tortugger/main.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