4
0

power grower powerup

This commit is contained in:
Zsolt Tasnadi
2025-12-04 14:01:16 +01:00
parent 083ab16f5c
commit 9b9271c7d6

View File

@@ -93,12 +93,34 @@ function Map.can_move_to(gridX, gridY)
return true return true
end end
-- powerup type definitions (extensible)
local POWERUP_TYPES = {
{type = "bomb", weight = 50}, -- extra bomb
{type = "power", weight = 50}, -- explosion range +1
}
local function get_random_powerup_type()
local total_weight = 0
for _, p in ipairs(POWERUP_TYPES) do
total_weight = total_weight + p.weight
end
local roll = math.random() * total_weight
local cumulative = 0
for _, p in ipairs(POWERUP_TYPES) do
cumulative = cumulative + p.weight
if roll <= cumulative then
return p.type
end
end
return POWERUP_TYPES[1].type
end
function Map.init_powerups() function Map.init_powerups()
powerups = {} powerups = {}
for row = 1, 9 do for row = 1, 9 do
for col = 1, 15 do for col = 1, 15 do
if map[row][col] == BREAKABLE_WALL and math.random() < 0.3 then if map[row][col] == BREAKABLE_WALL and math.random() < 0.3 then
table.insert(powerups, {gridX = col, gridY = row, type = "bomb"}) table.insert(powerups, {gridX = col, gridY = row, type = get_random_powerup_type()})
end end
end end
end end
@@ -171,8 +193,13 @@ function UI.draw_game()
local drawX = (pw.gridX - 1) * TILE_SIZE local drawX = (pw.gridX - 1) * TILE_SIZE
local drawY = (pw.gridY - 1) * TILE_SIZE local drawY = (pw.gridY - 1) * TILE_SIZE
rect(drawX + 5, drawY + 5, 10, 10, 1) -- shadow rect(drawX + 5, drawY + 5, 10, 10, 1) -- shadow
rect(drawX + 3, drawY + 3, 10, 10, 4) -- yellow background if pw.type == "bomb" then
print("B", drawX + 5, drawY + 5, 0) rect(drawX + 3, drawY + 3, 10, 10, 4) -- yellow background
print("B", drawX + 5, drawY + 5, 0)
elseif pw.type == "power" then
rect(drawX + 3, drawY + 3, 10, 10, 3) -- orange background
print("P", drawX + 5, drawY + 5, 0)
end
end end
end end
@@ -260,11 +287,12 @@ function Bomb.place(player)
end end
end end
table.insert(bombs, {x = bombX, y = bombY, timer = BOMB_TIMER, owner = player}) table.insert(bombs, {x = bombX, y = bombY, timer = BOMB_TIMER, owner = player, power = player.bombPower})
player.activeBombs = player.activeBombs + 1 player.activeBombs = player.activeBombs + 1
end end
function Bomb.explode(bombX, bombY) function Bomb.explode(bombX, bombY, power)
power = power or 1
sfx(0, nil, 30) -- explosion sound, 30 ticks = 0.5 sec sfx(0, nil, 30) -- explosion sound, 30 ticks = 0.5 sec
table.insert(explosions, {x = bombX, y = bombY, timer = EXPLOSION_TIMER}) table.insert(explosions, {x = bombX, y = bombY, timer = EXPLOSION_TIMER})
@@ -273,31 +301,35 @@ function Bomb.explode(bombX, bombY)
-- horizontal explosion -- horizontal explosion
for _, dir in ipairs({-1, 1}) do for _, dir in ipairs({-1, 1}) do
local explX = bombX + dir * TILE_SIZE for dist = 1, power do
local eGridX = gridX + dir local explX = bombX + dir * dist * TILE_SIZE
if eGridX >= 1 and eGridX <= 15 then local eGridX = gridX + dir * dist
if eGridX < 1 or eGridX > 15 then break end
local tile = map[gridY][eGridX] local tile = map[gridY][eGridX]
if tile == EMPTY then if tile == SOLID_WALL then break end
table.insert(explosions, {x = explX, y = bombY, timer = EXPLOSION_TIMER}) if tile == BREAKABLE_WALL then
elseif tile == BREAKABLE_WALL then
map[gridY][eGridX] = EMPTY map[gridY][eGridX] = EMPTY
table.insert(explosions, {x = explX, y = bombY, timer = EXPLOSION_TIMER}) table.insert(explosions, {x = explX, y = bombY, timer = EXPLOSION_TIMER})
break -- stop at breakable wall
end end
table.insert(explosions, {x = explX, y = bombY, timer = EXPLOSION_TIMER})
end end
end end
-- vertical explosion -- vertical explosion
for _, dir in ipairs({-1, 1}) do for _, dir in ipairs({-1, 1}) do
local explY = bombY + dir * TILE_SIZE for dist = 1, power do
local eGridY = gridY + dir local explY = bombY + dir * dist * TILE_SIZE
if eGridY >= 1 and eGridY <= 9 then local eGridY = gridY + dir * dist
if eGridY < 1 or eGridY > 9 then break end
local tile = map[eGridY][gridX] local tile = map[eGridY][gridX]
if tile == EMPTY then if tile == SOLID_WALL then break end
table.insert(explosions, {x = bombX, y = explY, timer = EXPLOSION_TIMER}) if tile == BREAKABLE_WALL then
elseif tile == BREAKABLE_WALL then
map[eGridY][gridX] = EMPTY map[eGridY][gridX] = EMPTY
table.insert(explosions, {x = bombX, y = explY, timer = EXPLOSION_TIMER}) table.insert(explosions, {x = bombX, y = explY, timer = EXPLOSION_TIMER})
break -- stop at breakable wall
end end
table.insert(explosions, {x = bombX, y = explY, timer = EXPLOSION_TIMER})
end end
end end
end end
@@ -547,6 +579,7 @@ function Player.create(gridX, gridY, color, is_ai)
moving = false, moving = false,
maxBombs = 1, maxBombs = 1,
activeBombs = 0, activeBombs = 0,
bombPower = 1, -- explosion range
color = color, color = color,
is_ai = is_ai, is_ai = is_ai,
moveTimer = 0, moveTimer = 0,
@@ -615,6 +648,7 @@ function Player.reset(player)
player.moving = false player.moving = false
player.maxBombs = 1 player.maxBombs = 1
player.activeBombs = 0 player.activeBombs = 0
player.bombPower = 1
player.bombCooldown = 0 player.bombCooldown = 0
end end
@@ -694,7 +728,7 @@ function TIC()
local bomb = bombs[i] local bomb = bombs[i]
bomb.timer = bomb.timer - 1 bomb.timer = bomb.timer - 1
if bomb.timer <= 0 then if bomb.timer <= 0 then
Bomb.explode(bomb.x, bomb.y) Bomb.explode(bomb.x, bomb.y, bomb.power)
if bomb.owner then if bomb.owner then
bomb.owner.activeBombs = bomb.owner.activeBombs - 1 bomb.owner.activeBombs = bomb.owner.activeBombs - 1
end end
@@ -717,7 +751,12 @@ function TIC()
local pw = powerups[i] local pw = powerups[i]
if map[pw.gridY][pw.gridX] == EMPTY and if map[pw.gridY][pw.gridX] == EMPTY and
player.gridX == pw.gridX and player.gridY == pw.gridY then player.gridX == pw.gridX and player.gridY == pw.gridY then
player.maxBombs = player.maxBombs + 1 -- apply powerup effect based on type
if pw.type == "bomb" then
player.maxBombs = player.maxBombs + 1
elseif pw.type == "power" then
player.bombPower = player.bombPower + 1
end
table.remove(powerups, i) table.remove(powerups, i)
sfx(1, nil, 8) -- short pickup beep sfx(1, nil, 8) -- short pickup beep
end end