Removed need to do multiple checks on tile hits

This commit is contained in:
2025-06-20 13:27:04 -05:00
parent 025bc2cff6
commit 44ebf3a66d
2 changed files with 36 additions and 47 deletions

View File

@ -62,58 +62,48 @@ void entityUpdate(entity_t *entity) {
fixed248_t selfCircR = halfTileWH; fixed248_t selfCircR = halfTileWH;
// Check for collisions with tiles // Check for collisions with tiles
uint8_t tileChecks = ENTITY_TILE_COLISSION_RESOLUTION_COUNT; fixed248_t tileStartX = fx248Floor(fx248Divfx248(
do { (newX - halfTileWH), FIXED248(TILE_WIDTH_HEIGHT, 0)
// loop to resolve tile collisions multiple times to handle sliding ));
// correctly fixed248_t tileStartY = fx248Floor(fx248Divfx248(
bool tileResolved = false; (newY - halfTileWH), FIXED248(TILE_WIDTH_HEIGHT, 0)
));
fixed248_t tileEndX = fx248Ceil(fx248Divfx248(
(newX + halfTileWH), FIXED248(TILE_WIDTH_HEIGHT, 0)
));
fixed248_t tileEndY = fx248Ceil(fx248Divfx248(
(newY + halfTileWH), FIXED248(TILE_WIDTH_HEIGHT, 0)
));
// Compute affected tile range // For each tile
fixed248_t tileStartX = fx248Floor(fx248Divfx248( for(fixed248_t y = tileStartY; y <= tileEndY; y += FIXED248_ONE) {
(newX - halfTileWH), FIXED248(TILE_WIDTH_HEIGHT, 0) for(fixed248_t x = tileStartX; x <= tileEndX; x += FIXED248_ONE) {
)); uint16_t tileX = fx248Tou16(x);
fixed248_t tileStartY = fx248Floor(fx248Divfx248( uint16_t tileY = fx248Tou16(y);
(newY - halfTileWH), FIXED248(TILE_WIDTH_HEIGHT, 0) uint16_t chunkX = tileX / CHUNK_WIDTH;
)); uint16_t chunkY = tileY / CHUNK_HEIGHT;
fixed248_t tileEndX = fx248Ceil(fx248Divfx248( chunk_t *chunk = chunkGetChunkAt(chunkX, chunkY);
(newX + halfTileWH), FIXED248(TILE_WIDTH_HEIGHT, 0) if(chunk == NULL) continue;
));
fixed248_t tileEndY = fx248Ceil(fx248Divfx248(
(newY + halfTileWH), FIXED248(TILE_WIDTH_HEIGHT, 0)
));
// For each tile uint8_t chunkTileX = tileX % CHUNK_WIDTH;
for(fixed248_t y = tileStartY; y <= tileEndY; y += FIXED248_ONE) { uint8_t chunkTileY = tileY % CHUNK_HEIGHT;
for(fixed248_t x = tileStartX; x <= tileEndX; x += FIXED248_ONE) { tile_t tile = chunk->tilesBase[chunkTileY * CHUNK_WIDTH + chunkTileX];
uint16_t tileX = fx248Tou16(x);
uint16_t tileY = fx248Tou16(y);
uint16_t chunkX = tileX / CHUNK_WIDTH;
uint16_t chunkY = tileY / CHUNK_HEIGHT;
chunk_t *chunk = chunkGetChunkAt(chunkX, chunkY);
if(chunk == NULL) continue;
uint8_t chunkTileX = tileX % CHUNK_WIDTH; collisionresult_t collision = physicsCheckCircleTile(
uint8_t chunkTileY = tileY % CHUNK_HEIGHT; selfCircX, selfCircY, selfCircR, x, y, tile
tile_t tile = chunk->tilesBase[chunkTileY * CHUNK_WIDTH + chunkTileX]; );
if(collision.hit && collision.depth > FIXED248(0, 1)) {
collisionresult_t collision = physicsCheckCircleTile( fixed248_t slideX = fx248Mulfx248(
selfCircX, selfCircY, selfCircR, x, y, tile collision.normalX, collision.depth
); );
if(collision.hit && collision.depth > FIXED248(0, 1)) { fixed248_t slideY = fx248Mulfx248(
fixed248_t slideX = fx248Mulfx248( collision.normalY, collision.depth
collision.normalX, collision.depth );
); newX -= slideX;
fixed248_t slideY = fx248Mulfx248( newY -= slideY;
collision.normalY, collision.depth
);
newX -= slideX;
newY -= slideY;
tileResolved = true;
}
} }
} }
if(!tileResolved) break; // no more overlaps }
} while(--tileChecks > 0);
// Check for collisions with other entities // Check for collisions with other entities
entity_t *otherEntity = ENTITIES; entity_t *otherEntity = ENTITIES;

View File

@ -11,7 +11,6 @@
#include "util/fixed.h" #include "util/fixed.h"
#define ENTITY_COUNT_MAX 32 #define ENTITY_COUNT_MAX 32
#define ENTITY_TILE_COLISSION_RESOLUTION_COUNT 4
typedef enum { typedef enum {
ENTITY_DIR_SOUTH = 0, ENTITY_DIR_SOUTH = 0,