[solved] sti/gamera woes
Posted: Wed Jul 05, 2017 6:52 am
Hey all,
I'm a grade-A novice at game programming, trying to learn good ecs coding practices while slowly getting my feet wet with some love/lua libraries. (And hi hello forum, you've seemed very pleasant from my lurking, and I'm really enjoying working with love.) Right now my goal is to recreate the functionality of the lua.space Tiled article with an ecs structure, using tiny-ecs, sti, and gamera. I'm taking a lot of cues (aka puzzling over/copying from) from the tiny-ecs demo code, making adjustments and simplifying where I can.
My problem is that, while the camera's position is clearly getting set, it isn't getting drawn, so camera position is moving but the map isn't getting translated. I'm sure the issue is something I overlooked, but I have pored over the Commando Kibbles code to see what I'm doing differently and am still scratching my head. I didn't include Player.lua and SpriteSystem.lua for simplicity's sake, but if you think they're relevant, I'll edit them in.
main.lua
src.CameraTrackingSystem.lua
src.TileMapRenderSystem.lua
src.PlayerControlSystem.lua
Edit: So the first problem was that map:draw wasn't using the l,t values from the camera, which I've now added. Now what I'm encountering is that the character starts moving 2x faster than the camera once it leaves the top-left quadrant of the screen. I'm guessing there's knowledge that I'm missing, but my best guess is that somehow the camera's new position is altering what (0,0) means for the character's position. Is there a common solution for this problem? Do I need to be rendering the character sprite inside an STI layer to maintain the map's coordinates under the changing camera?
I attached the code in case it's easier for answering questions.
I'm a grade-A novice at game programming, trying to learn good ecs coding practices while slowly getting my feet wet with some love/lua libraries. (And hi hello forum, you've seemed very pleasant from my lurking, and I'm really enjoying working with love.) Right now my goal is to recreate the functionality of the lua.space Tiled article with an ecs structure, using tiny-ecs, sti, and gamera. I'm taking a lot of cues (aka puzzling over/copying from) from the tiny-ecs demo code, making adjustments and simplifying where I can.
My problem is that, while the camera's position is clearly getting set, it isn't getting drawn, so camera position is moving but the map isn't getting translated. I'm sure the issue is something I overlooked, but I have pored over the Commando Kibbles code to see what I'm doing differently and am still scratching my head. I didn't include Player.lua and SpriteSystem.lua for simplicity's sake, but if you think they're relevant, I'll edit them in.
main.lua
Code: Select all
class = require("lib/middleclass")
tiny = require("lib/tiny")
local gamera = require("lib/gamera")
local sti = require("lib/sti")
local camera = nil
local tileMap = nil
local world = nil
function love.load()
tileMap = sti("assets/badshore.lua")
camera = gamera.new(0,0,tileMap.width*tileMap.tilewidth, tileMap.height*tileMap.tileheight)
world = tiny.world(
require("src.PlayerControlSystem")(tileMap),
require("src.CameraTrackingSystem")(camera),
require("src.TileMapRenderSystem")(tileMap, camera),
require("src.SpriteSystem")(),
require("src.Player")({x=200, y=200})
)
end
function love.update(dt)
end
function love.draw()
local dt = love.timer.getDelta()
if world then
world:update(dt)
end
end
Code: Select all
local CameraTrackingSystem = tiny.processingSystem(class "CameraTrackingSystem")
CameraTrackingSystem.filter = tiny.requireAll("position")
function CameraTrackingSystem:initialize(camera)
self.camera = camera
end
function CameraTrackingSystem:process(e, dt)
local tx, ty = math.floor(e.position.x), math.floor(e.position.y)
local camx, camy = self.camera:getPosition()
local lerp = 0.1
print("offset: "..tx..", "..ty.."; cam: "..camx..", "..camy)
self.camera:setPosition(round(camx + (tx - camx) * lerp), round(camy + (ty - camy) * lerp))
end
return CameraTrackingSystem
Code: Select all
local TileMapRenderSystem = tiny.system(class "TileMapRenderSystem")
function TileMapRenderSystem:initialize(map, camera)
self.camera = camera
self.map = map
function self.drawFn(l, t, w, h)
map:update(dt)
map:draw(-l, -t)
end
end
function TileMapRenderSystem:update(dt)
self.camera:draw(self.drawFn)
end
return TileMapRenderSystem
Code: Select all
local PlayerControlSystem = tiny.processingSystem(class "PlayerControlSystem")
PlayerControlSystem.filter = tiny.requireAll("controllable", "position", "speed")
function PlayerControlSystem:initialize(tileMap)
local layer = tileMap.layers["Sprites"]
self.atStart = true
self.start = {x=0, y=0}
for k, object in pairs(tileMap.objects) do
if object.name == "Player" then
self.start.x = object.x
self.start.y = object.y
print("location: "..object.x..", "..object.y)
break
end
end
end
function PlayerControlSystem:process(player, dt)
if self.atStart then
player.position = self.start
end
local dx, dy = 0, 0
if love.keyboard.isDown("w", "a", "s", "d", "up", "down", "left", "right") then
self.atStart = false
end
if love.keyboard.isDown("w", "up") then
dy = dy - player.speed * dt
end
if love.keyboard.isDown("s", "down") then
dy = dy + player.speed * dt
end
if love.keyboard.isDown("a", "left") then
dx = dx - player.speed * dt
end
if love.keyboard.isDown("d", "right") then
dx = dx + player.speed * dt
end
if dx ~= 0 and dy ~= 0 then
dx = dx * 0.707106781
dy = dy * 0.707106781
end
player.position.x = player.position.x + dx
player.position.y = player.position.y + dy
end
return PlayerControlSystem
I attached the code in case it's easier for answering questions.