power grower powerup
This commit is contained in:
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user