277 lines
8.2 KiB
Lua
277 lines
8.2 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,
|
|
playFieldTiles={},
|
|
map=sti("map.lua"),
|
|
entities={
|
|
vehicles={},
|
|
floatdevs={},
|
|
},
|
|
default_speeds={
|
|
floatdev=8,
|
|
vehicle=10,
|
|
},
|
|
hazards={},
|
|
drawGrid=false,
|
|
}
|
|
|
|
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=t2p(0), y=t2p(1)},
|
|
turtleHit=false,
|
|
lives=3,
|
|
turtles=3,
|
|
dead=false,
|
|
deadTimer=2,
|
|
float_speed=0,
|
|
}
|
|
|
|
function resetPlayer()
|
|
player.pos = {x=t2p(0), y=t2p(0)}
|
|
player.dead = false
|
|
player.turtleHit = false
|
|
player.turtlePos = {x=t2p(0), y=t2p(1)}
|
|
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
|
|
layer.visible = false
|
|
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
|
|
local entity = {
|
|
x=mapObj.x,
|
|
y=mapObj.y,
|
|
w=mapObj.width,
|
|
h=mapObj.height,
|
|
type=mapObj.type,
|
|
gid=mapObj.gid,
|
|
}
|
|
if mapObj.type == "vehicle" or mapObj.type == "floatdev" then
|
|
local tile = game.map.tiles[mapObj.gid] or game.map.tiles[game.map:setFlippedGID(mapObj.gid)]
|
|
entity.collider = tile.objectGroup.objects[1]
|
|
entity.speed = mapObj.properties.speed or game.default_speeds[mapObj.type]
|
|
end
|
|
table.insert(game.entities[typekey], entity)
|
|
end
|
|
end
|
|
end
|
|
player.sprites = love.graphics.newImage("player-sprites.png")
|
|
player.quads = {
|
|
dude=love.graphics.newQuad(17, 9, 15, 23, player.sprites),
|
|
turtle=love.graphics.newQuad(0, 23, 17, 9, player.sprites),
|
|
}
|
|
end
|
|
|
|
|
|
function love.keyreleased(key)
|
|
if player.dead or player.turtleHit 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.x = t2p(oldPos.x - 1)
|
|
player.turtlePos.y = t2p(oldPos.y - 1)
|
|
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)
|
|
if player.dead or player.turtleHit 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(screenPixelToTilePos(player.turtlePos))
|
|
if player.float_speed ~= 0 then
|
|
player.pos.y = player.pos.y + player.float_speed*dt
|
|
player.turtlePos.y = player.turtlePos.y + player.float_speed*dt
|
|
end
|
|
for i, vehicle in ipairs(game.entities.vehicles) do
|
|
local colliderRect = {x=vehicle.x + vehicle.collider.x, y=vehicle.y + vehicle.collider.y, w=vehicle.collider.width, h=vehicle.collider.height}
|
|
if rectanglesIntersect(playerRect, colliderRect) then
|
|
player.dead = true
|
|
player.lives = player.lives - 1
|
|
end
|
|
if rectanglesIntersect(turtleRect, colliderRect) then
|
|
player.turtleHit = true
|
|
end
|
|
|
|
vehicle.y = vehicle.y + vehicle.speed*dt
|
|
if vehicle.y > t2p(game.PLAYFIELD_HEIGHT) then
|
|
vehicle.y = -vehicle.h
|
|
end
|
|
if vehicle.y + vehicle.h < t2p(0) then
|
|
vehicle.y = t2p(game.PLAYFIELD_HEIGHT)
|
|
end
|
|
end
|
|
local was_floating = player.float_speed ~= 0
|
|
player.float_speed = 0
|
|
for i, floatdev in ipairs(game.entities.floatdevs) do
|
|
local colliderRect = {x=floatdev.x + floatdev.collider.x, y=floatdev.y + floatdev.collider.y, w=floatdev.collider.width, h=floatdev.collider.height}
|
|
if player.float_speed == 0 and rectanglesIntersect(playerRect, colliderRect) then
|
|
if not was_floating then
|
|
if math.abs(player.pos.y - colliderRect.y) > math.abs(player.pos.y - (colliderRect.y + colliderRect.h)) then
|
|
player.pos.y = colliderRect.y
|
|
player.turtlePos.y = player.pos.y + game.TILE_SIZE*2
|
|
else
|
|
player.pos.y = colliderRect.y + colliderRect.h - game.TILE_SIZE
|
|
player.turtlePos.y = player.pos.y - game.TILE_SIZE
|
|
end
|
|
end
|
|
player.turtlePos.x = player.pos.x
|
|
player.float_speed = floatdev.speed
|
|
end
|
|
floatdev.y = floatdev.y + floatdev.speed*dt
|
|
if floatdev.y > t2p(game.PLAYFIELD_HEIGHT) then
|
|
floatdev.y = -floatdev.h
|
|
end
|
|
if floatdev.y + floatdev.h < t2p(0) then
|
|
floatdev.y = t2p(game.PLAYFIELD_HEIGHT)
|
|
end
|
|
end
|
|
if player.float_speed == 0 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
|
|
if not player.dead and was_floating then
|
|
player.turtlePos.x = player.pos.x
|
|
player.turtlePos.y = player.pos.y - game.TILE_SIZE
|
|
if player.turtlePos.y < t2p(0) then
|
|
player.turtlePos.y = player.pos.y + game.TILE_SIZE
|
|
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
|
|
for i, vehicle in ipairs(game.entities.vehicles) do
|
|
local tile = game.map.tiles[vehicle.gid] or game.map:setFlippedGID(vehicle.gid)
|
|
local tileset = game.map.tilesets[tile.tileset]
|
|
local image = tileset.image
|
|
love.graphics.setColor(1, 1, 1)
|
|
love.graphics.draw(image, tile.quad, vehicle.x, vehicle.y)
|
|
love.graphics.setColor(0.9, 0.1, 0)
|
|
-- love.graphics.rectangle("line", vehicle.x + vehicle.collider.x, vehicle.y + vehicle.collider.y, vehicle.collider.width, vehicle.collider.height)
|
|
end
|
|
for i, floatdev in ipairs(game.entities.floatdevs) do
|
|
local tile = game.map.tiles[floatdev.gid] or game.map:setFlippedGID(floatdev.gid)
|
|
local tileset = game.map.tilesets[tile.tileset]
|
|
local image = tileset.image
|
|
love.graphics.setColor(1, 1, 1)
|
|
love.graphics.draw(image, tile.quad, floatdev.x, floatdev.y)
|
|
love.graphics.setColor(0.9, 0.1, 0)
|
|
end
|
|
if player.dead then
|
|
love.graphics.setColor(0.8, 0.1, 0)
|
|
else
|
|
love.graphics.setColor(1, 1, 1)
|
|
end
|
|
local x, y = player.pos.x, player.pos.y
|
|
love.graphics.draw(player.sprites, player.quads.dude, x, y - 8)
|
|
x, y = player.turtlePos.x, player.turtlePos.y
|
|
if player.turtleHit then
|
|
love.graphics.setColor(0.8, 0.1, 0)
|
|
else
|
|
love.graphics.setColor(1, 1, 1)
|
|
end
|
|
love.graphics.draw(player.sprites, player.quads.turtle, x, y + 4)
|
|
-- </playfield>
|
|
love.graphics.pop()
|
|
end
|