Page 82 of 92
Re: Simple Tiled Implementation - STI v1.2.3.0
Posted: Fri Feb 21, 2020 3:45 pm
by ikarius
ikarius wrote: ↑Fri Feb 21, 2020 2:39 pm
Thanks for your quick reply.
I succeeded adding static components by creating custom layers and adding manually all needed physics, so I think I am on the good path.
But I'm creating a lot of custom layers (one per static object). Is it OK to create a layer for every object in the game ?
Plus, I don't know how to change the tile in a given layer: I can replace any tile with an ID=0 and it removes it correctly.
But adding another tile ID is a no go (crash).
I tried with one single layer and multiple objects / sprites attached and it works well!
Re: Simple Tiled Implementation - STI v1.2.3.0
Posted: Fri Feb 21, 2020 8:40 pm
by Karai17
Yeah, custom layers are just layers that you dump your own data into. You can use one layer for tonnes of objects, it just allows you to order the draws so that your objects draw over and under other layers correctly.
As for the crash, I am uncertain about that. Can you share a .love example I can tinker with?
Re: Simple Tiled Implementation - STI v1.2.3.0
Posted: Thu Apr 23, 2020 9:30 pm
by JuanjoSalvador
Question about STI, sorry if already answered, I didn't found anything...
I'm trying to write a lazy-loader for different maps into a platformer game. Maps are made with Tiled and loaded into Love2D with STI (btw, thanks for this module @Karai17!), at this point I realized that everytime I switch to another map, the old map seems still loaded. Example, I've got the following code to get the graphic stats, because I noticed an increment of memory everytime I get into a new level/map:
Code: Select all
local stats = love.graphics.getStats()
print("Canvases: " .. stats["canvases"]
print("Texture Memory: " .. stats["texturememory"] / 1024 / 1024
Each map has 2 layers, tiles and objects. For the first map, the Canvases value is 2, OK. Second map, 4. Third map, 6... And the texture memory, increases by 12-13 MB each time.
My lazy loader has the following code:
Code: Select all
local levelList = {
'level01',
'level02',
'level03'
}
function Level:load(level)
map = sti("assets/maps/" .. levelList[level] .. ".lua", { "box2d" })
return map
end
Actually is just an "array of levels" and loader by selector. There is no function to unload the level. Everytime I call Level:load(), also sets the variable to nil and load it again. But I think there should be any way to unload/release the old unneeded canvases, isn't it? Maybe I just forgot something...
Re: Simple Tiled Implementation - STI v1.2.3.0
Posted: Thu Apr 23, 2020 10:24 pm
by pgimeno
Re: Simple Tiled Implementation - STI v1.2.3.0
Posted: Thu Apr 23, 2020 10:49 pm
by Karai17
Hm. It would seem that luajit isn't properly removing canvases when they are dereferenced. I'll have to look into this. I can call :release() on canvases when they are knowingly being tossed, such as when resizing the window, but I may need to add some sort of destroy function to a map to properly clear canvases when you are overwriting a variable in your own code.
Also worth noting in the code you show in your post, your "map" variable is global and so returning it isn't particularly useful. What I would recommend instead would simply be
Code: Select all
function Level:load(level)
return sti(string.format("assets/maps/%s.lua", levelList[level]), { "box2d" })
end
Re: Simple Tiled Implementation - STI v1.2.3.0
Posted: Thu Apr 23, 2020 11:00 pm
by JuanjoSalvador
That was I thought. But the canvases are created by STI, so... I can hack the library to add my own release() function into the old canvas. In fact, I added my own function, but only can release one of the two created canvas. I'm holding this line, thanks again!
Karai17 wrote: ↑Thu Apr 23, 2020 10:49 pm
Also worth noting in the code you show in your post, your "map" variable is global and so returning it isn't particularly useful. What I would recommend instead would simply be
Code: Select all
function Level:load(level)
return sti(string.format("assets/maps/%s.lua", levelList[level]), { "box2d" })
end
Yeah, I need to rewrite a lot, and also I need to improve my Lua skills... Thanks for the suggestion
I'm going to check the lib and if ) I'm able to add a properly :release() function for the canvases, maybe I can send you a PR.
Re: Simple Tiled Implementation - STI v1.2.3.0
Posted: Thu Apr 23, 2020 11:46 pm
by pgimeno
Karai17 wrote: ↑Thu Apr 23, 2020 10:49 pm
Hm. It would seem that luajit isn't properly removing canvases when they are dereferenced.
It's working as designed. The problem is that there aren't enough objects to trigger a GC; LuaJIT doesn't know (or care about, not sure) the underlying size of the objects so it treats all the same way regardless of size. If you just keep generating objects, eventually the GC will trigger and the canvases will be released, but that delay may not be affordable for some use cases. If you call collectgarbage() manually, the canvases are removed immediately.
Re: Simple Tiled Implementation - STI v1.2.3.0
Posted: Fri Apr 24, 2020 1:08 pm
by JuanjoSalvador
pgimeno wrote: ↑Thu Apr 23, 2020 11:46 pm
If you call collectgarbage() manually, the canvases are removed immediately.
This works too. No need to call my custom :release() for canvas everytime I load a new map, just collectgarbage() and go.
Re: Simple Tiled Implementation - STI v1.2.3.0
Posted: Tue May 26, 2020 5:33 am
by dashbandith
Greetings, I am new to Löve2d and I want to use it in my STI project. Sorry if my question is very basic I copy and paste the example from the tutorial (
https://github.com/karai17/Simple-Tiled ... -to-sti.md)
Code: Select all
-- Include Simple Tiled Implementation into project
local sti = require "sti"
function love.load()
-- Load map file
map = sti("map.lua")
-- Create new dynamic data layer called "Sprites" as the 8th layer
local layer = map:addCustomLayer("Sprites", 8)
-- Get player spawn object
local player
for k, object in pairs(map.objects) do
if object.name == "Player" then
player = object
break
end
end
-- Create player object
local sprite = love.graphics.newImage("sprite.png")
layer.player = {
sprite = sprite,
x = player.x,
y = player.y,
ox = sprite:getWidth() / 2,
oy = sprite:getHeight() / 1.35
}
-- Add controls to player
layer.update = function(self, dt)
-- 96 pixels per second
local speed = 96 * dt
-- Move player up
if love.keyboard.isDown("w", "up") then
self.player.y = self.player.y - speed
end
-- Move player down
if love.keyboard.isDown("s", "down") then
self.player.y = self.player.y + speed
end
-- Move player left
if love.keyboard.isDown("a", "left") then
self.player.x = self.player.x - speed
end
-- Move player right
if love.keyboard.isDown("d", "right") then
self.player.x = self.player.x + speed
end
end
-- Draw player
layer.draw = function(self)
love.graphics.draw(
self.player.sprite,
math.floor(self.player.x),
math.floor(self.player.y),
0,
1,
1,
self.player.ox,
self.player.oy
)
-- Temporarily draw a point at our location so we know
-- that our sprite is offset properly
love.graphics.setPointSize(5)
love.graphics.points(math.floor(self.player.x), math.floor(self.player.y))
end
-- Remove unneeded object layer
map:removeLayer("Spawn Point")
end
function love.update(dt)
-- Update world
map:update(dt)
end
function love.draw()
-- Scale world
local scale = 2
local screen_width = love.graphics.getWidth() / scale
local screen_height = love.graphics.getHeight() / scale
-- Translate world so that player is always centred
local player = map.layers["Sprites"].player
local tx = math.floor(player.x - screen_width / 2)
local ty = math.floor(player.y - screen_height / 2)
-- Transform world
love.graphics.scale(scale)
love.graphics.translate(-tx, -ty)
-- Draw world
map:draw()
end
and when running it shows me the following error message .
Code: Select all
Error
sti/init.lua:729: Layer not found: Spawn Point
Traceback
[C]: in function 'assert'
sti/init.lua:729: in function 'removeLayer'
main.lua:76: in function 'load'
[C]: in function 'xpcall'
[C]: in function 'xpcall'
What am I doing wrong?
Re: Simple Tiled Implementation - STI v1.2.3.0
Posted: Tue May 26, 2020 5:52 pm
by Karai17
you don't have a layer in your map named Spawn Point so trying to remove it is throwing an error.