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