Simple Tiled Implementation - STI v0.18.2.1

Showcase your libraries, tools and other projects that help your fellow love users.
User avatar
NightKawata
Party member
Posts: 290
Joined: Tue Jan 01, 2013 9:18 pm
Location: Cyberspace, Room 6502
Contact:

Re: Simple Tiled Implementation - STI v0.18.2.1

Post by NightKawata » Wed Jan 10, 2018 8:08 am

I didn't have any major issues using SSYGEN's STALKER-X lib with STI: https://github.com/SSYGEN/STALKER-X
"I view Python for game usage about the same as going fishing with a stick of dynamite. It will do the job but it's big, noisy, you'll probably get soaking wet and you've still got to get the damn fish out of the water." -taylor

User avatar
Pospos
Prole
Posts: 41
Joined: Sun Jun 18, 2017 11:10 am
Location: Agadir

Re: Simple Tiled Implementation - STI v0.18.2.1

Post by Pospos » Sat Jan 20, 2018 6:48 pm

i have this error.
Error: sti/init.lua:234: attempt to perform arithmetic on field 'offsetx' (a nil value)

and this is my code

Code: Select all

local sti = require "sti"

function love.load()
	-- Grab window size
	windowWidth  = love.graphics.getWidth()
	windowHeight = love.graphics.getHeight()

	-- Set world meter size (in pixels)
	love.physics.setMeter(32)

	-- Load a map exported to Lua from Tiled
	map = sti("map.lua")

	-- Prepare physics world with horizontal and vertical gravity
	world = love.physics.newWorld(0, 0)

	-- Prepare collision objects
	map:box2d_init(world)

	-- Create a Custom Layer
	map:addCustomLayer("Sprite Layer", 3)

	-- Add data to Custom Layer
	local spriteLayer = map.layers["Sprite Layer"]
	spriteLayer.sprites = {
		player = {
			image = love.graphics.newImage("assets/sprite.png"),
			x = 64,
			y = 64,
			r = 0,
		}
	}

	-- Update callback for Custom Layer
	function spriteLayer:update(dt)
		for _, sprite in pairs(self.sprites) do
			sprite.r = sprite.r + math.rad(90 * dt)
		end
	end

	-- Draw callback for Custom Layer
	function spriteLayer:draw()
		for _, sprite in pairs(self.sprites) do
			local x = math.floor(sprite.x)
			local y = math.floor(sprite.y)
			local r = sprite.r
			love.graphics.draw(sprite.image, x, y, r)
		end
	end
end

function love.update(dt)
	map:update(dt)
end

function love.draw()
	-- Draw the map and all objects within
	love.graphics.setColor(255, 255, 255)
	map:draw()

	-- Draw Collision Map (useful for debugging)
	love.graphics.setColor(255, 0, 0)
	map:box2d_draw()

	-- Please note that map:draw, map:box2d_draw, and map:bump_draw take
	-- translate and scale arguments (tx, ty, sx, sy) for when you want to
	-- grow, shrink, or reposition your map on screen.
