Add slimes
This commit is contained in:
parent
9e136ab4c9
commit
98030a09a1
127
bundle/main.lua
127
bundle/main.lua
|
@ -1,7 +1,7 @@
|
|||
local debug = false
|
||||
|
||||
local cavern = {}
|
||||
local tiletypes = {unknown = 0, empty = 1, wall = 2, orb = 3}
|
||||
local tiletypes = {unknown = 0, empty = 1, wall = 2, orb = 3, slime = 4}
|
||||
|
||||
local visibility_map = {}
|
||||
local remembered_cavern = {}
|
||||
|
@ -14,6 +14,8 @@ local player_x = nil
|
|||
local player_y = nil
|
||||
local player_direction = nil
|
||||
|
||||
local slimes = {}
|
||||
|
||||
local last_key_pressed = nil
|
||||
local last_direction_moved = nil
|
||||
local move_repeat_counter = nil
|
||||
|
@ -168,11 +170,24 @@ function spawnOrb()
|
|||
repeat
|
||||
orb_x = math.random(2, cavern.width - 1)
|
||||
orb_y = math.random(2, cavern.height - 1)
|
||||
until passable(orb_x, orb_y)
|
||||
until cavern[orb_x][orb_y] == tiletypes.empty
|
||||
|
||||
cavern[orb_x][orb_y] = tiletypes.orb
|
||||
end
|
||||
|
||||
function spawnSlimes()
|
||||
-- Try spawning 20 slimes, but if they don't hit any location then don't care
|
||||
for i = 1, 20 do
|
||||
local x = math.random(2, cavern.width - 1)
|
||||
local y = math.random(2, cavern.height - 1)
|
||||
|
||||
if cavern[x][y] == tiletypes.empty then
|
||||
cavern[x][y] = tiletypes.slime
|
||||
table.insert(slimes, {x = x, y = y})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- ------------------------------------------------------------------
|
||||
-- Visibility
|
||||
-- ------------------------------------------------------------------
|
||||
|
@ -291,22 +306,22 @@ function stepVisibilityMapGeneration(queue)
|
|||
for i, item in ipairs(queue) do
|
||||
if item.direction == directions.up then
|
||||
visibility_map[item.x][item.y] = true
|
||||
if passable(item.x, item.y) then
|
||||
if seethrough(item.x, item.y) then
|
||||
table.insert(new_queue, {x = item.x, y = item.y - 1, direction = directions.up})
|
||||
end
|
||||
elseif item.direction == directions.left then
|
||||
visibility_map[item.x][item.y] = true
|
||||
if passable(item.x, item.y) then
|
||||
if seethrough(item.x, item.y) then
|
||||
table.insert(new_queue, {x = item.x - 1, y = item.y, direction = directions.left})
|
||||
end
|
||||
elseif item.direction == directions.down then
|
||||
visibility_map[item.x][item.y] = true
|
||||
if passable(item.x, item.y) then
|
||||
if seethrough(item.x, item.y) then
|
||||
table.insert(new_queue, {x = item.x, y = item.y + 1, direction = directions.down})
|
||||
end
|
||||
elseif item.direction == directions.right then
|
||||
visibility_map[item.x][item.y] = true
|
||||
if passable(item.x, item.y) then
|
||||
if seethrough(item.x, item.y) then
|
||||
table.insert(new_queue, {x = item.x + 1, y = item.y, direction = directions.right})
|
||||
end
|
||||
elseif item.direction == directions.upleft then
|
||||
|
@ -322,9 +337,9 @@ function stepVisibilityMapGeneration(queue)
|
|||
-- it is not. We can therefore check whether the movement is valid
|
||||
-- by testing if either the cell to our right or below us (the
|
||||
-- directions opposite to the ones in an up.left movement) is empty
|
||||
if passable(item.x + 1, item.y) or passable(item.x, item.y + 1) then
|
||||
if seethrough(item.x + 1, item.y) or seethrough(item.x, item.y + 1) then
|
||||
visibility_map[item.x][item.y] = true
|
||||
if passable(item.x, item.y) then
|
||||
if seethrough(item.x, item.y) then
|
||||
-- ⌜^
|
||||
-- ⌜ <x
|
||||
table.insert(new_queue, {x = item.x - 1, y = item.y - 1, direction = directions.upleft})
|
||||
|
@ -334,9 +349,9 @@ function stepVisibilityMapGeneration(queue)
|
|||
end
|
||||
elseif item.direction == directions.downleft then
|
||||
-- See under item.direction == directions.upleft
|
||||
if passable(item.x + 1, item.y) or passable(item.x, item.y - 1) then
|
||||
if seethrough(item.x + 1, item.y) or seethrough(item.x, item.y - 1) then
|
||||
visibility_map[item.x][item.y] = true
|
||||
if passable(item.x, item.y) then
|
||||
if seethrough(item.x, item.y) then
|
||||
-- ⌞ <x
|
||||
-- ⌞v
|
||||
table.insert(new_queue, {x = item.x - 1, y = item.y, direction = directions.left})
|
||||
|
@ -346,9 +361,9 @@ function stepVisibilityMapGeneration(queue)
|
|||
end
|
||||
elseif item.direction == directions.downright then
|
||||
-- See under item.direction == directions.upleft
|
||||
if passable(item.x - 1, item.y) or passable(item.x, item.y - 1) then
|
||||
if seethrough(item.x - 1, item.y) or seethrough(item.x, item.y - 1) then
|
||||
visibility_map[item.x][item.y] = true
|
||||
if passable(item.x, item.y) then
|
||||
if seethrough(item.x, item.y) then
|
||||
-- ⌟ x>
|
||||
-- v⌟
|
||||
table.insert(new_queue, {x = item.x + 1, y = item.y, direction = directions.right})
|
||||
|
@ -358,9 +373,9 @@ function stepVisibilityMapGeneration(queue)
|
|||
end
|
||||
elseif item.direction == directions.upright then
|
||||
-- See under item.direction == directions.upleft
|
||||
if passable(item.x - 1, item.y) or passable(item.x, item.y + 1) then
|
||||
if seethrough(item.x - 1, item.y) or seethrough(item.x, item.y + 1) then
|
||||
visibility_map[item.x][item.y] = true
|
||||
if passable(item.x, item.y) then
|
||||
if seethrough(item.x, item.y) then
|
||||
-- ^⌝
|
||||
-- ⌝ x>
|
||||
table.insert(new_queue, {x = item.x, y = item.y - 1, direction = directions.up})
|
||||
|
@ -404,11 +419,20 @@ function passable(x, y)
|
|||
return cavern[x][y] == tiletypes.empty or cavern[x][y] == tiletypes.orb
|
||||
end
|
||||
|
||||
function seethrough(x, y)
|
||||
return cavern[x][y] == tiletypes.empty or cavern[x][y] == tiletypes.orb or cavern[x][y] == tiletypes.slime
|
||||
end
|
||||
|
||||
function collidedPlayerOrb()
|
||||
local body_x, body_y = getBodyLocation()
|
||||
return cavern[player_x][player_y] == tiletypes.orb or cavern[body_x][body_y] == tiletypes.orb
|
||||
end
|
||||
|
||||
function collidedPlayerSlime()
|
||||
local body_x, body_y = getBodyLocation()
|
||||
return cavern[player_x][player_y] == tiletypes.slime or cavern[body_x][body_y] == tiletypes.slime
|
||||
end
|
||||
|
||||
-- ------------------------------------------------------------------
|
||||
-- Player helper functions
|
||||
-- ------------------------------------------------------------------
|
||||
|
@ -567,6 +591,7 @@ function newGame()
|
|||
|
||||
spawnPlayer()
|
||||
spawnOrb()
|
||||
spawnSlimes()
|
||||
|
||||
generateVisibilityMap()
|
||||
initializeRememberedCavern()
|
||||
|
@ -576,6 +601,56 @@ function newGame()
|
|||
end
|
||||
end
|
||||
|
||||
function moveSlimes()
|
||||
for i, slime in ipairs(slimes) do
|
||||
local dx = 0
|
||||
local dy = 0
|
||||
|
||||
local to_player_dx = player_x - slime.x
|
||||
local to_player_dy = player_y - slime.y
|
||||
if math.abs(to_player_dx) + math.abs(to_player_dy) <= 7 then
|
||||
-- If at max 7 moves away from player, book for it
|
||||
if math.abs(to_player_dx) > math.abs(to_player_dy) then
|
||||
-- Needs to move more in the horizontal direction → move horizontally
|
||||
if to_player_dx < 0 then
|
||||
dx = -1
|
||||
else
|
||||
dx = 1
|
||||
end
|
||||
else
|
||||
-- Otherwise move vertically
|
||||
if to_player_dy < 0 then
|
||||
dy = -1
|
||||
else
|
||||
dy = 1
|
||||
end
|
||||
end
|
||||
else
|
||||
local movement = math.random(0, 3)
|
||||
if movement == 0 then
|
||||
-- Up
|
||||
dy = -1
|
||||
elseif movement == 1 then
|
||||
-- Left
|
||||
dx = -1
|
||||
elseif movement == 2 then
|
||||
-- Down
|
||||
dy = 1
|
||||
elseif movement == 3 then
|
||||
-- Right
|
||||
dx = 1
|
||||
end
|
||||
end
|
||||
|
||||
-- We test for empty instead of using passable(), since we are overwriting a tile
|
||||
if cavern[slime.x + dx][slime.y + dy] == tiletypes.empty then
|
||||
cavern[slime.x + dx][slime.y + dy] = tiletypes.slime
|
||||
cavern[slime.x][slime.y] = tiletypes.empty
|
||||
slimes[i] = {x = slime.x + dx, y = slime.y + dy}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function step(direction)
|
||||
if game_mode == gamemodes.normal then
|
||||
if last_direction_moved == direction then
|
||||
|
@ -587,12 +662,19 @@ function step(direction)
|
|||
end
|
||||
|
||||
rememberVisible()
|
||||
|
||||
movePlayer(direction)
|
||||
moveSlimes()
|
||||
|
||||
generateVisibilityMap()
|
||||
|
||||
if collidedPlayerOrb() then
|
||||
game_mode = gamemodes.won
|
||||
end
|
||||
|
||||
if collidedPlayerSlime() then
|
||||
newGame()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -622,6 +704,10 @@ function drawCavern()
|
|||
love.graphics.rectangle('fill', x, y, x_scale, y_scale)
|
||||
love.graphics.setColor(0, 1, 0)
|
||||
love.graphics.ellipse('fill', x + 0.5 * x_scale, y + 0.5 * y_scale, 0.7 * x_scale/2, 0.7 * y_scale/2)
|
||||
elseif tile == tiletypes.slime then
|
||||
love.graphics.setColor(0, 0, 1)
|
||||
love.graphics.ellipse('fill', x + 0.5 * x_scale, y + 0.5 * y_scale, 0.8 * x_scale/2, 0.8 * y_scale/2)
|
||||
love.graphics.rectangle('fill', x + 0.1 * x_scale , y + 0.5 * y_scale, 0.8 * x_scale, 0.8 * y_scale/2)
|
||||
else
|
||||
love.graphics.setColor(1, 0.5, 0.5)
|
||||
love.graphics.rectangle('fill', x, y, x_scale, y_scale)
|
||||
|
@ -640,11 +726,20 @@ function drawCavern()
|
|||
love.graphics.rectangle('fill', x, y, x_scale, y_scale)
|
||||
love.graphics.setColor(0.2, 0.7, 0.2)
|
||||
love.graphics.ellipse('fill', x + 0.5 * x_scale, y + 0.5 * y_scale, 0.7 * x_scale/2, 0.7 * y_scale/2)
|
||||
elseif tile == tiletypes.slime then
|
||||
love.graphics.setColor(0.2, 0.2, 0.7)
|
||||
love.graphics.ellipse('fill', x + 0.5 * x_scale, y + 0.5 * y_scale, 0.8 * x_scale/2, 0.8 * y_scale/2)
|
||||
love.graphics.rectangle('fill', x + 0.1 * x_scale , y + 0.5 * y_scale, 0.8 * x_scale, 0.8 * y_scale/2)
|
||||
else
|
||||
love.graphics.setColor(0.7, 0.5, 0.5)
|
||||
love.graphics.rectangle('fill', x, y, x_scale, y_scale)
|
||||
end
|
||||
end
|
||||
|
||||
if debug and tile_x == player_x and tile_y == player_y then
|
||||
love.graphics.setColor(1, 1, 0)
|
||||
love.graphics.rectangle('fill', x + 0.5 * x_scale, y + 0.5 * y_scale, x_scale/2, y_scale/2)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -781,7 +876,9 @@ end
|
|||
function love.draw()
|
||||
if game_mode == gamemodes.normal then
|
||||
drawCavern()
|
||||
drawPlayer()
|
||||
if not debug then
|
||||
drawPlayer()
|
||||
end
|
||||
elseif game_mode == gamemodes.won then
|
||||
drawWin()
|
||||
elseif game_mode == gamemodes.config then
|
||||
|
|
Loading…
Reference in New Issue