From d92817820ab5e3a72ea00f0ddb5bb04e100625ca Mon Sep 17 00:00:00 2001 From: James Turk Date: Sun, 30 Apr 2023 04:34:36 -0500 Subject: [PATCH] fix explosions --- games/boybomb.p8 | 133 +++++++++++++++++++++++++--------------------- games/sprites.lua | 9 ++++ 2 files changed, 82 insertions(+), 60 deletions(-) diff --git a/games/boybomb.p8 b/games/boybomb.p8 index 5182a85..d9d1fe0 100644 --- a/games/boybomb.p8 +++ b/games/boybomb.p8 @@ -184,7 +184,6 @@ levels = { function start_level(n) start_scene("level") last_gravity = t() - exploding = false level_dets = 0 level_boxes = 0 level_num = n @@ -215,7 +214,6 @@ end particles = {} function add_particles(gx, gy, colors) - sfx(0) local x = gx*8+4 local y = gy*8+4 for i=0,30 do @@ -287,79 +285,92 @@ function can_move(dx, dy) return true end +explosion_types = { + fire={8, 9, 10}, + wood={4, 15}, +} + +function add_explosion(x, y, countdown, colors) + explode_grid[y][x] = {countdown=countdown, colors=colors} +end + function explosion_adjacent(x, y) -- called when the block next door explodes local block = puzzle_grid[y][x] - puzzle_grid[y][x] = 0 - if block == BOX_FIRE then + if block == BOX_WOOD then + add_explosion(x, y, 1, explosion_types.wood) + elseif block == BOX_FIRE then -- TODO: add explosion end end -function process_block(x, y) +function update_exp_grid(x, y) -- called on each block each frame + -- the explosion grid contains countdown objects + -- grid items are {countdown, colors} local block = puzzle_grid[y][x] local explode = explode_grid[y][x] if explode then - -- grid items are {countdown, colors} - explode.countdown -= 1 - printh("CD: "..x..", "..y.." "..explode.countdown) + --printh("CD: "..x..", "..y.." "..explode.countdown) + if explode.countdown == 0 then - -- blow up the box (if present) - puzzle_grid[y][x] = 0 + -- always add particles and destroy box add_particles(x, y, explode.colors) - -- 4, 15 for box + puzzle_grid[y][x] = 0 + + if explode.colors ~= explosion_types.fire then + -- don't propagate + return + end + + -- fiery explosion + sfx(0) + local ys = {0} + local xs = {0} + if y > 1 then + add(ys, -1) + end + if y < GRID_H then + add(ys, 1) + end + if x > 1 then + add(xs, -1) + end + if x < GRID_W then + add(xs, 1) + end + for xx in all(xs) do + for yy in all(ys) do + if xx~=0 or yy~=0 then + explosion_adjacent(x+xx, y+yy) + end + end + end explode_grid[y][x] = nil end end - -- elseif block == GRID_EXPLODE then - -- local ys = {0} - -- local xs = {0} - -- if y > 1 then - -- add(ys, -1) - -- end - -- if y < GRID_H then - -- add(ys, 1) - -- end - -- if x > 1 then - -- add(xs, -1) - -- end - -- if x < GRID_W then - -- add(xs, 1) - -- end - -- for xx in all(xs) do - -- for yy in all(ys) do - -- if xx~=0 or yy~=0 then - -- explosion_adjacent(x+xx, y+yy) - -- end - -- end - -- end - -- puzzle_grid[y][x] = 0 - -- end end function update_level() - -- bombs break adjacent tiles - -- fire boxes turn into more bombs - -- goal: break all boxes - -- ??? only 8 positions? - - -- update grid + -- gravity fall_speed = 0.3 - if exploding then - if bomb_spr.speed == 0 and bomb_spr.anim then - exploding = false - bomb_spr.frame = 0 - bomb_y = 0 - end - end - printh("===") if t() - last_gravity > fall_speed then last_gravity = t() + + -- decrement explosions in separate loop to avoid + -- issues with chains + for x=1,GRID_W do + for y=1,GRID_H do + local exp = explode_grid[y][x] + if exp then + exp.countdown -= 1 + end + end + end for y=GRID_H,1,-1 do for x=1,GRID_W do - process_block(x, y) + update_exp_grid(x, y) -- fall down if y < GRID_H and puzzle_grid[y+1][x] == 0 @@ -381,11 +392,12 @@ function update_level() update_sprite(bomb_spr) update_explosions() - if exploding then - if bomb_spr.frame > 10 and bomb_spr.anim then + -- bomb animation / explosion + if bomb_spr.frame > 1 then + if bomb_spr.is_done then -- when explosion hits last frame, particles / update grid - --add_particles(bomb_x, bomb_y, {8, 9, 10}) - explode_grid[bomb_y][bomb_x] = {countdown=1, colors={8, 9, 10}} + reset_sprite(bomb_spr) + bomb_y = 0 end -- exploding means we're done before input comes return @@ -412,6 +424,12 @@ function update_level() explode() end + -- bomb gravity after movement + if bomb_y < GRID_H and puzzle_grid[bomb_y+1][bomb_x] == 0 then + bomb_y += 1 + end + + -- DEBUG LEVEL SELECT if btnp(⬇️) then level_num = max(level_num-1, 1) @@ -421,16 +439,11 @@ function update_level() level_num = min(level_num+1, #levels) start_level(level_num) end - - -- fall immediately - if bomb_y < GRID_H and puzzle_grid[bomb_y+1][bomb_x] == 0 then - bomb_y += 1 - end end function explode() - exploding = true bomb_spr.speed = 0.1 + add_explosion(bomb_x, bomb_y, 4, explosion_types.fire) level_dets += 1 end diff --git a/games/sprites.lua b/games/sprites.lua index cbf40e8..122936c 100644 --- a/games/sprites.lua +++ b/games/sprites.lua @@ -4,10 +4,18 @@ function make_sprite(x, y, anim, speed) vx=0, vy=0, frame=0, last_update=t(), flip_x=false, flip_y=false, loop=false, + is_done=false, } return s end +function reset_sprite(s) + s.speed = 0 + s.frame = 0 + s.last_update = t() + s.is_done = false +end + function update_sprite(s) local now = t() if s.last_update == 0 then @@ -26,6 +34,7 @@ function update_sprite(s) else s.speed = 0 s.frame = #s.anim.frames + s.is_done = true end end