Reputation: 21
i been trying to make a collision for the player i did use some ai for it but i came to a problem that idk how to fix at some blocks that face north and east i can noclip in 1 block deep in the wall if there is two block tick wall and sometimes when i fall i noclip 1 block into the ground. i'm using C with a 3D opengl renderer
#include "Player.h"
#include <stdio.h>
#include "Utils.h"
#include "Camera.h"
#include "WorldGenerator.h"
void Player_Init(Player* player, vec3 startPos) {
glm_vec3_copy(startPos, player->position);
glm_vec3_zero(player->velocity);
player->isOnGround = 0;
while (!CheckAABBCollision(player, (vec3) { player->position[0], player->position[1] - 1.0f, player->position[2] })) {
player->position[1] -= 1.0f;
if (player->position[1] <= 0.0f) break;
}
if (CheckAABBCollision(player, player->position)) {
player->position[1] += 0.1f;
}
player->isOnGround = 1;
player->velocity[1] = 0;
}
int CheckCollision(vec3 position) {
int x = (int)floorf(position[0]);
int y = (int)floorf(position[1]);
int z = (int)floorf(position[2]);
if (x < 0 || x >= CHUNK_SIZE * NUM_CHUNKS ||
y < 0 || y >= CHUNK_HEIGHT ||
z < 0 || z >= CHUNK_SIZE * NUM_CHUNKS) {
return 0;
}
int chunkX = x / CHUNK_SIZE;
int chunkZ = z / CHUNK_SIZE;
int localX = x % CHUNK_SIZE;
int localZ = z % CHUNK_SIZE;
return world[chunkX][chunkZ].blocks[localX][y][localZ] != 0;
}
int CheckAABBCollision(Player* player, vec3 newPos) {
float halfWidth = PLAYER_WIDTH / 2;
float expand = 0.05f;
float minX = newPos[0] - halfWidth - expand;
float maxX = newPos[0] + halfWidth + expand;
float minY = newPos[1];
float maxY = newPos[1] + PLAYER_HEIGHT;
float minZ = newPos[2] - halfWidth - expand;
float maxZ = newPos[2] + halfWidth + expand;
vec3 checkPoints[8] = {
{minX, minY, minZ}, {maxX, minY, minZ}, {minX, minY, maxZ}, {maxX, minY, maxZ},
{minX, maxY, minZ}, {maxX, maxY, minZ}, {minX, maxY, maxZ}, {maxX, maxY, maxZ}
};
for (int i = 0; i < 8; i++) {
if (CheckCollision(checkPoints[i])) {
return 1;
}
}
return 0;
}
void ResolveCollision(Player* player, float deltaTime) {
vec3 newPos;
glm_vec3_copy(player->position, newPos);
if (!player->isOnGround) {
player->velocity[1] += GRAVITY * deltaTime;
}
newPos[1] += player->velocity[1] * deltaTime;
if (CheckAABBCollision(player, newPos)) {
if (player->velocity[1] < 0) {
player->isOnGround = 1;
player->velocity[1] = 0;
while (CheckAABBCollision(player, (vec3) { newPos[0], newPos[1] - 0.01f, newPos[2] })) {
newPos[1] += 0.01f;
}
}
else if (player->velocity[1] > 0) {
player->velocity[1] = 0;
}
}
else {
player->position[1] = newPos[1];
player->isOnGround = 0;
}
newPos[0] += player->velocity[0] * deltaTime;
if (CheckAABBCollision(player, (vec3) { newPos[0], player->position[1], player->position[2] })) {
printf("X Collision at %.2f\n", newPos[0]);
if (player->velocity[0] > 0) {
newPos[0] = floor(newPos[0]) - 0.01f;
}
else if (player->velocity[0] < 0) {
newPos[0] = ceil(newPos[0]) + 0.01f;
}
player->velocity[0] = 0;
}
else {
player->position[0] = newPos[0];
}
newPos[2] += player->velocity[2] * deltaTime;
if (CheckAABBCollision(player, (vec3) { player->position[0], player->position[1], newPos[2] })) {
printf("Z Collision at %.2f\n", newPos[2]);
if (player->velocity[2] > 0) {
newPos[2] = floor(newPos[2]) - 0.01f;
}
else if (player->velocity[2] < 0) {
newPos[2] = ceil(newPos[2]) + 0.01f;
}
player->velocity[2] = 0;
}
else {
player->position[2] = newPos[2];
}
}
void Player_Update(Player* player, float deltaTime) {
if (!player->isOnGround) {
player->velocity[1] += GRAVITY * deltaTime;
}
if (player->velocity[1] < -MAX_FALL_SPEED) {
player->velocity[1] = -MAX_FALL_SPEED;
}
ResolveCollision(player, deltaTime);
}
i was expecting to player collides with the cubes.
Upvotes: 0
Views: 58