tortugger/main.lua

256 lines
7.1 KiB
Lua
Raw Normal View History

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)},
2023-08-23 11:13:07 +00:00
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
2023-08-23 11:13:38 +00:00
player.turtleHit = false
2023-08-23 11:13:07 +00:00
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
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,
}
if entity.type == "floatdev" then
entity.speed = mapObj.properties.speed or game.FLOATDEV_SPEED
end
table.insert(game.entities[typekey], entity)
end
end
end
end
function love.keyreleased(key)
2023-08-23 11:13:38 +00:00
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
2023-08-23 11:13:07 +00:00
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)
2023-08-23 11:13:38 +00:00
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))
2023-08-23 11:13:07 +00:00
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
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
local was_floating = player.float_speed ~= 0
player.float_speed = 0
for i, floatdev in ipairs(game.entities.floatdevs) do
if player.float_speed == 0 and rectanglesIntersect(playerRect, floatdev) then
if not was_floating then
if math.abs(player.pos.y - floatdev.y) > math.abs(player.pos.y - (floatdev.y + floatdev.h)) then
player.pos.y = floatdev.y
player.turtlePos.y = player.pos.y + game.TILE_SIZE*2
else
player.pos.y = floatdev.y + floatdev.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
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
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)
2023-08-23 11:13:07 +00:00
x, y = player.turtlePos.x, player.turtlePos.y
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