diff --git a/res/clouds.png b/res/clouds.png new file mode 100644 index 0000000..2ef1ec5 Binary files /dev/null and b/res/clouds.png differ diff --git a/res/ground.png b/res/ground.png new file mode 100644 index 0000000..1d66e9e Binary files /dev/null and b/res/ground.png differ diff --git a/res/mapenemy.png b/res/mapenemy.png new file mode 100644 index 0000000..b14a824 Binary files /dev/null and b/res/mapenemy.png differ diff --git a/res/mapframe.png b/res/mapframe.png new file mode 100644 index 0000000..80d11a8 Binary files /dev/null and b/res/mapframe.png differ diff --git a/res/mapindicator.png b/res/mapindicator.png new file mode 100644 index 0000000..93ae0b5 Binary files /dev/null and b/res/mapindicator.png differ diff --git a/res/mapplayer.png b/res/mapplayer.png new file mode 100644 index 0000000..c08bfcf Binary files /dev/null and b/res/mapplayer.png differ diff --git a/res/resources.res b/res/resources.res index 2330de0..000a46b 100644 --- a/res/resources.res +++ b/res/resources.res @@ -4,6 +4,9 @@ IMAGE shadow "shadow.png" NONE NONE IMAGE logo "logo.png" NONE NONE IMAGE sky "sky.png" NONE NONE +IMAGE ground "ground.png" NONE NONE +// IMAGE clouds "clouds.png" NONE NONE + IMAGE fadeTop "fadetop.png" NONE NONE IMAGE fadeBottom "fadebottom.png" NONE NONE @@ -16,4 +19,8 @@ SPRITE pBulletSprite "pbullet.png" 4 4 NONE 0 SPRITE butterflySprite "butterfly.png" 4 4 NONE 8 // SPRITE fairySprite "fairy.png" 4 4 NONE 8 SPRITE fairySprite "fairy2.png" 4 4 NONE 8 -SPRITE aliceSprite "alice.png" 6 6 NONE 0 \ No newline at end of file +SPRITE aliceSprite "alice.png" 6 6 NONE 0 + +// IMAGE mapPlayer "mapplayer.png" NONE NONE +IMAGE mapIndicator "mapindicator.png" NONE NONE +// IMAGE mapFrame "mapframe.png" NONE NONE \ No newline at end of file diff --git a/res/sakuya2.png b/res/sakuya2.png index f68a7db..e201cca 100644 Binary files a/res/sakuya2.png and b/res/sakuya2.png differ diff --git a/res/sky.png b/res/sky.png index e20f9c9..bad2f06 100644 Binary files a/res/sky.png and b/res/sky.png differ diff --git a/src/background.h b/src/background.h index ef7e5a7..303132b 100644 --- a/src/background.h +++ b/src/background.h @@ -1,13 +1,14 @@ #define BG_I 8 -#define FADE_TOP_I BG_I + 64 -#define FADE_BOTTOM_I FADE_TOP_I + 64 +// #define FADE_TOP_I BG_I + 64 +// #define FADE_BOTTOM_I FADE_TOP_I + 64 #define BG_OFF 112 void loadBackground(){ VDP_loadTileSet(sky.tileset, BG_I, DMA); - VDP_loadTileSet(fadeTop.tileset, FADE_TOP_I, DMA); - VDP_loadTileSet(fadeBottom.tileset, FADE_BOTTOM_I, DMA); + VDP_loadTileSet(ground.tileset, BG_I + 64, DMA); + // VDP_loadTileSet(fadeTop.tileset, FADE_TOP_I, DMA); + // VDP_loadTileSet(fadeBottom.tileset, FADE_BOTTOM_I, DMA); for(u8 y = 0; y < 4; y++){ for(u8 x = 0; x < 16; x++){ VDP_fillTileMapRectInc(BG_B, TILE_ATTR_FULL(PAL1, 0, 0, 0, BG_I), x * 8, y * 8, 8, 8); diff --git a/src/bullets.h b/src/bullets.h index d72147d..5c34ff1 100644 --- a/src/bullets.h +++ b/src/bullets.h @@ -66,7 +66,14 @@ void spawnBullet(struct bulletSpawner spawner, void(*updater)){ // Find available slot, return if none s16 i = -1; for(s16 j = 0; j < BULLET_COUNT; j++) if(!bullets[j].active) { i = j; break; } - if(i == -1) return; + if(i == -1 && spawner.player){ + + for(s16 j = 0; j < BULLET_COUNT; j++) if(bullets[j].active && !bullets[j].player){ + killBullet(j, FALSE); + i = j; + } + + } else if(i == -1 && !spawner.player) return; bullets[i].active = TRUE; bullets[i].pos.x = spawner.x; @@ -154,7 +161,7 @@ static void updateBulletExplosion(u8 i){ s16 sx = getScreenX(bullets[i].pos.x, player.camera); s16 sy = fix32ToInt(bullets[i].pos.y); u8 off = bullets[i].player ? P_BULLET_OFF : BULLET_OFF; - SPR_setPosition(bullets[i].image, sx - off, sy); + SPR_setPosition(bullets[i].image, sx - off, sy - off); } static void updateBullet(u8 i){ @@ -176,7 +183,7 @@ static void updateBullet(u8 i){ bool offScreenX = (dx < -CULL_LIMIT || dx > CULL_LIMIT); bool offScreenTop = (bullets[i].pos.y < FIX32(-16)); - bool offScreenBottom = (bullets[i].pos.y > GAME_H_F - FIX32(8)); + bool offScreenBottom = (bullets[i].pos.y > GAME_H_F); if(offScreenX || offScreenTop){ killBullet(i, FALSE); @@ -204,5 +211,5 @@ void updateBullets(){ bulletCount = 0; for(s16 i = 0; i < BULLET_COUNT; i++) if(bullets[i].active) updateBullet(i); - intToStr(bulletCount, debugStr, 1); + // intToStr(bulletCount, debugStr, 1); } \ No newline at end of file diff --git a/src/chrome.h b/src/chrome.h index ff2216a..1aa8d6e 100644 --- a/src/chrome.h +++ b/src/chrome.h @@ -1,12 +1,101 @@ +#define MAP_I 512 +#define MAP_TILE TILE_ATTR_FULL(PAL1, 1, 0, 0, MAP_I) +#define MAP_PLAYER_TILE TILE_ATTR_FULL(PAL0, 1, 0, 0, MAP_I + 1) +#define MAP_ENEMY_TILE TILE_ATTR_FULL(PAL0, 1, 0, 0, MAP_I + 2) +#define MAP_BORDER_X_TILE TILE_ATTR_FULL(PAL0, 1, 0, 0, MAP_I + 3) + char scoreStr[SCORE_LENGTH]; u32 lastScore; +// previous map positions: -1 means not drawn +s16 mapEnemyCol[ENEMY_COUNT], mapEnemyRow[ENEMY_COUNT]; +s16 mapPlayerRow; + static void drawScore(){ uintToStr(score, scoreStr, 1); - VDP_drawText(scoreStr, 1, 1); + VDP_drawText(scoreStr, 1, 5); +} + +// load map when stage does so we have all enemies + player +void loadMap(){ + VDP_fillTileMapRect(BG_A, MAP_TILE, MAP_X, MAP_Y, MAP_W, MAP_H); + + // VDP_fillTileMapRect(BG_A, TILE_ATTR_FULL(PAL0, 1, 0, 0, MAP_I + 3), MAP_X, MAP_Y - 1, MAP_W, 1); + // VDP_fillTileMapRect(BG_A, TILE_ATTR_FULL(PAL0, 1, 1, 0, MAP_I + 3), MAP_X, MAP_Y + MAP_H, MAP_W, 1); + + // VDP_fillTileMapRect(BG_A, TILE_ATTR_FULL(PAL0, 1, 0, 0, MAP_I + 4), MAP_X - 1, MAP_Y, 1, MAP_H); + + for(s16 i = 0; i < ENEMY_COUNT; i++){ + mapEnemyCol[i] = -1; + mapEnemyRow[i] = -1; + } + mapPlayerRow = -1; +} + +// temp arrays for new positions +s16 mapNewCol[ENEMY_COUNT], mapNewRow[ENEMY_COUNT]; + +static bool mapTileOccupied(s16 col, s16 row, s16 pRow){ + // player always at center column + if(col == MAP_W / 2 && row == pRow) return TRUE; + for(s16 i = 0; i < ENEMY_COUNT; i++) + if(mapNewCol[i] == col && mapNewRow[i] == row) return TRUE; + return FALSE; +} + +static void updateMap(){ + // compute new player row + s16 pRow = fix32ToInt(player.pos.y) / 75; + if(pRow < 0) pRow = 0; + if(pRow >= MAP_H) pRow = MAP_H - 1; + + // compute new enemy positions + for(s16 i = 0; i < ENEMY_COUNT; i++){ + if(!enemies[i].active || enemies[i].image == NULL){ + mapNewCol[i] = -1; + mapNewRow[i] = -1; + continue; + } + fix32 dx = getWrappedDelta(enemies[i].pos.x, player.pos.x); + s16 col = fix32ToInt(dx) / 54 + MAP_W / 2; + if(col < 0) col = 0; + if(col >= MAP_W) col = MAP_W - 1; + s16 row = fix32ToInt(enemies[i].pos.y) / 75; + if(row < 0) row = 0; + if(row >= MAP_H) row = MAP_H - 1; + mapNewCol[i] = col; + mapNewRow[i] = row; + } + + // clear old player tile if it moved and nothing new occupies it + if(mapPlayerRow >= 0 && mapPlayerRow != pRow) + if(!mapTileOccupied(MAP_W / 2, mapPlayerRow, pRow)) + VDP_setTileMapXY(BG_A, MAP_TILE, MAP_X + MAP_W / 2, MAP_Y + mapPlayerRow); + + // clear old enemy tiles that moved or disappeared + for(s16 i = 0; i < ENEMY_COUNT; i++){ + if(mapEnemyCol[i] < 0) continue; + if(mapEnemyCol[i] == mapNewCol[i] && mapEnemyRow[i] == mapNewRow[i]) continue; + if(!mapTileOccupied(mapEnemyCol[i], mapEnemyRow[i], pRow)) + VDP_setTileMapXY(BG_A, MAP_TILE, MAP_X + mapEnemyCol[i], MAP_Y + mapEnemyRow[i]); + } + + // draw enemy dots (skip if player occupies same tile) + for(s16 i = 0; i < ENEMY_COUNT; i++){ + mapEnemyCol[i] = mapNewCol[i]; + mapEnemyRow[i] = mapNewRow[i]; + if(mapNewCol[i] < 0) continue; + if(mapNewCol[i] == MAP_W / 2 && mapNewRow[i] == pRow) continue; + VDP_setTileMapXY(BG_A, MAP_ENEMY_TILE, MAP_X + mapNewCol[i], MAP_Y + mapNewRow[i]); + } + + // draw player dot on top + mapPlayerRow = pRow; + VDP_setTileMapXY(BG_A, MAP_PLAYER_TILE, MAP_X + MAP_W / 2, MAP_Y + pRow); } void loadChrome(){ + VDP_loadTileSet(mapIndicator.tileset, MAP_I, DMA); drawScore(); } @@ -17,6 +106,7 @@ void updateChrome(){ lastScore = score; drawScore(); } - VDP_clearText(1, 26, 4); - VDP_drawText(debugStr, 1, 26); + if(clock % 4 == 0) updateMap(); + // VDP_clearText(1, 26, 4); + // VDP_drawText(debugStr, 1, 26); } \ No newline at end of file diff --git a/src/enemies.h b/src/enemies.h index 8b2df37..381a349 100644 --- a/src/enemies.h +++ b/src/enemies.h @@ -42,7 +42,7 @@ void spawnEnemy(u8 type, u8 zone){ enemies[i].pos.y = randY; enemies[i].off = 16; enemies[i].image = SPR_addSprite(&fairySprite, - 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)); + getScreenX(enemies[i].pos.x, player.camera) - enemies[i].off, fix32ToInt(enemies[i].pos.y) - enemies[i].off, TILE_ATTR(PAL0, 0, 0, 0)); if(!enemies[i].image){ enemies[i].active = FALSE; return; diff --git a/src/enemytypes.h b/src/enemytypes.h index 2b02d36..f538b02 100644 --- a/src/enemytypes.h +++ b/src/enemytypes.h @@ -1,22 +1,25 @@ void loadEnemyOne(u8 i){ - enemies[i].ints[0] = random() % 60; + enemies[i].ints[0] = random() % 40; enemies[i].angle = ((random() % 4) * 256) + 128; enemies[i].speed = FIX32(2); } void updateEnemyOne(u8 i){ - if(enemies[i].clock % 60 == enemies[i].ints[0] && enemies[i].onScreen){ - enemies[i].clock % 120 == enemies[i].ints[0] ? sfxEnemyShotB() : sfxEnemyShotA(); + if(enemies[i].clock % 40 == enemies[i].ints[0] && enemies[i].onScreen){ + enemies[i].clock % 80 == enemies[i].ints[0] ? sfxEnemyShotB() : sfxEnemyShotA(); struct bulletSpawner spawner = { .x = enemies[i].pos.x, .y = enemies[i].pos.y, - // .anim = 6 + (random() % 3), - .anim = 6, + .anim = 3 + (random() % 3), + // .anim = 6, // .frame = 1, .speed = FIX32(2) + FIX16(random() % 4), .angle = random() % 128, }; - // if(random() % 2 < 1) spawner.anim += 3; + switch(random() % 3){ + case 1: spawner.anim += 3; break; + case 2: spawner.anim += 6; break; + } for(u8 j = 0; j < 8; j++){ spawnBullet(spawner, EMPTY); spawner.angle += 128; diff --git a/src/global.h b/src/global.h index dcc009d..77b84cc 100644 --- a/src/global.h +++ b/src/global.h @@ -15,6 +15,11 @@ u32 score; #define FIRST_ROTATING_BULLET 3 +#define MAP_X 1 +#define MAP_Y 1 +#define MAP_W 38 +#define MAP_H 3 + char debugStr[8]; void EMPTY(s16 i){(void)i;} diff --git a/src/player.h b/src/player.h index 08b55b4..75ff7bb 100644 --- a/src/player.h +++ b/src/player.h @@ -138,5 +138,5 @@ void updatePlayer(){ SPR_setPosition(player.image, sx - PLAYER_OFF, sy - PLAYER_OFF); - // intToStr(fix32ToInt(player.pos.x), debugStr, 1); + intToStr(fix32ToInt(player.pos.x), debugStr, 1); } \ No newline at end of file diff --git a/src/stage.h b/src/stage.h index 5aa93c0..723bcd3 100644 --- a/src/stage.h +++ b/src/stage.h @@ -5,4 +5,5 @@ void loadStage(){ spawnEnemy(0, zone); } } + loadMap(); } \ No newline at end of file