end
ⵜⴰⵎⴰⵣⵉⵖⵜ(https://en.wikipedia.org/wiki/Berbers)

FrenchMasterSword
Prole
Posts: 3
Joined: Sat Jan 20, 2018 4:27 pm

Re: Simple Tiled Implementation - STI v0.18.2.1

Post by FrenchMasterSword » Sun Jan 21, 2018 10:59 am

Before any other problem, I just can't get löve to display my map ; it tells in the console and in the window that the only tileset used (Atlas :awesome: ) doesn't exists ; of course it exists at the given place. the path to the map being `assets/maps/map.lua`
If I change this path to "assets\\maps\\map.lua", it is now map.lua which doesn't exist, I get this error :
stack traceback:
[C]: in function 'newImage'
sti/utils.lua:197: in function 'fix_transparent_color'
sti/init.lua:105: in function 'init'
sti/init.lua:47: in function 'sti'
main.lua:6: in function 'load'
[string "boot.lua"]:440: in function <[string "boot.lua"]:436>
[C]: in function 'xpcall'
main.lua is alone with the "sti" file and "assets"
my code so far :

Code: Select all

-- Include Simple Tiled Implementation library
local sti = require "sti"
local tx, ty, sx, sy, map

function love.load()
    map = sti("assets\\maps\\map.lua")
    tx, ty = 0,0
    sx, sy = 1.5, 1.5
end

function love.update(dt)
    map:update(dt)
end

function love.draw()
    map:draw(-tx, -ty, sx, sy)
end
EDIT: well it's just that with, the tmx map, the tilesets have to depend of main.lua.
Also Kairi, I see you often say to draw with -tx and -ty
I suspect it is because the tiles start at the bottom right corner ; but you know, when you start a new map on Tiled, you can change it to upper left !

User avatar
modiX
Citizen
Posts: 54
Joined: Mon Dec 04, 2017 1:47 am

Re: Simple Tiled Implementation - STI v0.18.2.1

Post by modiX » Mon Jan 22, 2018 5:00 pm

FrenchMasterSword wrote:
Sun Jan 21, 2018 10:59 am
Before any other problem, I just can't get löve to display my map ; it tells in the console and in the window that the only tileset used (Atlas :awesome: ) doesn't exists ; of course it exists at the given place. the path to the map being `assets/maps/map.lua`
If I change this path to "assets\\maps\\map.lua", it is now map.lua which doesn't exist, I get this error :
stack traceback:
[C]: in function 'newImage'
sti/utils.lua:197: in function 'fix_transparent_color'
sti/init.lua:105: in function 'init'
sti/init.lua:47: in function 'sti'
main.lua:6: in function 'load'
[string "boot.lua"]:440: in function <[string "boot.lua"]:436>
[C]: in function 'xpcall'
main.lua is alone with the "sti" file and "assets"
my code so far :

Code: Select all

-- Include Simple Tiled Implementation library
local sti = require "sti"
local tx, ty, sx, sy, map

function love.load()
    map = sti("assets\\maps\\map.lua")
    tx, ty = 0,0
    sx, sy = 1.5, 1.5
end

function love.update(dt)
    map:update(dt)
end

function love.draw()
    map:draw(-tx, -ty, sx, sy)
end
EDIT: well it's just that with, the tmx map, the tilesets have to depend of main.lua.
Also Kairi, I see you often say to draw with -tx and -ty
I suspect it is because the tiles start at the bottom right corner ; but you know, when you start a new map on Tiled, you can change it to upper left !
First of all, use / not \\ to point to your lua map file.
The reason why it cannot track your tileset file is, because the tile map editor stores the references relative to the lua map file, while LÖVE needs those relative to the root directory. I always wondered why Kairi never implemented a work around, so my work around is fixing those paths in the lua file with a post process including some regex. For now, you should change the paths by hand and you are good, I suppose.
───▄▀▀▀▄▄▄▄▄▄▄▀▀▀▄───
───█▒▒░░░░░░░░░▒▒█───
────█░░░░░░░░░█────
▄▄──█░░░▀█▀░░░█──▄▄
█░░█▀▄░░░░░░░▄▀█░░█

User avatar
Karai17
Party member
Posts: 835
Joined: Sun Sep 02, 2012 10:46 pm

Re: Simple Tiled Implementation - STI v0.18.2.1

Post by Karai17 » Mon Jan 22, 2018 8:50 pm

I recommend creatiing your maps in your game directory so when it comes time to load them, all the files are already where they should be.
STI - An awesome Tiled library
LÖVE3D - A 3D library for LÖVE 0.10+

Dev Blog | GitHub | excessive ❤ moé

User avatar
modiX
Citizen
Posts: 54
Joined: Mon Dec 04, 2017 1:47 am

Re: Simple Tiled Implementation - STI

Post by modiX » Thu Jan 25, 2018 12:32 pm

I'm on the point where I want to include some collision to my map and character. I'm glad there are plugins for bump and box2d already. I don't want to work with box2d, because of its sometimes not expectable behaviours. Bump on the other hand is a little too less for me. What, if I have tiles that are half collidable? Having tiles being half collidable horizontally or vertically could be solved by decreasing the tile width and height. But I'm thinking on the case when you allow diagonal collisions. Bump is not capable of handling triangle shapes on the collisions.

The simplest way is to use HC and build a new plugin for STI that allows 50% diagonal collision tiles like in Zelda-LttP:

Image

I think about besides the "collidable" property on the layer to have a collisionType property on each tile that defaults to the value "full" and should offer some additional values for various collision types like diagonal tiles:

Image

It would also require orientation information, although Zelda-LttP used to store only 4 different collision types:
full, diagonal left top to right bottom, diagonal right top to left bottom and none.

I also could imagine providing a 2nd layer that acts as collision mask. the collision layer could point to a mask layer with a property maskLayer. And supporting even objects (with masks) would be superior even more.

My question is, anybody did something like this for STI already? Also what do you think about this idea, Karai? Would you be interested supporting a HC plugin for STI?
───▄▀▀▀▄▄▄▄▄▄▄▀▀▀▄───
───█▒▒░░░░░░░░░▒▒█───
────█░░░░░░░░░█────
▄▄──█░░░▀█▀░░░█──▄▄
█░░█▀▄░░░░░░░▄▀█░░█

Saoskia
Prole
Posts: 3
Joined: Tue Feb 13, 2018 7:15 am

Re: Simple Tiled Implementation - STI v0.18.2.1

Post by Saoskia » Tue Feb 13, 2018 7:33 am

First post, yay :crazy:

I'm having an issue with the box2d plugin.
I'm pretty sure I have everything set up the way it should be in both Tiled and my code (I followed the tutorial on lua.space), but the collisions don't seem to be working. The documentation tells me absolutely nothing, so here I am.

I've looked through my code, and I'm not entirely sure the player has been given a collider. I'll post the code below as well as a .love file.

Can someone tell me if/where the player has been given a collider, and how I can fix it if need be.

Also, I kept getting an error with box2d regarding line 264 of box2d.lua. It has to do with translating the map which I chose not to do, so I just edited it out and everything works fine. If someone could also tell me why I'm getting this error, that would be great too.

Code: Select all

-- Include Simple Tiled Integration into project
local sti = require "sti"


function love.load()
    -- Load map file
    map = sti("maps/hi.lua", { "box2d" })

    world = love.physics.newWorld(0, 0)

    -- Create new dynamic data layer called "Sprites"
    local layer = map:addCustomLayer("Sprites", 4)

    -- 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("images/purple.png")
    layer.player = {
        sprite = sprite,
        x      = player.x,
        y      = player.y,
        ox     = sprite:getWidth() / 2,
        oy     = sprite:getHeight() / 2
    }

    -- Add controls to player
    layer.update = function(self, dt)

        local speed = 200

        -- Move player up
        if love.keyboard.isDown("w") then
            self.player.y = self.player.y - speed * dt
        end

        -- Move player down
        if love.keyboard.isDown("s") then
            self.player.y = self.player.y + speed * dt
        end

        -- Move player left
        if love.keyboard.isDown("a") then
            self.player.x = self.player.x - speed * dt
        end

        -- Move player right
        if love.keyboard.isDown("d") then
            self.player.x = self.player.x + speed * dt
        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("Player Spawn")

    -- Box2D
    map:box2d_init(world)
end


function love.update (dt)
    -- Update world
    map:update(dt)
end


function love.draw()
    -- Draw world
    map:draw()
    map:box2d_draw(world, 0, 0, 0, 0)
end
TiledTest.love
(25.37 KiB) Downloaded 2 times
Thanks :awesome:

User avatar
Karai17
Party member
Posts: 835
Joined: Sun Sep 02, 2012 10:46 pm

Re: Simple Tiled Implementation - STI v0.18.2.1

Post by Karai17 » Tue Feb 13, 2018 11:05 am

Take a look at the demo file in the OP, there shoudl be some collision code in there to reference.
STI - An awesome Tiled library
LÖVE3D - A 3D library for LÖVE 0.10+

Dev Blog | GitHub | excessive ❤ moé

User avatar
Karai17
Party member
Posts: 835
Joined: Sun Sep 02, 2012 10:46 pm

Re: Simple Tiled Implementation - STI

Post by Karai17 » Tue Feb 13, 2018 11:13 am

modiX wrote:
Thu Jan 25, 2018 12:32 pm
I'm on the point where I want to include some collision to my map and character. I'm glad there are plugins for bump and box2d already. I don't want to work with box2d, because of its sometimes not expectable behaviours. Bump on the other hand is a little too less for me. What, if I have tiles that are half collidable? Having tiles being half collidable horizontally or vertically could be solved by decreasing the tile width and height. But I'm thinking on the case when you allow diagonal collisions. Bump is not capable of handling triangle shapes on the collisions.

The simplest way is to use HC and build a new plugin for STI that allows 50% diagonal collision tiles like in Zelda-LttP:

Image

I think about besides the "collidable" property on the layer to have a collisionType property on each tile that defaults to the value "full" and should offer some additional values for various collision types like diagonal tiles:

Image

It would also require orientation information, although Zelda-LttP used to store only 4 different collision types:
full, diagonal left top to right bottom, diagonal right top to left bottom and none.

I also could imagine providing a 2nd layer that acts as collision mask. the collision layer could point to a mask layer with a property maskLayer. And supporting even objects (with masks) would be superior even more.

My question is, anybody did something like this for STI already? Also what do you think about this idea, Karai? Would you be interested supporting a HC plugin for STI?
I had asked vrld if he wanted to make an HC plugin for STI but he was busy at the time and I also got busy too. I made the box2d plugin as a reference and the bump plugin was made by a third party. If you want to make an HC plugin, I'd be very happy to accept a pull request. :)
STI - An awesome Tiled library
LÖVE3D - A 3D library for LÖVE 0.10+

Dev Blog | GitHub | excessive ❤ moé

Saoskia
Prole
Posts: 3
Joined: Tue Feb 13, 2018 7:15 am

Re: Simple Tiled Implementation - STI v0.18.2.1

Post by Saoskia » Tue Feb 13, 2018 2:23 pm

Thanks for the quick reply :awesome:

I checked out the OP, and I managed to get a collider onto the player object, but it's not working properly.
The player itself (the image) can still cross over other colliders. The player's collider does its best to actually collide with the other colliders, but ultimately will follow the player. I've managed to record a gif to show what I mean.
ColliderFail.gif
ColliderFail.gif (185.65 KiB) Viewed 157 times
How can I make sure the sprite image stops moving when the collider does?

Code: Select all

-- Include Simple Tiled Integration into project
local sti = require "sti"


function love.load()
    -- Load map file
    map = sti("maps/hi.lua", { "box2d" })

    -- Create world
    world = love.physics.newWorld(0, 0)
    map:box2d_init(world)

    -- Create new dynamic data layer called "Sprites"
    local layer = map:addCustomLayer("Sprites", 4)

    -- 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("images/purple.png")
    layer.player = {
        sprite = sprite,
        x      = player.x,
        y      = player.y,
        ox     = sprite:getWidth() / 2,
        oy     = sprite:getHeight() / 2
    }

    -- Add physics to player object
    layer.player.body = love.physics.newBody(world, layer.player.x, layer.player.y, "dynamic")
    layer.player.body:setFixedRotation(true)
    layer.player.shape = love.physics.newRectangleShape(sprite:getWidth(), sprite:getHeight())
    layer.player.fixture = love.physics.newFixture(layer.player.body, layer.player.shape)

    -- Add controls to player
    layer.update = function(self, dt)

        local speed = 200

        -- Move player up
        if love.keyboard.isDown("w") then
            self.player.y = self.player.y - speed * dt
        end

        -- Move player down
        if love.keyboard.isDown("s") then
            self.player.y = self.player.y + speed * dt
        end

        -- Move player left
        if love.keyboard.isDown("a") then
            self.player.x = self.player.x - speed * dt
        end

        -- Move player right
        if love.keyboard.isDown("d") then
            self.player.x = self.player.x + speed * dt
        end

        self.player.body:setX(self.player.x)
        self.player.body:setY(self.player.y)
    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
        )

        love.graphics.polygon("line", self.player.body:getWorldPoints(self.player.shape:getPoints()))        

        -- 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("Player Spawn")

end


function love.update (dt)
    -- Update world
    map:update(dt)
    world:update(dt)
end


function love.draw()
    -- Draw world
    map:draw()
    map:box2d_draw(world, 0, 0, 0, 0)
end
TiledTest.love
(25.51 KiB) Downloaded 4 times

Post Reply

Who is online

Users browsing this forum: No registered users and 4 guests