Moved tile collision
This commit is contained in:
@ -54,6 +54,11 @@ void entityUpdate(entity_t *entity) {
|
||||
fixed248_t newX = entity->x + entity->vx;
|
||||
fixed248_t newY = entity->y + entity->vy;
|
||||
fixed248_t halfTileWH = FIXED248(TILE_WIDTH_HEIGHT / 2, 0);
|
||||
|
||||
// Because all hit detection is done assuming the entity is a circle, with
|
||||
// its position centered, we need to precalc these;
|
||||
fixed248_t selfCircX = fx248Addfx248(newX, halfTileWH);
|
||||
fixed248_t selfCircY = fx248Addfx248(newY, halfTileWH);
|
||||
fixed248_t selfCircR = halfTileWH;
|
||||
|
||||
// Check for collisions with tiles
|
||||
@ -91,63 +96,9 @@ void entityUpdate(entity_t *entity) {
|
||||
uint8_t chunkTileY = tileY % CHUNK_HEIGHT;
|
||||
tile_t tile = chunk->tilesBase[chunkTileY * CHUNK_WIDTH + chunkTileX];
|
||||
|
||||
fixed248_t lx = fx248Mulfx248(x, FIXED248(TILE_WIDTH_HEIGHT, 0));
|
||||
fixed248_t ty = fx248Mulfx248(y, FIXED248(TILE_WIDTH_HEIGHT, 0));
|
||||
fixed248_t rx = fx248Addfx248(lx, FIXED248(TILE_WIDTH_HEIGHT, 0));
|
||||
fixed248_t by = fx248Addfx248(ty, FIXED248(TILE_WIDTH_HEIGHT, 0));
|
||||
|
||||
// Determine tile collision type
|
||||
collisionresult_t collision;
|
||||
switch(TILE_META_DATA[tile].solidType) {
|
||||
case TILE_SOLID_FULL:
|
||||
collision = physicsCheckCircleAABB(
|
||||
fx248Addfx248(newX, halfTileWH), fx248Addfx248(newY, halfTileWH), selfCircR,
|
||||
lx, ty,
|
||||
FIXED248(TILE_WIDTH_HEIGHT, 0),
|
||||
FIXED248(TILE_WIDTH_HEIGHT, 0)
|
||||
);
|
||||
break;
|
||||
|
||||
case TILE_SOLID_TRIANGLE_TOP_RIGHT:
|
||||
collision = physicsCheckCircleTriangle(
|
||||
fx248Addfx248(newX, halfTileWH), fx248Addfx248(newY, halfTileWH), selfCircR,
|
||||
rx, by,
|
||||
rx, ty,
|
||||
lx, ty
|
||||
);
|
||||
break;
|
||||
|
||||
case TILE_SOLID_TRIANGLE_TOP_LEFT:
|
||||
collision = physicsCheckCircleTriangle(
|
||||
fx248Addfx248(newX, halfTileWH), fx248Addfx248(newY, halfTileWH), selfCircR,
|
||||
lx, by,
|
||||
lx, ty,
|
||||
rx, ty
|
||||
);
|
||||
break;
|
||||
|
||||
case TILE_SOLID_TRIANGLE_BOTTOM_RIGHT:
|
||||
collision = physicsCheckCircleTriangle(
|
||||
fx248Addfx248(newX, halfTileWH), fx248Addfx248(newY, halfTileWH), selfCircR,
|
||||
rx, ty,
|
||||
rx, by,
|
||||
lx, by
|
||||
);
|
||||
break;
|
||||
case TILE_SOLID_TRIANGLE_BOTTOM_LEFT:
|
||||
collision = physicsCheckCircleTriangle(
|
||||
fx248Addfx248(newX, halfTileWH), fx248Addfx248(newY, halfTileWH), selfCircR,
|
||||
lx, ty,
|
||||
lx, by,
|
||||
rx, by
|
||||
);
|
||||
break;
|
||||
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
collisionresult_t collision = physicsCheckCircleTile(
|
||||
selfCircX, selfCircY, selfCircR, x, y, tile
|
||||
);
|
||||
if(collision.hit && collision.depth > FIXED248(0, 1)) {
|
||||
fixed248_t slideX = fx248Mulfx248(
|
||||
collision.normalX, collision.depth
|
||||
@ -172,6 +123,7 @@ void entityUpdate(entity_t *entity) {
|
||||
|
||||
fixed248_t otherCircR = halfTileWH;
|
||||
|
||||
// We DONT use selfCircX/Y here because the other entity is ALSO a circle.
|
||||
collisionresult_t collision = physicsCheckCircleCircle(
|
||||
newX, newY, selfCircR,
|
||||
otherEntity->x, otherEntity->y, otherCircR
|
||||
|
@ -6,6 +6,7 @@
|
||||
*/
|
||||
|
||||
#include "physics.h"
|
||||
#include "world/tiledata.h"
|
||||
|
||||
collisionresult_t physicsCheckCircleCircle(
|
||||
fixed248_t circle0x, fixed248_t circle0y, fixed248_t circle0r,
|
||||
@ -245,3 +246,68 @@ collisionresult_t physicsCheckCircleTriangle(
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
collisionresult_t physicsCheckCircleTile(
|
||||
fixed248_t circleX, fixed248_t circleY, fixed248_t circleR,
|
||||
fixed248_t tileX, fixed248_t tileY, tile_t tile
|
||||
) {
|
||||
collisionresult_t result;
|
||||
|
||||
#define tw FIXED248(TILE_WIDTH_HEIGHT, 0)
|
||||
#define th FIXED248(TILE_WIDTH_HEIGHT, 0)
|
||||
#define lx fx248Mulfx248(tileX, tw)
|
||||
#define ty fx248Mulfx248(tileY, th)
|
||||
#define rx fx248Addfx248(lx, tw)
|
||||
#define by fx248Addfx248(ty, th)
|
||||
|
||||
switch(TILE_META_DATA[tile].solidType) {
|
||||
case TILE_SOLID_FULL:
|
||||
result = physicsCheckCircleAABB(
|
||||
circleX, circleY, circleR,
|
||||
lx, ty,
|
||||
tw, th
|
||||
);
|
||||
break;
|
||||
|
||||
case TILE_SOLID_TRIANGLE_TOP_RIGHT:
|
||||
result = physicsCheckCircleTriangle(
|
||||
circleX, circleY, circleR,
|
||||
rx, by,
|
||||
rx, ty,
|
||||
lx, ty
|
||||
);
|
||||
break;
|
||||
|
||||
case TILE_SOLID_TRIANGLE_TOP_LEFT:
|
||||
result = physicsCheckCircleTriangle(
|
||||
circleX, circleY, circleR,
|
||||
lx, by,
|
||||
lx, ty,
|
||||
rx, ty
|
||||
);
|
||||
break;
|
||||
|
||||
case TILE_SOLID_TRIANGLE_BOTTOM_RIGHT:
|
||||
result = physicsCheckCircleTriangle(
|
||||
circleX, circleY, circleR,
|
||||
rx, ty,
|
||||
rx, by,
|
||||
lx, by
|
||||
);
|
||||
break;
|
||||
case TILE_SOLID_TRIANGLE_BOTTOM_LEFT:
|
||||
result = physicsCheckCircleTriangle(
|
||||
circleX, circleY, circleR,
|
||||
lx, ty,
|
||||
lx, by,
|
||||
rx, by
|
||||
);
|
||||
break;
|
||||
|
||||
default:
|
||||
result.hit = false;
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
@ -7,6 +7,7 @@
|
||||
|
||||
#pragma once
|
||||
#include "util/fixed.h"
|
||||
#include "world/tile.h"
|
||||
|
||||
typedef struct {
|
||||
bool_t hit;
|
||||
@ -106,4 +107,20 @@ collisionresult_t physicsCheckCircleTriangle(
|
||||
fixed248_t triX0, fixed248_t triY0,
|
||||
fixed248_t triX1, fixed248_t triY1,
|
||||
fixed248_t triX2, fixed248_t triY2
|
||||
);
|
||||
|
||||
/**
|
||||
* Check for collision between a circle and a tile.
|
||||
*
|
||||
* @param circleX X coordinate of the circle's center.
|
||||
* @param circleY Y coordinate of the circle's center.
|
||||
* @param circleR Radius of the circle.
|
||||
* @param tileX X coordinate of the tile's top-left corner.
|
||||
* @param tileY Y coordinate of the tile's top-left corner.
|
||||
* @param tile The tile to check against.
|
||||
* @return A collisionresult_t structure containing collision information.
|
||||
*/
|
||||
collisionresult_t physicsCheckCircleTile(
|
||||
fixed248_t circleX, fixed248_t circleY, fixed248_t circleR,
|
||||
fixed248_t tileX, fixed248_t tileY, tile_t tile
|
||||
);
|
Reference in New Issue
Block a user