streamline collision detection
This commit is contained in:
parent
83c35f68c4
commit
7b85f11143
154
combat.c
154
combat.c
|
@ -109,84 +109,94 @@ void populateTargetCollision(struct CompiledSpriteRender *sprite) {
|
||||||
collisionDetection.targetEY = bounds.bottom;
|
collisionDetection.targetEY = bounds.bottom;
|
||||||
}
|
}
|
||||||
|
|
||||||
void handleRabbitToEnemyCollisions(
|
// We are hardcoding a 2x2 grid on the screen as our collision partitioning
|
||||||
|
// scheme.
|
||||||
|
int rabbitBulletGrid[4][RABBIT_BULLET_LIMIT];
|
||||||
|
int enemyGrid[4][ENEMY_MAX_COUNT];
|
||||||
|
int rabbitGrid[4];
|
||||||
|
int rabbitBulletGridIndex[4], enemyGridIndex[4];
|
||||||
|
|
||||||
|
int gridPosition[4];
|
||||||
|
|
||||||
|
#define CALCULATE_GRID_POS(x,y) ((x / COLLISION_GRID_SIZE) + (y / COLLISION_GRID_SIZE) * 2)
|
||||||
|
|
||||||
|
void determineGridPositionsForSprite(struct CompiledSpriteRender *sprite) {
|
||||||
|
int i;
|
||||||
|
|
||||||
|
getSpriteBounds(sprite, &bounds);
|
||||||
|
|
||||||
|
for (i = 0; i < 4; ++i) {
|
||||||
|
gridPosition[i] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
gridPosition[CALCULATE_GRID_POS(bounds.left, bounds.top)] = 1;
|
||||||
|
gridPosition[CALCULATE_GRID_POS(bounds.right, bounds.top)] = 1;
|
||||||
|
gridPosition[CALCULATE_GRID_POS(bounds.left, bounds.bottom)] = 1;
|
||||||
|
gridPosition[CALCULATE_GRID_POS(bounds.right, bounds.bottom)] = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void buildCollisionGrids(
|
||||||
|
struct BulletPosition rabbitBulletPosition[],
|
||||||
struct RabbitPosition *rabbitPosition,
|
struct RabbitPosition *rabbitPosition,
|
||||||
struct EnemyPosition enemyPosition[]
|
struct EnemyPosition enemyPosition[]
|
||||||
) {
|
) {
|
||||||
int enemyIdx;
|
int grid, i;
|
||||||
|
|
||||||
|
for (grid = 0; grid < 4; ++grid) {
|
||||||
|
rabbitBulletGridIndex[grid] = 0;
|
||||||
|
enemyGridIndex[grid] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
// to start: brute force items
|
|
||||||
// possible performance improvements:
|
|
||||||
// * grid partitioning
|
|
||||||
rabbit.x = rabbitPosition->rabbitPosition[0];
|
rabbit.x = rabbitPosition->rabbitPosition[0];
|
||||||
rabbit.y = rabbitPosition->rabbitPosition[1];
|
rabbit.y = rabbitPosition->rabbitPosition[1];
|
||||||
populateSourceCollision(&rabbit);
|
determineGridPositionsForSprite(&rabbit);
|
||||||
|
|
||||||
for (enemyIdx = 0; enemyIdx < ENEMY_MAX_COUNT; ++enemyIdx) {
|
for (grid = 0; grid < 4; ++grid) {
|
||||||
if (!enemyPosition[enemyIdx].isActive) continue;
|
rabbitGrid[grid] = gridPosition[grid];
|
||||||
if (enemyPosition[enemyIdx].willBeInactive) continue;
|
}
|
||||||
|
|
||||||
enemy.x = enemyPosition[enemyIdx].enemyPosition[0];
|
for (i = 0; i < RABBIT_BULLET_LIMIT; ++i) {
|
||||||
enemy.y = enemyPosition[enemyIdx].enemyPosition[1];
|
if (!rabbitBulletPosition[i].isActive) continue;
|
||||||
populateTargetCollision(&enemy);
|
if (rabbitBulletPosition[i].willBeInactive) continue;
|
||||||
|
|
||||||
if (isCollision()) {
|
bullet.x = rabbitBulletPosition[i].x;
|
||||||
enemyPosition[enemyIdx].willBeInactive = 1;
|
bullet.y = rabbitBulletPosition[i].y;
|
||||||
|
determineGridPositionsForSprite(&bullet);
|
||||||
|
|
||||||
|
for (grid = 0; grid < 4; ++grid) {
|
||||||
|
if (gridPosition[grid]) {
|
||||||
|
rabbitBulletGrid[grid][rabbitBulletGridIndex[grid]++] = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < ENEMY_MAX_COUNT; ++i) {
|
||||||
|
if (!enemyPosition[i].isActive) continue;
|
||||||
|
if (enemyPosition[i].willBeInactive) continue;
|
||||||
|
|
||||||
|
enemy.x = enemyPosition[i].enemyPosition[0];
|
||||||
|
enemy.y = enemyPosition[i].enemyPosition[1];
|
||||||
|
determineGridPositionsForSprite(&enemy);
|
||||||
|
|
||||||
|
for (grid = 0; grid < 4; ++grid) {
|
||||||
|
if (gridPosition[grid]) {
|
||||||
|
enemyGrid[grid][enemyGridIndex[grid]++] = i;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int rabbitBulletGrid[4][RABBIT_BULLET_LIMIT];
|
|
||||||
int enemyGrid[4][ENEMY_MAX_COUNT];
|
|
||||||
|
|
||||||
void handleRabbitBulletToEnemyCollisions(
|
void handleRabbitBulletToEnemyCollisions(
|
||||||
struct BulletPosition rabbitBulletPosition[],
|
struct BulletPosition rabbitBulletPosition[],
|
||||||
struct EnemyPosition enemyPosition[]
|
struct EnemyPosition enemyPosition[]
|
||||||
) {
|
) {
|
||||||
int bulletIdx, enemyIdx, grid;
|
int bulletIdx, enemyIdx, grid;
|
||||||
int resolvedBulletIdx, resolvedEnemyIdx;
|
int resolvedBulletIdx, resolvedEnemyIdx;
|
||||||
int rabbitGridIndex[4], enemyGridIndex[4];
|
|
||||||
|
|
||||||
char buffer[30];
|
|
||||||
|
|
||||||
for (grid = 0; grid < 4; ++grid) {
|
|
||||||
rabbitGridIndex[grid] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (bulletIdx = 0; bulletIdx < RABBIT_BULLET_LIMIT; ++bulletIdx) {
|
|
||||||
if (!rabbitBulletPosition[bulletIdx].isActive) continue;
|
|
||||||
if (rabbitBulletPosition[bulletIdx].willBeInactive) continue;
|
|
||||||
|
|
||||||
grid = (
|
|
||||||
rabbitBulletPosition[bulletIdx].x / (TILE_SIZE * 5)
|
|
||||||
) + (
|
|
||||||
(rabbitBulletPosition[bulletIdx].y / (TILE_SIZE * 5)) * 2
|
|
||||||
);
|
|
||||||
|
|
||||||
rabbitBulletGrid[grid][rabbitGridIndex[grid]++] = bulletIdx;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (grid = 0; grid < 4; ++grid) {
|
|
||||||
enemyGridIndex[grid] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (enemyIdx = 0; enemyIdx < ENEMY_MAX_COUNT; ++enemyIdx) {
|
|
||||||
if (!enemyPosition[enemyIdx].isActive) continue;
|
|
||||||
if (enemyPosition[enemyIdx].willBeInactive) continue;
|
|
||||||
|
|
||||||
grid = (
|
|
||||||
enemyPosition[enemyIdx].enemyPosition[0] / (TILE_SIZE * 5)
|
|
||||||
) + (
|
|
||||||
(enemyPosition[enemyIdx].enemyPosition[1] / (TILE_SIZE * 5)) * 2
|
|
||||||
);
|
|
||||||
|
|
||||||
enemyGrid[grid][enemyGridIndex[grid]++] = enemyIdx;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (grid = 0; grid < 4; ++grid) {
|
for (grid = 0; grid < 4; ++grid) {
|
||||||
if (enemyGridIndex[grid] == 0) continue;
|
if (enemyGridIndex[grid] == 0) continue;
|
||||||
|
|
||||||
for (bulletIdx = 0; bulletIdx < rabbitGridIndex[grid]; ++bulletIdx) {
|
for (bulletIdx = 0; bulletIdx < rabbitBulletGridIndex[grid]; ++bulletIdx) {
|
||||||
resolvedBulletIdx = rabbitBulletGrid[grid][bulletIdx];
|
resolvedBulletIdx = rabbitBulletGrid[grid][bulletIdx];
|
||||||
|
|
||||||
if (!rabbitBulletPosition[resolvedBulletIdx].isActive) continue;
|
if (!rabbitBulletPosition[resolvedBulletIdx].isActive) continue;
|
||||||
|
@ -216,3 +226,37 @@ void handleRabbitBulletToEnemyCollisions(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void handleRabbitToEnemyCollisions(
|
||||||
|
struct RabbitPosition *rabbitPosition,
|
||||||
|
struct EnemyPosition enemyPosition[]
|
||||||
|
) {
|
||||||
|
int enemyIdx, grid, resolvedEnemyIdx;
|
||||||
|
|
||||||
|
// to start: brute force items
|
||||||
|
// possible performance improvements:
|
||||||
|
// * grid partitioning
|
||||||
|
rabbit.x = rabbitPosition->rabbitPosition[0];
|
||||||
|
rabbit.y = rabbitPosition->rabbitPosition[1];
|
||||||
|
populateSourceCollision(&rabbit);
|
||||||
|
|
||||||
|
for (grid = 0; grid < 4; ++grid) {
|
||||||
|
if (!rabbitGrid[grid]) continue;
|
||||||
|
if (enemyGridIndex[grid] == 0) continue;
|
||||||
|
|
||||||
|
for (enemyIdx = 0; enemyIdx < enemyGridIndex[grid]; ++enemyIdx) {
|
||||||
|
resolvedEnemyIdx = enemyGrid[grid][enemyIdx];
|
||||||
|
|
||||||
|
if (!enemyPosition[resolvedEnemyIdx].isActive) continue;
|
||||||
|
if (enemyPosition[resolvedEnemyIdx].willBeInactive) continue;
|
||||||
|
|
||||||
|
enemy.x = enemyPosition[resolvedEnemyIdx].enemyPosition[0];
|
||||||
|
enemy.y = enemyPosition[resolvedEnemyIdx].enemyPosition[1];
|
||||||
|
populateTargetCollision(&enemy);
|
||||||
|
|
||||||
|
if (isCollision()) {
|
||||||
|
enemyPosition[resolvedEnemyIdx].willBeInactive = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
6
combat.h
6
combat.h
|
@ -18,3 +18,9 @@ void handleRabbitToEnemyCollisions(
|
||||||
struct RabbitPosition*,
|
struct RabbitPosition*,
|
||||||
struct EnemyPosition[]
|
struct EnemyPosition[]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
void buildCollisionGrids(
|
||||||
|
struct BulletPosition rabbitBulletPosition[],
|
||||||
|
struct RabbitPosition *rabbitPosition,
|
||||||
|
struct EnemyPosition enemyPosition[]
|
||||||
|
);
|
||||||
|
|
1
const.h
1
const.h
|
@ -1,6 +1,7 @@
|
||||||
#define TILE_SIZE (20)
|
#define TILE_SIZE (20)
|
||||||
#define ARENA_WIDTH_TILES (10)
|
#define ARENA_WIDTH_TILES (10)
|
||||||
#define ARENA_HEIGHT_TILES (10)
|
#define ARENA_HEIGHT_TILES (10)
|
||||||
|
#define COLLISION_GRID_SIZE (ARENA_WIDTH_TILES / 2 * TILE_SIZE)
|
||||||
|
|
||||||
#define MOUSE_DISTANCE (32)
|
#define MOUSE_DISTANCE (32)
|
||||||
|
|
||||||
|
|
8
game.c
8
game.c
|
@ -286,6 +286,12 @@ void handleCombat() {
|
||||||
&rabbitWeaponry
|
&rabbitWeaponry
|
||||||
);
|
);
|
||||||
|
|
||||||
|
buildCollisionGrids(
|
||||||
|
rabbitBulletPosition,
|
||||||
|
&rabbitPosition,
|
||||||
|
enemyPosition
|
||||||
|
);
|
||||||
|
|
||||||
handleRabbitToEnemyCollisions(
|
handleRabbitToEnemyCollisions(
|
||||||
&rabbitPosition,
|
&rabbitPosition,
|
||||||
enemyPosition
|
enemyPosition
|
||||||
|
@ -337,10 +343,10 @@ int main(void) {
|
||||||
|
|
||||||
handleMovement();
|
handleMovement();
|
||||||
handleRedraw();
|
handleRedraw();
|
||||||
|
handleCombat();
|
||||||
|
|
||||||
waitStartVbl();
|
waitStartVbl();
|
||||||
copyDrawBufferToDisplay();
|
copyDrawBufferToDisplay();
|
||||||
handleCombat();
|
|
||||||
waitEndVbl();
|
waitEndVbl();
|
||||||
|
|
||||||
if (keyboardKeydownState.KEY_ESC) { keepRunning = 0; }
|
if (keyboardKeydownState.KEY_ESC) { keepRunning = 0; }
|
||||||
|
|
Loading…
Reference in New Issue