// bullets #define BULLET_OFF 4 #define BULLET_OFF_BIG 8 #define BULLET_DIST FIX32(4) #define BULLET_DIST_BIG FIX32(8) void spawnBullet(struct bulletSpawner spawner, void(*updater)){ s16 i = -1; for(s16 j = 0; j < BULLET_COUNT; j++) if(!bullets[j].active && i == -1) i = j; if(i > -1 && (spawner.player || (player.invincibleClock < INVINCIBLE_LIMIT))){ bullets[i].active = TRUE; bullets[i].pos.x = spawner.x; bullets[i].pos.y = spawner.y; bullets[i].dist = fix16ToFix32(spawner.big ? BULLET_DIST_BIG : BULLET_DIST); bullets[i].speed = spawner.speed; bullets[i].angle = spawner.angle; bullets[i].player = spawner.player; bullets[i].clock = 0; bullets[i].dead = FALSE; bullets[i].big = spawner.big; for(u8 j = 0; j < COUNT_INT; j++){ bullets[i].bools[j] = spawner.bools[j]; bullets[i].ints[j] = spawner.ints[j]; bullets[i].fixes[j] = spawner.fixes[j]; } if(spawner.vel.x && spawner.vel.y){ bullets[i].vel.x = spawner.vel.x; bullets[i].vel.y = spawner.vel.y; if(bullets[i].vel.x > 0 && !bullets[i].player) bullets[i].vel.x = -bullets[i].vel.x; } else { bullets[i].vel.x = fix16Mul(cosFix16(spawner.angle), spawner.speed); bullets[i].vel.y = fix16Mul(sinFix16(spawner.angle), spawner.speed); } bullets[i].updater = updater; bullets[i].image = SPR_addSprite(spawner.image, fix16ToInt(fix16Sub(bullets[i].pos.x, spawner.big ? BULLET_OFF_BIG : BULLET_OFF)), fix16ToInt(fix16Sub(bullets[i].pos.y,spawner.big ? BULLET_OFF_BIG : BULLET_OFF)), TILE_ATTR(PAL1, 0, 0, 0)); // SPR_setDepth(bullets[i].image, 4); } } static void killBullet(s16 i){ bullets[i].active = FALSE; SPR_releaseSprite(bullets[i].image); if(bullets[i].dead){ // spawnExplosion(bullets[i].pos.x, bullets[i].pos.y, 0); bullets[i].dead = FALSE; } } void updateBulletVel(s16 i){ bullets[i].vel.x = fix16Mul(cosFix16(bullets[i].angle), bullets[i].speed); bullets[i].vel.y = fix16Mul(sinFix16(bullets[i].angle), bullets[i].speed); } // collision #define BULLET_LIMIT FIX16(-BULLET_OFF) #define BULLET_LIMIT_W FIX16(GAME_W + BULLET_OFF) #define BULLET_LIMIT_H FIX16(GAME_H + BULLET_OFF) #define BULLET_LIMIT_BIG FIX16(-BULLET_OFF_BIG) #define BULLET_LIMIT_W_BIG FIX16(GAME_W + BULLET_OFF_BIG) #define BULLET_LIMIT_H_BIG FIX16(GAME_H + BULLET_OFF_BIG) static void collideBullet(s16 i){ if(bullets[i].pos.x < (bullets[i].big ? BULLET_LIMIT_BIG : BULLET_LIMIT) || bullets[i].pos.x > (bullets[i].big ? BULLET_LIMIT_W_BIG : BULLET_LIMIT_W) || bullets[i].pos.y < (bullets[i].big ? BULLET_LIMIT_BIG : BULLET_LIMIT) || bullets[i].pos.y > (bullets[i].big ? BULLET_LIMIT_H_BIG : BULLET_LIMIT_H)){ killBullet(i); } } // loop static void updateBullet(s16 i){ bullets[i].pos.x = fix16Add(bullets[i].pos.x, bullets[i].vel.x); bullets[i].pos.y = fix16Add(bullets[i].pos.y, bullets[i].vel.y); bullets[i].updater(i); collideBullet(i); SPR_setPosition( bullets[i].image, fix16ToInt(fix16Sub(bullets[i].pos.x, bullets[i].big ? BULLET_OFF_BIG : BULLET_OFF)), fix16ToInt(fix16Sub(bullets[i].pos.y, bullets[i].big ? BULLET_OFF_BIG : BULLET_OFF))); bullets[i].clock++; } void updateBullets(){ if(killBullets){ for(s16 i = 0; i < BULLET_COUNT; i++) if(bullets[i].active){ if(i % 4 == 0) bullets[i].dead = TRUE; killBullet(i); } killBullets = FALSE; } else { for(s16 i = 0; i < BULLET_COUNT; i++) if(bullets[i].active) updateBullet(i); } }