summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--enemy.lua76
-rw-r--r--entity.lua2
-rw-r--r--main.lua6
-rw-r--r--player.lua6
-rw-r--r--tilemap.lua26
-rw-r--r--world.lua29
6 files changed, 134 insertions, 11 deletions
diff --git a/enemy.lua b/enemy.lua
new file mode 100644
index 0000000..9732e98
--- /dev/null
+++ b/enemy.lua
@@ -0,0 +1,76 @@
+local Enemy = {}
+local Entity = require("entity")
+Enemy.__index = Enemy
+setmetatable(Enemy, { __index = Entity })
+
+function Enemy.new(spawnX, spawnY, width, height, physicsWidth, physicsHeight)
+ local self = setmetatable(Entity:new(spawnX or 0, spawnY or 0, width or 16, height or 16, physicsWidth or width or 8, physicsHeight or height or 8), Enemy)
+ self.direction = math.random(1, 2) == 1 and 1 or -1
+ self.speed = 20
+ self.turnDelay = 0.35
+ self.turning = false
+ self.turnTimer = 0
+ return self
+end
+
+function Enemy:setWorldContext(world)
+ self.world = world
+ self:enablePhysics(world.physicsWorld, "dynamic")
+end
+
+function Enemy:noPathAhead()
+ if not self.world then return false end
+
+ local frontX
+ if self.direction == 1 then
+ frontX = self.x + self.physicsWidth * 1.5 + 1
+ else
+ frontX = self.x + self.physicsWidth * 0.5 - 1
+ end
+
+ local midY = self.y + self.physicsHeight * 0.5
+ local belowY = self.y + self.physicsHeight + 1
+
+ local wallAhead = self.world:isTileSolidAtPixel(frontX, midY)
+ local floorAhead = self.world:isTileSolidAtPixel(frontX, belowY)
+
+ return wallAhead or not floorAhead
+end
+
+function Enemy:patrolPlatform(dt)
+ self:syncFromPhysicsBody()
+
+ if self.turning then
+ self.turnTimer = self.turnTimer - dt
+ if self.turnTimer <= 0 then
+ self.direction = self.direction * -1
+ self.turning = false
+ end
+ if self.body then
+ local _, vy = self.body:getLinearVelocity()
+ self.body:setLinearVelocity(0, vy)
+ end
+ return
+ end
+
+ if self:noPathAhead() then
+ self.turning = true
+ self.turnTimer = self.turnDelay
+ end
+
+ if self.body then
+ local _, vy = self.body:getLinearVelocity()
+ self.body:setLinearVelocity(self.speed * self.direction, vy)
+ end
+end
+
+function Enemy:update(dt)
+ self:patrolPlatform(dt)
+end
+
+function Enemy:draw()
+ --bug: texture is drawn shifted by half width to the left
+ love.graphics.draw(self.texture, self.x + self.physicsWidth / 2, self.y)
+end
+
+return Enemy \ No newline at end of file
diff --git a/entity.lua b/entity.lua
index b0c146a..c85dc71 100644
--- a/entity.lua
+++ b/entity.lua
@@ -9,7 +9,7 @@ function Entity:new(x, y, width, height, physicsWidth, physicsHeight)
self.height = height
self.physicsWidth = physicsWidth or width
self.physicsHeight = physicsHeight or height
- self.texture = love.graphics.newImage("assets/missing.png")
+ self.texture = love.graphics.newImage("assets/missing8x8.png")
return self
end
diff --git a/main.lua b/main.lua
index d014b96..066ff00 100644
--- a/main.lua
+++ b/main.lua
@@ -1,7 +1,7 @@
-local VIRTUAL_WIDTH, VIRTUAL_HEIGHT = 16*10*3, 9*10*3
+local VIRTUAL_WIDTH, VIRTUAL_HEIGHT = 16*10*5, 9*10*5
local CANVAS_PADDING = 6
-DEBUG = false
+DEBUG = true
local CANVAS_WIDTH = VIRTUAL_WIDTH + CANVAS_PADDING
local CANVAS_HEIGHT = VIRTUAL_HEIGHT + CANVAS_PADDING
@@ -23,7 +23,7 @@ local currentState = "game"
local currentMapPath = "assets/maps/tilemap.lua"
local currentTilesets = {
tileset = { path = "assets/maps/tileset.png", tilewidth = 16, tileheight = 16 },
- ground = { path = "assets/maps/ground.png", tilewidth = 8, tileheight = 8 },
+ misc = { path = "assets/maps/simples_pimples.png", tilewidth = 16, tileheight = 16 },
}
local world = nil
diff --git a/player.lua b/player.lua
index 81e56bc..de02625 100644
--- a/player.lua
+++ b/player.lua
@@ -6,13 +6,13 @@ Player.__index = Player
setmetatable(Player, { __index = Entity })
local MOVE_SPEED = 65
-local SWIM_SPEED = 15
+local SWIM_SPEED = 100
local JUMP_FORCE = -200
local GROUND_LAYER = "ground"
function Player.new(world, spawnX, spawnY)
local w, h = 16, 16
- local pw, ph = 8, 8 -- physics body size
+ local pw, ph = 16, 16 -- physics body size
local self = setmetatable(Entity:new(spawnX or 0, spawnY or 0, w, h, pw, ph), Player)
self.directionState = { 'side', 'up', 'down', 'side_up', 'side_down' }
@@ -209,7 +209,7 @@ function Player:jump()
return false
end
- local maxJumps = self.doubleJump and 2 or 1
+ local maxJumps = self.doubleJump and 1 or 0
if self.jumpsUsed >= maxJumps then
return false
diff --git a/tilemap.lua b/tilemap.lua
index 8ad1c9c..09ce8d6 100644
--- a/tilemap.lua
+++ b/tilemap.lua
@@ -53,10 +53,13 @@ function Tilemap:new(mapPath, tilesets)
self.entitiesLiquidPolygons = {}
self.entitiesLiquidSurfaces = {}
self.layerBackground = nil
+ self.layerDecorationBackground = nil
+ self.layerDecorationForeground = nil
+ self.layerFarground = nil
self.layerGround = nil
self.layerForeground = nil
- self.tileWidth = 8
- self.tileHeight = 8
+ self.tileWidth = 16
+ self.tileHeight = 16
self.mapWidth = 0
self.mapHeight = 0
self.tileGidInfo = {}
@@ -65,8 +68,8 @@ function Tilemap:new(mapPath, tilesets)
local mapData = loadMapData(mapPath)
self.mapData = mapData
- self.tileWidth = mapData and (mapData.tilewidth or 8) or 8
- self.tileHeight = mapData and (mapData.tileheight or 8) or 8
+ self.tileWidth = mapData and (mapData.tilewidth or 16) or 16
+ self.tileHeight = mapData and (mapData.tileheight or 16) or 16
self.mapWidth = (mapData and mapData.width or 0) * self.tileWidth
self.mapHeight = (mapData and mapData.height or 0) * self.tileHeight
@@ -98,6 +101,9 @@ function Tilemap:new(mapPath, tilesets)
if layer.type == "tilelayer" and layer.name then
local n = layer.name:lower()
if n == "background" then self.layerBackground = layer
+ elseif n == "farground" then self.layerFarground = layer
+ elseif n == "decoration_background" then self.layerDecorationBackground = layer
+ elseif n == "decoration_foreground" then self.layerDecorationForeground = layer
elseif n == "ground" then self.layerGround = layer
elseif n == "foreground" then self.layerForeground = layer
end
@@ -183,6 +189,18 @@ function Tilemap:getBackgroundLayer()
return self.layerBackground
end
+function Tilemap:getFargroundLayer()
+ return self.layerFarground
+end
+
+function Tilemap:getDecorationBackgroundLayer()
+ return self.layerDecorationBackground
+end
+
+function Tilemap:getDecorationForegroundLayer()
+ return self.layerDecorationForeground
+end
+
function Tilemap:getGroundLayer()
return self.layerGround
end
diff --git a/world.lua b/world.lua
index 2542fa1..8f1722f 100644
--- a/world.lua
+++ b/world.lua
@@ -3,6 +3,7 @@ local Entity = require("entity")
local Player = require("player")
local Camera = require("camera")
local Textbox = require("textbox")
+local Enemy = require("enemy")
local World = {}
World.__index = World
@@ -118,6 +119,11 @@ function World:load(mapPath, tilesets)
self.player = Player.new(self.physicsWorld, spawn.x, spawn.y)
self.player.isPlayer = true
table.insert(self.entities, self.player)
+ elseif entityType == "Enemy" then
+ local e = Enemy.new(spawn.x, spawn.y, spawn.width, spawn.height)
+ e:setWorldContext(self)
+ e:setPropertiesFromOptions({ properties = spawn.properties or {}, name = spawn.name, type = spawn.type })
+ table.insert(self.entities, e)
else
local e = Entity:new(spawn.x, spawn.y, spawn.width, spawn.height)
e:setPropertiesFromOptions({ properties = spawn.properties or {}, name = spawn.name, type = spawn.type })
@@ -271,6 +277,22 @@ function World:getMapData()
return self.mapData
end
+function World:isTileSolidAtPixel(x, y)
+ local groundLayer = self.tilemap:getGroundLayer()
+ if not groundLayer or not groundLayer.data then return false end
+ local dims = self.tilemap:getLayerTileDimensions("ground")
+ local tw = dims.tilewidth or self.tilemap:getTileWidth()
+ local th = dims.tileheight or self.tilemap:getTileHeight()
+ local mapW = self.mapData.width or 0
+ local mapH = self.mapData.height or 0
+ local col = math.floor(x / tw)
+ local row = math.floor(y / th)
+ if col < 0 or col >= mapW or row < 0 or row >= mapH then return false end
+ local idx = row * mapW + col + 1
+ local gid = groundLayer.data[idx]
+ return gid and gid ~= 0
+end
+
local function drawTileLayer(layer, mapTileW, mapTileH, tileGidInfo, viewMinX, viewMinY, viewMaxX, viewMaxY)
if not layer or not layer.visible or not layer.data then return end
local w = layer.width or 0
@@ -360,12 +382,15 @@ function World:draw()
love.graphics.push()
love.graphics.setCanvas(self.refractionCanvas)
love.graphics.clear(0, 0, 0, 1)
+ drawTileLayer(self.tilemap:getFargroundLayer(), mapTileW, mapTileH, tileGidInfo, viewMinX, viewMinY, viewMaxX, viewMaxY)
+ drawTileLayer(self.tilemap:getDecorationBackgroundLayer(), mapTileW, mapTileH, tileGidInfo, viewMinX, viewMinY, viewMaxX, viewMaxY)
drawTileLayer(self.tilemap:getBackgroundLayer(), mapTileW, mapTileH, tileGidInfo, viewMinX, viewMinY, viewMaxX, viewMaxY)
drawTileLayer(self.tilemap:getGroundLayer(), mapTileW, mapTileH, tileGidInfo, viewMinX, viewMinY, viewMaxX, viewMaxY)
for _, e in ipairs(self.entities) do
if e.draw then e:draw() else World.drawEntityDefault(self, e) end
end
drawTileLayer(self.tilemap:getForegroundLayer(), mapTileW, mapTileH, tileGidInfo, viewMinX, viewMinY, viewMaxX, viewMaxY)
+ drawTileLayer(self.tilemap:getDecorationForegroundLayer(), mapTileW, mapTileH, tileGidInfo, viewMinX, viewMinY, viewMaxX, viewMaxY)
love.graphics.setCanvas(mainCanvas)
love.graphics.pop()
@@ -411,7 +436,10 @@ function World:draw()
love.graphics.setShader()
else
drawTileLayer(self.tilemap:getBackgroundLayer(), mapTileW, mapTileH, tileGidInfo, viewMinX, viewMinY, viewMaxX, viewMaxY)
+ drawTileLayer(self.tilemap:getDecorationBackgroundLayer(), mapTileW, mapTileH, tileGidInfo, viewMinX, viewMinY, viewMaxX, viewMaxY)
drawTileLayer(self.tilemap:getGroundLayer(), mapTileW, mapTileH, tileGidInfo, viewMinX, viewMinY, viewMaxX, viewMaxY)
+ drawTileLayer(self.tilemap:getFargroundLayer(), mapTileW, mapTileH, tileGidInfo, viewMinX, viewMinY, viewMaxX, viewMaxY)
+ drawTileLayer(self.tilemap:getDecorationBackgroundLayer(), mapTileW, mapTileH, tileGidInfo, viewMinX, viewMinY, viewMaxX, viewMaxY)
love.graphics.setColor(0.25, 0.5, 0.9, 0.6)
for _, liquid in ipairs(self.liquidPolygons) do
@@ -440,6 +468,7 @@ function World:draw()
if e.draw then e:draw() else World.drawEntityDefault(self, e) end
end
drawTileLayer(self.tilemap:getForegroundLayer(), mapTileW, mapTileH, tileGidInfo, viewMinX, viewMinY, viewMaxX, viewMaxY)
+ drawTileLayer(self.tilemap:getDecorationForegroundLayer(), mapTileW, mapTileH, tileGidInfo, viewMinX, viewMinY, viewMaxX, viewMaxY)
end
if DEBUG then