231 lines
6.0 KiB
Lua
231 lines
6.0 KiB
Lua
|
local sti = require("sti")
|
||
|
local inspect = require("inspect")
|
||
|
|
||
|
love.graphics.setDefaultFilter("nearest", "nearest")
|
||
|
|
||
|
local game = {
|
||
|
SCREEN_WIDTH=320,
|
||
|
SCREEN_HEIGHT=200,
|
||
|
TILE_SIZE=16,
|
||
|
-- NOTE: playfield dimensions in tiles
|
||
|
PLAYFIELD_OFFSET_TOP=1.5,
|
||
|
PLAYFIELD_WIDTH=20,
|
||
|
PLAYFIELD_HEIGHT=10,
|
||
|
VEHICLE_SPEED=10,
|
||
|
FLOATDEV_SPEED=8,
|
||
|
playFieldTiles={},
|
||
|
map=sti("map.lua"),
|
||
|
entities={
|
||
|
vehicles={},
|
||
|
floatdevs={},
|
||
|
},
|
||
|
hazards={},
|
||
|
drawGrid=true,
|
||
|
}
|
||
|
|
||
|
function t2p(tileDim)
|
||
|
return tileDim*game.TILE_SIZE
|
||
|
end
|
||
|
|
||
|
function tilePos2Pixels(tilePos)
|
||
|
return t2p(tilePos.x - 1), t2p(tilePos.y - 1)
|
||
|
end
|
||
|
|
||
|
function screenPixelToTilePos(pixelPos)
|
||
|
return {
|
||
|
x=math.floor(pixelPos.x/game.TILE_SIZE + 1),
|
||
|
y=math.floor((pixelPos.y + t2p(game.PLAYFIELD_OFFSET_TOP))/game.TILE_SIZE)
|
||
|
}
|
||
|
end
|
||
|
|
||
|
|
||
|
local player = {
|
||
|
pos={x=t2p(0), y=t2p(0)},
|
||
|
turtlePos={x=1, y=2},
|
||
|
turtleHit=false,
|
||
|
lives=3,
|
||
|
turtles=3,
|
||
|
dead=false,
|
||
|
deadTimer=2,
|
||
|
}
|
||
|
|
||
|
function resetPlayer()
|
||
|
player.pos = {x=t2p(0), y=t2p(0)}
|
||
|
player.dead = false
|
||
|
end
|
||
|
|
||
|
function love.load()
|
||
|
local desktop_width, desktop_height = love.window.getDesktopDimensions()
|
||
|
game.scaleW = desktop_width / game.SCREEN_WIDTH
|
||
|
game.scaleH = desktop_height / game.SCREEN_HEIGHT
|
||
|
for i, layer in ipairs(game.map.layers) do
|
||
|
if layer.objects then
|
||
|
for j, mapObj in ipairs(layer.objects) do
|
||
|
mapObj.visible = false
|
||
|
local typekey = mapObj.type.."s"
|
||
|
if game.entities[typekey] == nil then
|
||
|
game.entities[typekey] = {}
|
||
|
end
|
||
|
table.insert(
|
||
|
game.entities[typekey],
|
||
|
{
|
||
|
x=mapObj.x,
|
||
|
y=mapObj.y,
|
||
|
w=mapObj.width,
|
||
|
h=mapObj.height,
|
||
|
type=mapObj.type,
|
||
|
}
|
||
|
)
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
|
||
|
function love.keyreleased(key)
|
||
|
if player.dead then
|
||
|
return
|
||
|
end
|
||
|
local newPos = screenPixelToTilePos(player.pos)
|
||
|
local oldPos = screenPixelToTilePos(player.pos)
|
||
|
if key == "up" or key == "w" then
|
||
|
newPos.y = newPos.y - 1
|
||
|
end
|
||
|
if key == "down" or key == "s" then
|
||
|
newPos.y = newPos.y + 1
|
||
|
end
|
||
|
if key == "right" or key == "d" then
|
||
|
newPos.x = newPos.x + 1
|
||
|
end
|
||
|
if key == "left" or key == "a" then
|
||
|
newPos.x = newPos.x - 1
|
||
|
end
|
||
|
player.turtlePos = oldPos
|
||
|
if newPos.x < 1 then
|
||
|
newPos.x = 1
|
||
|
end
|
||
|
if newPos.x > game.PLAYFIELD_WIDTH then
|
||
|
newPos.x = game.PLAYFIELD_WIDTH
|
||
|
end
|
||
|
if newPos.y < 1 then
|
||
|
newPos.y = 1
|
||
|
end
|
||
|
if newPos.y > game.PLAYFIELD_HEIGHT then
|
||
|
newPos.y = game.PLAYFIELD_HEIGHT
|
||
|
end
|
||
|
player.pos.x = t2p(newPos.x - 1)
|
||
|
player.pos.y = t2p(newPos.y - 1)
|
||
|
end
|
||
|
|
||
|
function tilePos2Rect(tilePos)
|
||
|
return {
|
||
|
x=t2p(tilePos.x - 1),
|
||
|
y=t2p(tilePos.y - 1),
|
||
|
w=game.TILE_SIZE,
|
||
|
h=game.TILE_SIZE,
|
||
|
}
|
||
|
end
|
||
|
|
||
|
function rectanglesIntersect(rect1, rect2)
|
||
|
return (rect1.x < rect2.x + rect2.w and
|
||
|
rect1.x + rect1.w > rect2.x and
|
||
|
rect1.y < rect2.y + rect2.h and
|
||
|
rect1.y + rect1.h > rect2.y)
|
||
|
end
|
||
|
|
||
|
function love.update(dt)
|
||
|
player.turtleHit = false
|
||
|
if player.dead then
|
||
|
player.deadTimer = player.deadTimer - dt
|
||
|
if player.deadTimer <= 0 then
|
||
|
player.deadTimer = 2
|
||
|
resetPlayer()
|
||
|
end
|
||
|
else
|
||
|
local playerRect = tilePos2Rect(screenPixelToTilePos(player.pos))
|
||
|
local turtleRect = tilePos2Rect(player.turtlePos)
|
||
|
if player.floating then
|
||
|
player.pos.y = player.pos.y + game.FLOATDEV_SPEED*dt
|
||
|
end
|
||
|
for i, vehicle in ipairs(game.entities.vehicles) do
|
||
|
if rectanglesIntersect(playerRect, vehicle) then
|
||
|
player.dead = true
|
||
|
player.lives = player.lives - 1
|
||
|
end
|
||
|
if rectanglesIntersect(turtleRect, vehicle) then
|
||
|
player.turtleHit = true
|
||
|
end
|
||
|
|
||
|
vehicle.y = vehicle.y + game.VEHICLE_SPEED*dt
|
||
|
if vehicle.y > t2p(game.PLAYFIELD_HEIGHT) then
|
||
|
vehicle.y = -vehicle.h
|
||
|
end
|
||
|
end
|
||
|
player.floating = false
|
||
|
for i, floatdev in ipairs(game.entities.floatdevs) do
|
||
|
if not player.floating and rectanglesIntersect(playerRect, floatdev) then
|
||
|
player.floating = true
|
||
|
end
|
||
|
floatdev.y = floatdev.y + game.FLOATDEV_SPEED*dt
|
||
|
if floatdev.y > t2p(game.PLAYFIELD_HEIGHT) then
|
||
|
floatdev.y = -floatdev.h
|
||
|
end
|
||
|
end
|
||
|
if not player.floating then
|
||
|
for i, water in ipairs(game.entities.waters) do
|
||
|
if not player.dead and rectanglesIntersect(playerRect, water) then
|
||
|
player.dead = true
|
||
|
player.lives = player.lives - 1
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
function love.draw()
|
||
|
love.graphics.setColor(1, 1, 1)
|
||
|
game.map:draw(0, t2p(game.PLAYFIELD_OFFSET_TOP), game.scaleW, game.scaleH)
|
||
|
love.graphics.push()
|
||
|
-- <playfield>
|
||
|
love.graphics.scale(game.scaleW, game.scaleH)
|
||
|
love.graphics.translate(0, t2p(game.PLAYFIELD_OFFSET_TOP))
|
||
|
if game.drawGrid then
|
||
|
love.graphics.setColor(0.4, 0.3, 0.1)
|
||
|
for i=0, game.PLAYFIELD_WIDTH do
|
||
|
love.graphics.line(t2p(i), 0, t2p(i), t2p(game.PLAYFIELD_HEIGHT))
|
||
|
end
|
||
|
for i=0, game.PLAYFIELD_HEIGHT do
|
||
|
love.graphics.line(0, t2p(i), t2p(game.PLAYFIELD_WIDTH), t2p(i))
|
||
|
end
|
||
|
end
|
||
|
love.graphics.setColor(0.9, 0.2, 0)
|
||
|
for i, vehicle in ipairs(game.entities.vehicles) do
|
||
|
love.graphics.rectangle("fill", vehicle.x, vehicle.y, vehicle.w, vehicle.h)
|
||
|
end
|
||
|
love.graphics.setColor(0.8, 0.7, 0)
|
||
|
for i, floatdev in ipairs(game.entities.floatdevs) do
|
||
|
love.graphics.rectangle("fill", floatdev.x, floatdev.y, floatdev.w, floatdev.h)
|
||
|
end
|
||
|
if player.dead then
|
||
|
love.graphics.setColor(0.8, 0.1, 0)
|
||
|
else
|
||
|
love.graphics.setColor(0.9, 0.6, 0.1)
|
||
|
end
|
||
|
-- TODO: change this to use player's stored pixel pos
|
||
|
local x, y = player.pos.x, player.pos.y
|
||
|
love.graphics.circle("fill", x + game.TILE_SIZE/2, y + game.TILE_SIZE/2, game.TILE_SIZE/2)
|
||
|
love.graphics.setColor(0.2, 0.1, 0.1)
|
||
|
love.graphics.circle("line", x + game.TILE_SIZE/2, y + game.TILE_SIZE/2, game.TILE_SIZE/2)
|
||
|
x, y = tilePos2Pixels(player.turtlePos)
|
||
|
love.graphics.setColor(0.2, 0.1, 0.1)
|
||
|
love.graphics.circle("line", x + game.TILE_SIZE/2, y + game.TILE_SIZE/2, game.TILE_SIZE/2)
|
||
|
if player.turtleHit then
|
||
|
love.graphics.setColor(0.8, 0.1, 0)
|
||
|
else
|
||
|
love.graphics.setColor(0, 0.7, 0.2)
|
||
|
end
|
||
|
love.graphics.circle("fill", x + game.TILE_SIZE/2, y + game.TILE_SIZE/2, game.TILE_SIZE/2)
|
||
|
-- </playfield>
|
||
|
love.graphics.pop()
|
||
|
end
|