#include #include "game.h" #include "movement.h" #include "const.h" #include "system/vga.h" void attemptToFireRabbitBullet( struct RabbitPosition *rabbitPosition, struct RabbitWeaponry *rabbitWeaponry, struct BulletPosition rabbitBulletPosition[] ) { int okToFire = 0, availableBullet, i; signed char doubleVelocityX, doubleVelocityY; if (rabbitWeaponry->cooldown > 0) return; for (i = 0; i < RABBIT_BULLET_LIMIT; ++i) { if (rabbitBulletPosition[i].isActive == 0) { okToFire = 1; availableBullet = i; break; } } if (!okToFire) return; rabbitWeaponry->cooldown = RABBIT_BULLET_COOLDOWN; doubleVelocityX = sin(rabbitPosition->mouseAngle * DEG2RAD) * (RABBIT_BULLET_VELOCITY * 2); doubleVelocityY = -cos(rabbitPosition->mouseAngle * DEG2RAD) * (RABBIT_BULLET_VELOCITY * 2); rabbitBulletPosition[availableBullet].isActive = 1; rabbitBulletPosition[availableBullet].willBeInactive = 0; rabbitBulletPosition[availableBullet].x = rabbitPosition->rabbitPosition[0]; rabbitBulletPosition[availableBullet].y = rabbitPosition->rabbitPosition[1] - RABBIT_BULLET_HEIGHT_START; rabbitBulletPosition[availableBullet].oldX = rabbitBulletPosition[availableBullet].x; rabbitBulletPosition[availableBullet].oldY = rabbitBulletPosition[availableBullet].y; rabbitBulletPosition[availableBullet].velocityXSteps[0] = doubleVelocityX / RABBIT_BULLET_VELOCITY; rabbitBulletPosition[availableBullet].velocityXSteps[1] = doubleVelocityX % RABBIT_BULLET_VELOCITY; rabbitBulletPosition[availableBullet].velocityYSteps[0] = doubleVelocityY / RABBIT_BULLET_VELOCITY; rabbitBulletPosition[availableBullet].velocityYSteps[1] = doubleVelocityY % RABBIT_BULLET_VELOCITY; rabbitBulletPosition[availableBullet].velocityStep = 0; } void advanceRabbitBullets( struct BulletPosition rabbitBulletPosition[], struct RabbitWeaponry *rabbitWeaponry ) { int i; for (i = 0; i < RABBIT_BULLET_LIMIT; ++i) { if (!rabbitBulletPosition[i].isActive) continue; rabbitBulletPosition[i].oldX = rabbitBulletPosition[i].x; rabbitBulletPosition[i].oldY = rabbitBulletPosition[i].y; rabbitBulletPosition[i].x += rabbitBulletPosition[i].velocityXSteps[rabbitBulletPosition[i].velocityStep]; rabbitBulletPosition[i].y += rabbitBulletPosition[i].velocityYSteps[rabbitBulletPosition[i].velocityStep]; if (rabbitBulletPosition[i].x < MOUSE_LIMIT_LEFT) rabbitBulletPosition[i].willBeInactive = 1; if (rabbitBulletPosition[i].x >= MOUSE_LIMIT_RIGHT) rabbitBulletPosition[i].willBeInactive = 1; if (rabbitBulletPosition[i].y < MOUSE_LIMIT_TOP) rabbitBulletPosition[i].willBeInactive = 1; if (rabbitBulletPosition[i].y >= MOUSE_LIMIT_BOTTOM) rabbitBulletPosition[i].willBeInactive = 1; rabbitBulletPosition[i].velocityStep = 1 - rabbitBulletPosition[i].velocityStep; } if (rabbitWeaponry->cooldown > 0) rabbitWeaponry->cooldown--; } struct CollisionDetection { short int sourceSX, sourceSY, sourceEX, sourceEY; short int targetSX, targetSY, targetEX, targetEY; }; struct CollisionDetection collisionDetection; int isCollision() { int result; // first pass: are the hitboxes even close result = !( collisionDetection.sourceEY < collisionDetection.targetSY || collisionDetection.sourceEX < collisionDetection.targetSX || collisionDetection.targetEY < collisionDetection.sourceSY || collisionDetection.targetEX < collisionDetection.sourceSX ); if (!result) return result; // second pass: check against specific character shaped hitboxes // these will be generated from the spritesheet generator return result; } void populateSourceCollision(struct CompiledSpriteRender *sprite) { getSpriteBounds(sprite, &bounds); collisionDetection.sourceSX = bounds.left; collisionDetection.sourceSY = bounds.top; collisionDetection.sourceEX = bounds.right; collisionDetection.sourceEY = bounds.bottom; } void populateTargetCollision(struct CompiledSpriteRender *sprite) { getSpriteBounds(sprite, &bounds); collisionDetection.targetSX = bounds.left; collisionDetection.targetSY = bounds.top; collisionDetection.targetEX = bounds.right; collisionDetection.targetEY = bounds.bottom; } void handleRabbitBulletToEnemyCollisions( struct BulletPosition rabbitBulletPosition[], struct EnemyPosition enemyPosition[] ) { int bulletIdx, enemyIdx; // to start: brute force items // possible performance improvements: // * horizontal sweep against enemies to rule out enemies to check for (bulletIdx = 0; bulletIdx < RABBIT_BULLET_LIMIT; ++bulletIdx) { if (!rabbitBulletPosition[bulletIdx].isActive) continue; if (rabbitBulletPosition[bulletIdx].willBeInactive) continue; populateSourceCollision(&bullet); for (enemyIdx = 0; enemyIdx < ENEMY_MAX_COUNT; ++enemyIdx) { if (!enemyPosition[enemyIdx].isActive) continue; if (enemyPosition[enemyIdx].willBeInactive) continue; populateTargetCollision(&enemy); if (isCollision()) { enemyPosition[enemyIdx].willBeInactive = 1; rabbitBulletPosition[bulletIdx].willBeInactive = 1; break; } } } }