This repository has been archived on 2022-09-26. You can view files and clone it, but cannot push or open issues or pull requests.
fd2/src/enemies.h
2022-08-17 20:39:28 -04:00

96 lines
3.1 KiB
C

// enemies
// lifecycle
void spawnEnemy(struct enemySpawner spawner, void(*updater), void(*suicide)){
s16 i = -1;
for(s16 j = 0; j < ENEMY_COUNT; j++) if(!enemies[j].active && i == -1) i = j;
if(i > -1){
enemies[i].active = TRUE;
enemies[i].off.x = FIX16(spawner.offX);
enemies[i].off.y = FIX16(spawner.offY);
enemies[i].pos.x = FIX16(spawner.x);
enemies[i].pos.y = FIX16(spawner.y);
enemies[i].dist = intToFix32(spawner.offX - 2);
enemies[i].speed = spawner.speed;
enemies[i].angle = spawner.angle;
enemies[i].boss = spawner.boss;
enemies[i].shotClock = 0;
enemies[i].dead = FALSE;
enemies[i].health = spawner.health ? spawner.health : 1;
if(spawner.vel.x && spawner.vel.y){
enemies[i].vel.x = spawner.vel.x;
enemies[i].vel.y = spawner.vel.y;
} else {
enemies[i].vel.x = fix16Mul(cosFix16(spawner.angle), spawner.speed);
enemies[i].vel.y = fix16Mul(sinFix16(spawner.angle), spawner.speed);
}
for(s16 j = 0; j < COUNT_INT; j++){
enemies[i].bools[j] = spawner.bools[j];
enemies[i].ints[j] = spawner.ints[j];
enemies[i].fixes[j] = spawner.fixes[j];
}
enemies[i].updater = updater;
enemies[i].suicide = suicide;
enemies[i].clock = 0;
enemies[i].seen = FALSE;
enemies[i].image = SPR_addSprite(spawner.image,
fix16ToInt(fix16Sub(enemies[i].pos.x, enemies[i].off.x)),
fix16ToInt(fix16Sub(enemies[i].pos.y, enemies[i].off.y)),
TILE_ATTR(PAL1, 0, 0, 0));
SPR_setAnim(enemies[i].image, spawner.anim ? spawner.anim : 0);
SPR_setFrame(enemies[i].image, spawner.frame ? spawner.frame : 0);
SPR_setDepth(enemies[i].image, 5);
SPR_setVisibility(enemies[i].image, HIDDEN);
}
}
void killEnemy(s16 i){
enemies[i].dead = TRUE;
}
// helpers
void updateEnemyVel(s16 i){
enemies[i].vel.x = fix16Mul(cosFix16(enemies[i].angle), enemies[i].speed);
enemies[i].vel.y = fix16Mul(sinFix16(enemies[i].angle), enemies[i].speed);
}
// loop
static void updateEnemy(s16 i){
if(enemies[i].seen && (enemies[i].pos.x < fix16Sub(0, enemies[i].off.x) ||
enemies[i].pos.x > fix16Add(FIX16(GAME_W), enemies[i].off.x) ||
enemies[i].pos.y < fix16Sub(0, enemies[i].off.y) ||
enemies[i].pos.y > fix16Add(FIX16(GAME_H), enemies[i].off.y))){
killEnemy(i);
enemies[i].suicide(i);
} else {
if(!enemies[i].seen && enemies[i].pos.x <= fix16Add(FIX16(GAME_W), enemies[i].off.x)){
enemies[i].seen = TRUE;
SPR_setVisibility(enemies[i].image, VISIBLE);
}
enemies[i].pos.x = fix16Add(enemies[i].pos.x, enemies[i].vel.x);
enemies[i].pos.y = fix16Add(enemies[i].pos.y, enemies[i].vel.y);
if(enemies[i].seen){
enemies[i].updater(i);
if(enemies[i].boss) bossHealth = enemies[i].health;
// collideEnemy(i);
enemies[i].clock++;
if(enemies[i].clock >= CLOCK_LIMIT) enemies[i].clock -= CLOCK_LIMIT;
SPR_setPosition(enemies[i].image,
fix16ToInt(fix16Sub(enemies[i].pos.x, enemies[i].off.x)),
fix16ToInt(fix16Sub(enemies[i].pos.y, enemies[i].off.y)));
}
}
if(enemies[i].dead){
enemies[i].active = FALSE;
SPR_releaseSprite(enemies[i].image);
}
}
void updateEnemies(){
for(s16 i = 0; i < ENEMY_COUNT; i++) if(enemies[i].active) updateEnemy(i);
}