101 lines
No EOL
2.8 KiB
C
101 lines
No EOL
2.8 KiB
C
|
|
#include "enemytypes.h"
|
|
|
|
#define ENEMY_MIN_DIST FIX32(64)
|
|
|
|
static bool isValidEnemyPosition(fix32 x, fix32 y) {
|
|
for(s16 j = 0; j < ENEMY_COUNT; j++) {
|
|
if(enemies[j].active) {
|
|
fix32 dx = getWrappedDelta(x, enemies[j].pos.x);
|
|
fix32 dy = y - enemies[j].pos.y;
|
|
// Check if within 64px in both X and Y
|
|
if(dx >= -ENEMY_MIN_DIST && dx <= ENEMY_MIN_DIST &&
|
|
dy >= -ENEMY_MIN_DIST && dy <= ENEMY_MIN_DIST) {
|
|
return FALSE; // Too close to existing enemy
|
|
}
|
|
}
|
|
}
|
|
return TRUE; // Position is valid
|
|
}
|
|
|
|
void spawnEnemy(u8 type, u8 zone){
|
|
// Find available slot, return if none
|
|
s16 i = -1;
|
|
for(s16 j = 0; j < ENEMY_COUNT; j++) if(!enemies[j].active) { i = j; break; }
|
|
if(i == -1) return;
|
|
|
|
enemies[i].active = TRUE;
|
|
enemies[i].type = type;
|
|
|
|
// Calculate zone bounds (each zone is 512px)
|
|
fix32 zoneStart = FIX32(zone * 512);
|
|
fix32 randX, randY;
|
|
u16 attempts = 0;
|
|
do {
|
|
// Random X within zone: zoneStart + random(0-511)
|
|
randX = zoneStart + FIX32(random() % 512);
|
|
randY = FIX32(16 + (random() % 192));
|
|
attempts++;
|
|
} while(!isValidEnemyPosition(randX, randY) && attempts < 100);
|
|
|
|
enemies[i].pos.x = randX;
|
|
enemies[i].pos.y = randY;
|
|
enemies[i].off = 16;
|
|
enemies[i].image = SPR_addSprite(&butterflySprite,
|
|
getScreenX(enemies[i].pos.x, player.camera) - enemies[i].off, fix32ToInt(enemies[i].pos.y) - enemies[i].off, TILE_ATTR(gameOver ? PAL1 : PAL0, 0, 0, 0));
|
|
enemies[i].angle = random() % 2 < 1 ? 128 : 384;
|
|
enemies[i].speed = FIX32(1);
|
|
enemies[i].vel.x = fix32Mul(fix16ToFix32(cosFix16(enemies[i].angle)), enemies[i].speed);
|
|
enemies[i].vel.y = fix32Mul(fix16ToFix32(sinFix16(enemies[i].angle)), enemies[i].speed);
|
|
for(u8 j = 0; j < PROP_COUNT; j++){
|
|
enemies[i].ints[j] = 0;
|
|
}
|
|
switch(enemies[i].type){
|
|
case 0:
|
|
loadEnemyOne(i);
|
|
break;
|
|
}
|
|
|
|
}
|
|
|
|
static void boundsEnemy(u8 i){
|
|
if(enemies[i].pos.y >= GAME_H_F - FIX32(enemies[i].off) || enemies[i].pos.y <= FIX32(enemies[i].off))
|
|
enemies[i].vel.y *= -1;
|
|
|
|
if(enemies[i].pos.x >= GAME_WRAP){
|
|
enemies[i].pos.x -= GAME_WRAP;
|
|
}
|
|
if(enemies[i].pos.x < 0){
|
|
enemies[i].pos.x += GAME_WRAP;
|
|
}
|
|
}
|
|
|
|
static void updateEnemy(u8 i){
|
|
boundsEnemy(i);
|
|
enemies[i].pos.x += enemies[i].vel.x;
|
|
enemies[i].pos.y += enemies[i].vel.y;
|
|
|
|
switch(enemies[i].type){
|
|
case 0:
|
|
updateEnemyOne(i);
|
|
break;
|
|
}
|
|
|
|
s16 sx = getScreenX(enemies[i].pos.x, player.camera);
|
|
s16 sy = fix32ToInt(enemies[i].pos.y);
|
|
fix32 dx = getWrappedDelta(enemies[i].pos.x, player.pos.x);
|
|
bool onScreen = (dx >= FIX32(-256) && dx <= FIX32(256));
|
|
SPR_setVisibility(enemies[i].image, onScreen ? VISIBLE : HIDDEN);
|
|
SPR_setPosition(enemies[i].image, sx - enemies[i].off, sy - enemies[i].off);
|
|
|
|
enemies[i].clock++;
|
|
if(enemies[i].clock >= CLOCK_LIMIT) enemies[i].clock = 0;
|
|
enemyCount++;
|
|
}
|
|
|
|
void updateEnemies(){
|
|
enemyCount = 0;
|
|
for(s16 i = 0; i < ENEMY_COUNT; i++) if(enemies[i].active)
|
|
updateEnemy(i);
|
|
intToStr(enemyCount, debugStr, 1);
|
|
} |