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=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 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) 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 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() -- 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) 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) -- love.graphics.pop() end