diff --git a/res/fg/rock1lt.png b/res/fg/rock1lt.png new file mode 100644 index 0000000..79c5297 Binary files /dev/null and b/res/fg/rock1lt.png differ diff --git a/res/fg/rock1rt.png b/res/fg/rock1rt.png new file mode 100644 index 0000000..3ade725 Binary files /dev/null and b/res/fg/rock1rt.png differ diff --git a/res/resources.res b/res/resources.res index da127e1..dd5dd7b 100644 --- a/res/resources.res +++ b/res/resources.res @@ -9,6 +9,8 @@ IMAGE rock1r "fg/rock1r.png" FAST IMAGE rock1b "fg/rock1b.png" FAST IMAGE rock1t "fg/rock1t.png" FAST +IMAGE rock1lt "fg/rock1lt.png" FAST +IMAGE rock1rt "fg/rock1rt.png" FAST SPRITE nitori "player/nitori.png" 4 4 FAST diff --git a/src/foreground.h b/src/foreground.h index b6bc5bc..9a2f24b 100644 --- a/src/foreground.h +++ b/src/foreground.h @@ -4,9 +4,13 @@ #define FG_W GAME_W_T + 30 #define OBSTACLE_COUNT 8 +#define FG_SPEED FIX16(2) +#define FG_SPEED_NORM FIX16(1.414) + struct obstacle { - bool active; + bool active, top; Vect2D_f16 pos; + s16 startX; }; struct obstacle obstacles[OBSTACLE_COUNT]; @@ -27,24 +31,58 @@ static void drawFg(){ // obstacle +#define OBS_CEIL_Y CEIL_Y + 4 #define OBS_FLOOR_Y FLOOR_Y - 4 -s16 fgPos; -s16 obsX; +#define OBS_X 32 -static void spawnObstacle(){ - obsX = 32; - VDP_drawImageEx(BG_B, &rock1l, TILE_ATTR_FULL(PAL2, 1, 0, 0, FG_I + 32), obsX, OBS_FLOOR_Y, 0, DMA); - VDP_drawImageEx(BG_B, &rock1, TILE_ATTR_FULL(PAL2, 1, 0, 0, FG_I + 48), obsX + 2, OBS_FLOOR_Y, 0, DMA); - VDP_drawImageEx(BG_B, &rock1r, TILE_ATTR_FULL(PAL2, 1, 0, 0, FG_I + 64), obsX + 2 + 4, OBS_FLOOR_Y, 0, DMA); - VDP_drawImageEx(BG_B, &rock1b, TILE_ATTR_FULL(PAL2, 1, 0, 0, FG_I + 80), obsX + 2, OBS_FLOOR_Y + 4, 0, DMA); +s16 fgPos; + +static void spawnObstacle(bool top){ + s16 i = -1; + for(s16 j = 0; j < OBSTACLE_COUNT; j++) if(!obstacles[j].active && i == -1) i = j; + if(i > -1){ + obstacles[i].active = TRUE; + obstacles[i].top = top; + obstacles[i].pos.x = FIX16(256); + obstacles[i].startX = OBS_X; + if(top){ + VDP_drawImageEx(BG_B, &rock1lt, TILE_ATTR_FULL(PAL2, 1, 0, 0, FG_I + 32), OBS_X, OBS_CEIL_Y - 2, 0, DMA); + VDP_drawImageEx(BG_B, &rock1t, TILE_ATTR_FULL(PAL2, 1, 0, 0, FG_I + 48), OBS_X + 2, OBS_CEIL_Y, 0, DMA); + VDP_drawImageEx(BG_B, &rock1rt, TILE_ATTR_FULL(PAL2, 1, 0, 0, FG_I + 64), OBS_X + 2 + 4, OBS_CEIL_Y - 2, 0, DMA); + VDP_drawImageEx(BG_B, &rock1b, TILE_ATTR_FULL(PAL2, 1, 0, 0, FG_I + 80), OBS_X + 2, OBS_CEIL_Y - 4, 0, DMA); + } else { + VDP_drawImageEx(BG_B, &rock1l, TILE_ATTR_FULL(PAL2, 1, 0, 0, FG_I + 32 + 80), OBS_X, OBS_FLOOR_Y, 0, DMA); + VDP_drawImageEx(BG_B, &rock1, TILE_ATTR_FULL(PAL2, 1, 0, 0, FG_I + 48 + 80), OBS_X + 2, OBS_FLOOR_Y, 0, DMA); + VDP_drawImageEx(BG_B, &rock1r, TILE_ATTR_FULL(PAL2, 1, 0, 0, FG_I + 64 + 80), OBS_X + 2 + 4, OBS_FLOOR_Y, 0, DMA); + VDP_drawImageEx(BG_B, &rock1b, TILE_ATTR_FULL(PAL2, 1, 0, 0, FG_I + 80), OBS_X + 2, OBS_FLOOR_Y + 4, 0, DMA); + } + } +} + +#define OBSTACLE_MOD FIX16(8) +#define OBSTACLE_LIMIT_X FIX16(-64) + +static void killObstacle(s16 i){ + obstacles[i].active = FALSE; + if(obstacles[i].top){ + VDP_clearTileMapRect(BG_B, obstacles[i].startX, OBS_CEIL_Y, 8, 8); + for(u8 i = 0; i < 2; i++) VDP_drawImageEx(BG_B, &rock1t, TILE_ATTR_FULL(PAL2, 1, 0, 0, FG_I),obstacles[i].startX + 4 * i, CEIL_Y, 0, DMA); + } else { + VDP_clearTileMapRect(BG_B, obstacles[i].startX, OBS_FLOOR_Y, 8, 8); + for(u8 i = 0; i < 2; i++) VDP_drawImageEx(BG_B, &rock1, TILE_ATTR_FULL(PAL2, 1, 0, 0, FG_I + 16), obstacles[i].startX + 4 * i, FLOOR_Y, 0, DMA); + } +} + +static void updateObstacle(s16 i){ + obstacles[i].pos.x = fix16Sub(obstacles[i].pos.x, FG_SPEED); + if(obstacles[i].pos.x <= OBSTACLE_LIMIT_X){ + killObstacle(i); + } } // update -#define FG_SPEED FIX16(2) -#define FG_SPEED_NORM FIX16(1.414) - #define FG_SIZE 32 #define FG_LIMIT FIX16(-320) @@ -70,10 +108,12 @@ static void scrollFg(){ void loadFg(){ drawFg(); - spawnObstacle(); + spawnObstacle(FALSE); + spawnObstacle(TRUE); } void updateFg(){ VDP_setHorizontalScrollTile(BG_B, 0, fgPosX, GAME_H_T, DMA); scrollFg(); + for(s16 i = 0; i < OBSTACLE_COUNT; i++) if(obstacles[i].active) updateObstacle(i); } \ No newline at end of file