diff --git a/res/fg/rock2bottom.png b/res/fg/rock2bottom.png new file mode 100644 index 0000000..0fec024 Binary files /dev/null and b/res/fg/rock2bottom.png differ diff --git a/res/fg/rock2top.png b/res/fg/rock2top.png new file mode 100644 index 0000000..8cef8c1 Binary files /dev/null and b/res/fg/rock2top.png differ diff --git a/res/font.png b/res/font.png index b9f7c7c..b78a4ff 100644 Binary files a/res/font.png and b/res/font.png differ diff --git a/res/resources.res b/res/resources.res index a19b516..0be75d8 100644 --- a/res/resources.res +++ b/res/resources.res @@ -5,10 +5,15 @@ IMAGE startLogo1 "start/logo1.png" FAST IMAGE frame "chrome/frame.png" FAST + +// background + IMAGE wall1 "bg/wall1.png" FAST -IMAGE rock1Bottom "fg/rock1bottom.png" FAST +// foreground + +IMAGE rock1Bottom "fg/rock1bottom.png" FAST IMAGE rock1Top "fg/rock1top.png" FAST IMAGE obstacle1LeftBottom "fg/obstacle1leftbottom.png" FAST @@ -19,9 +24,13 @@ IMAGE obstacle1LeftTop "fg/obstacle1lefttop.png" FAST IMAGE obstacle1RightTop "fg/obstacle1righttop.png" FAST IMAGE obstacle1MiddleTop "fg/obstacle1middletop.png" FAST +IMAGE rock2Bottom "fg/rock2bottom.png" FAST +IMAGE rock2Top "fg/rock2top.png" FAST + + +// player and enemies SPRITE nitori "player/nitori.png" 4 4 FAST - SPRITE fairy1 "enemies/fairy1.png" 5 4 FAST SPRITE smallRedBullet "bullets/smallred.png" 1 1 FAST 5 diff --git a/src/foreground.h b/src/foreground.h index e9cf27e..7ad4dc2 100644 --- a/src/foreground.h +++ b/src/foreground.h @@ -4,8 +4,8 @@ #define FG_W 64 #define OBSTACLE_COUNT 24 -#define FG_SPEED FIX16(2) -#define FG_SPEED_NORM FIX16(1.414) +#define FG_SPEED FIX16(1.75) +#define FG_SPEED_NORM FIX16(1.75 * 0.707) struct obstacle { bool active, top; @@ -14,6 +14,9 @@ struct obstacle { }; struct obstacle obstacles[OBSTACLE_COUNT]; +s16 currentFg; +SpriteDefinition* currentTopImage; +SpriteDefinition* currentBottomImage; // draw @@ -21,10 +24,20 @@ struct obstacle obstacles[OBSTACLE_COUNT]; #define FLOOR_Y 24 static void drawFg(){ + switch(currentFg){ + case 0: + currentTopImage = &rock1Top; + currentBottomImage = &rock1Bottom; + break; + case 1: + currentTopImage = &rock2Top; + currentBottomImage = &rock2Bottom; + break; + } for(u16 x = 0; x < FG_W; x++){ if(x % 4 == 0){ - VDP_drawImageEx(BG_B, &rock1Top, TILE_ATTR_FULL(PAL2, 1, 0, 0, FG_I), x, CEIL_Y, 0, DMA); - VDP_drawImageEx(BG_B, &rock1Bottom, TILE_ATTR_FULL(PAL2, 1, 0, 0, FG_I + 16), x, FLOOR_Y, 0, DMA); + VDP_drawImageEx(BG_B, currentTopImage, TILE_ATTR_FULL(PAL2, 1, 0, 0, FG_I), x, CEIL_Y, 0, DMA); + VDP_drawImageEx(BG_B, currentBottomImage, TILE_ATTR_FULL(PAL2, 1, 0, 0, FG_I + 16), x, FLOOR_Y, 0, DMA); } } } @@ -72,13 +85,6 @@ static void spawnObstacle(bool top, s16 offset, u8 type){ VDP_drawImageEx(BG_B, obstacleImage, TILE_ATTR_FULL(PAL2, 1, 0, 0, OBS_I + obstacleI), obsX, top ? OBS_CEIL_Y : OBS_FLOOR_Y, 0, DMA); - - // VDP_drawImageEx(BG_B, - // top ? (j == 0 ? &rock1lt : (j == 1 ? &rock1t : (j == 2 ? &rock1rt : &rock1b))) : (j == 0 ? &rock1l : (j == 1 ? &rock1 : (j == 2 ? &rock1r : &rock1b))), - // TILE_ATTR_FULL(PAL2, 1, 0, 0, FG_I + (top ? (j == 0 ? 32 : (j == 1 ? 48 : (j == 2 ? 64 : 80))) : (j == 0 ? 112 : (j == 1 ? 128 : (j == 2 ? 144 : 80))))), - // obsX + (top ? (j == 1 || j == 3 ? 2 : (j == 2 ? 6 : 0)) : ((j == 1 || j == 3 ? 2 : (j == 2 ? 6 : 0)))), - // top ? (OBS_CEIL_Y - (j == 0 || j == 2 ? 2 : (j == 3 ? 4 : 0))) : (OBS_FLOOR_Y + (j == 3 ? 4 : 0)), - // 0, DMA); } } @@ -89,11 +95,13 @@ SpriteDefinition* obstacleImage; static void killObstacle(s16 i){ obstacles[i].active = FALSE; - VDP_clearTileMapRect(BG_B, obstacles[i].startX, obstacles[i].top ? OBS_CEIL_Y + 4 : OBS_FLOOR_Y, 8, 4); - for(u8 x = 0; x < 2; x++){ - VDP_drawImageEx(BG_B, obstacles[i].top ? &rock1Top : &rock1Bottom, TILE_ATTR_FULL(PAL2, 1, 0, 0, FG_I + (obstacles[i].top ? 0 : 16)), - obstacles[i].startX + 4 * x, obstacles[i].top ? CEIL_Y : FLOOR_Y, 0, DMA_QUEUE); - } + VDP_clearTileMapRect(BG_B, obstacles[i].startX, obstacles[i].top ? OBS_CEIL_Y + 4 : OBS_FLOOR_Y, 4, 4); + VDP_drawImageEx(BG_B, + obstacles[i].top ? currentTopImage : currentBottomImage, + TILE_ATTR_FULL(PAL2, 1, 0, 0, FG_I + (obstacles[i].top ? 0 : 16)), + obstacles[i].startX, + obstacles[i].top ? CEIL_Y : FLOOR_Y, + 0, DMA_QUEUE); } static void collideObstacle(s16 i){ @@ -116,16 +124,21 @@ static void updateObstacle(s16 i){ s16 fgPosX[GAME_H_T]; fix16 fgPosXF[GAME_H_T]; - static void scrollFg(){ for(u8 y = 0; y < GAME_H_T; y++){ if(y > 2){ fgPosXF[y] = fix16Sub(fgPosXF[y], FG_SPEED); if(fgPosXF[y] <= FG_LIMIT) fgPosXF[y] = 0; fgPosX[y] = fix16ToInt(fgPosXF[y]); - if(y == 3) fgPos = fgPosX[y]; } } + fgPos = fgPosX[3]; +} + +void nextFg(){ + VDP_clearTileMapRect(BG_B, 0, OBS_CEIL_Y + 4, FG_W, 17); + currentFg++; + drawFg(); } diff --git a/src/global.h b/src/global.h index 3d95b75..69b926f 100644 --- a/src/global.h +++ b/src/global.h @@ -37,10 +37,10 @@ Vect2D_f16 hPos, velPos; Vect2D_f16 hone(Vect2D_f16 pos, Vect2D_f16 target, fix16 speed, s16 lerp){ hPos.x = target.x; hPos.y = target.y; - // if(lerp > 0){ - // hPos.x = fix16Add(fix16Sub(hPos.x, FIX16(lerp)), FIX16(random() % (lerp * 2))); - // hPos.y = fix16Add(fix16Sub(hPos.y, FIX16(lerp)), FIX16(random() % (lerp * 2))); - // } + if(lerp > 0){ + hPos.x = fix16Add(fix16Sub(hPos.x, FIX16(lerp)), FIX16(random() % (lerp * 2))); + hPos.y = fix16Add(fix16Sub(hPos.y, FIX16(lerp)), FIX16(random() % (lerp * 2))); + } honeSpeed = fix32ToFix16(getApproximatedDistance( fix32Sub(fix16ToFix32(pos.x), fix16ToFix32(hPos.x)), fix32Sub(fix16ToFix32(pos.y), fix16ToFix32(hPos.y)))); diff --git a/src/stage.h b/src/stage.h index eab6cff..dfff2b1 100644 --- a/src/stage.h +++ b/src/stage.h @@ -3,12 +3,12 @@ #define SPAWN_MID 124 -// waves +// groups -static void waveOne(s16 off, bool big){ +static void groupOne(s16 off, bool firesAll){ struct enemySpawner spawner = { .angle = 512, - .speed = FIX16(0.8), + .speed = FIX16(1), .x = GAME_W + 20, .y = SPAWN_MID + off, .image = &fairy1, @@ -30,39 +30,65 @@ static void waveOne(s16 off, bool big){ .angle = 512, .speed = FIX16(1.5) }; - if(enemies[i].bools[1]){ - spawner.image = &bigRedBullet; - spawner.big = TRUE; - } spawner.vel = hone(enemies[i].pos, player.pos, spawner.speed, 0); spawnBullet(spawner, EMPTY); } } for(u8 j = 0; j < 3; j++){ - spawner.bools[0] = j == 2; - spawner.bools[1] = big ? TRUE : FALSE; + spawner.bools[0] = j == 2 || firesAll; spawnEnemy(spawner, updater, EMPTY); - spawner.x += 40; + spawner.x += 44; } } // loop -s16 stageClock; +s16 stageClock, + nextClock, + currentWave; static void updateWaves(){ - switch(stageClock){ - case 0: - for(s16 i = 0; i < 8; i++) - for(s16 j = 0; j < 2; j++) spawnObstacle(j == 0 ? TRUE : FALSE, 256 - 32 * i, i == 7 ? 2 : 1); - break; - // case 0: waveOne(-32, FALSE); break; - // case 180: waveOne(32, FALSE); break; - // case 360: waveOne(0, TRUE); break; + if(stageClock == nextClock){ + switch(currentWave){ + case 0: + for(s16 i = 0; i < 6; i++) + for(s16 j = 0; j < 2; j++) spawnObstacle(j == 0 ? TRUE : FALSE, 256 - i * 32, i == 5 ? 2 : 1); + groupOne(0, FALSE); + nextClock += 180; + break; + case 1: + for(s16 i = 0; i < 6; i++) + spawnObstacle(FALSE, 0 - i * 32, i == 0 ? 0 : (i == 5 ? 2 : 1)); + groupOne(-24, FALSE); + nextClock += 180; + break; + case 2: + for(s16 i = 0; i < 6; i++) + spawnObstacle(TRUE, 0 - i * 32, i == 0 ? 0 : (i == 5 ? 2 : 1)); + groupOne(24, FALSE); + nextClock += 180; + break; + case 3: + groupOne(0, FALSE); + nextClock += 180; + break; + case 4: + nextFg(); + break; + } + currentWave++; } } + + + + // case 0: groupOne(-32, FALSE); break; + // case 180: groupOne(32, FALSE); break; + // case 360: groupOne(0, TRUE); break; + + void updateStage(){ updateWaves(); stageClock++;