Simple Tiled Implementation - STI v1.2.3.0

Showcase your libraries, tools and other projects that help your fellow love users.
User avatar
Cryogenical
Prole
Posts: 49
Joined: Mon Apr 28, 2014 5:23 pm

Re: Simple Tiled Implementation - STI v0.7.4

Post by Cryogenical »

Does someone have an example of how to implement collision with tiled maps?
User avatar
Karai17
Party member
Posts: 930
Joined: Sun Sep 02, 2012 10:46 pm

Re: Simple Tiled Implementation - STI v0.7.4

Post by Karai17 »

Cryogenical wrote:Does someone have an example of how to implement collision with tiled maps?
The simplest way to implement tile collision is to create a collision layer with 0 visibility and then use STI's built in collision map function to get a binary map of the collision layer. Once you have that, you can just check your movement against that map.

Code: Select all

local sti = require "sti"

function love.load()
    map = sti.new("map")
    collision = map:getCollisionMap("Collision Layer")
    player = { x = 24, y = 36 } -- player is standing on the 24,36 block of the map
end

function love.keypressed(key, isrepeat)
    if key == "up" then
        if collision.data[player.y - 1][player.x] ~= 1 then
            -- the block above us is not collidable, so we can walk there!
            player.y = player.y - 1
        end

        return
    end

    if key == "down" then
        if collision.data[player.y + 1][player.x] ~= 1 then
            -- the block below us is not collidable, so we can walk there!
            player.y = player.y + 1
        end

        return
    end

    if key == "left" then
        if collision.data[player.y][player.x - 1] ~= 1 then
            -- the block to the left of us is not collidable, so we can walk there!
            player.x = player.x - 1
        end

        return
    end

    if key == "right" then
        if collision.data[player.y][player.x + 1] ~= 1 then
            -- the block to the right of us is not collidable, so we can walk there!
            player.x = player.x + 1
        end

        return
    end
end

STI - An awesome Tiled library
LÖVE3D - A 3D library for LÖVE 0.10+

Dev Blog | GitHub | excessive ❤ moé
User avatar
Cryogenical
Prole
Posts: 49
Joined: Mon Apr 28, 2014 5:23 pm

Re: Simple Tiled Implementation - STI v0.7.4

Post by Cryogenical »

I've tried to implement it like this

Code: Select all

local sti = require "lib.sti"
require "player"

function love.load()
    
    map = sti.new("assets/maps/map01")
    collision = map:getCollisionMap("solidlayer")
    --player = { act_x = 24, act_y = 36 }

end


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



function love.draw()
    map:draw()
    player.draw()
    
end

function love.keypressed(key, isrepeat)
    if key == "up" then
        if collision.data[player.act_y - 1][player.act_x] ~= 1 then
            -- the block above us is not collidable, so we can walk there!
            player.act_y = player.act_y - 1
        end

        return
    end
    if key == "down" then
        if collision.data[player.act_y + 1][player.act_x] ~= 1 then
            -- the block below us is not collidable, so we can walk there!
            player.act_y = player.act_y + 1
        end

        return
    end

    if key == "left" then
        if collision.data[player.act_y][player.act_x - 1] ~= 1 then
            -- the block to the left of us is not collidable, so we can walk there!
            player.act_x = player.act_x - 1
        end

        return
    end

    if key == "right" then
        if collision.data[player.act_y][player.act_x + 1] ~= 1 then
            -- the block to the right of us is not collidable, so we can walk there!
            player.act_x = player.act_x + 1
        end

        return
    end
end
This is my player.lua file:

Code: Select all

player = {
    grid_x = 380,
    grid_y = 96,
    act_x = 24,
    act_y = 36,
    speed = 10,
    image = love.graphics.newImage("assets/images/player.png")
	}
function player.update(dt)
	player.act_y = player.act_y - ((player.act_y - player.grid_y) * player.speed * dt)
	player.act_x = player.act_x - ((player.act_x - player.grid_x) * player.speed * dt)
end
function canWalk(x, y)
    if map[(player.grid_y / 32) + y][(player.grid_x / 32) + x] == 1 
    or map[(player.grid_y / 32) + y][(player.grid_x / 32) + x] == 2
    or map[(player.grid_y / 32) + y][(player.grid_x / 32) + x] == 3 then
        return false
    end
 	return true
end
function player.draw()
    love.graphics.draw(player.image, player.act_x, player.act_y)
end
it's trying to index a value in each keypress, but it's returning nil. Do I need to instantiate a table for collision.data? Is it already pre-defined in the STI library or what?
User avatar
Karai17
Party member
Posts: 930
Joined: Sun Sep 02, 2012 10:46 pm

Re: Simple Tiled Implementation - STI v0.7.4

Post by Karai17 »

is "solidlayer" the actual name of one of your layers? when a collision map is created, it puts all the binary data in the data key
STI - An awesome Tiled library
LÖVE3D - A 3D library for LÖVE 0.10+

Dev Blog | GitHub | excessive ❤ moé
User avatar
Cryogenical
Prole
Posts: 49
Joined: Mon Apr 28, 2014 5:23 pm

Re: Simple Tiled Implementation - STI v0.7.4

Post by Cryogenical »

In Tiled I created a new layer and that's where I placed my objects like trees, bushes, and rocks. I want these to become "solid", where the player cannot go through, so, collision.

Code: Select all

 type = "tilelayer",
      name = "solidlayer",
      x = 0,
      y = 0,
      width = 16,
      height = 16,
      visible = true,
      opacity = 1,
      properties = {},
      encoding = "lua",
      data = {
        9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
        9, 9, 2, 10, 0, 0, 10, 2, 9, 9, 0, 0, 0, 0, 0, 9,
        9, 10, 10, 0, 0, 0, 0, 6, 0, 9, 0, 0, 0, 0, 0, 9,
        9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9,
        9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9,
        9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9,
        9, 0, 0, 0, 0, 2, 10, 10, 2, 2, 10, 10, 10, 9, 9, 9,
        9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9,
        9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 9,
        9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9,
        9, 0, 2, 0, 0, 10, 10, 10, 2, 10, 0, 0, 0, 0, 0, 9,
        9, 10, 0, 0, 10, 0, 0, 0, 0, 10, 10, 0, 0, 0, 0, 9,
        9, 10, 0, 0, 0, 0, 0, 0, 0, 2, 10, 0, 0, 0, 0, 9,
        9, 9, 10, 6, 0, 0, 0, 0, 0, 2, 10, 0, 0, 0, 0, 9,
        9, 9, 9, 10, 10, 2, 9, 9, 2, 2, 0, 0, 0, 0, 0, 9,
        9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 6, 0, 0, 0, 6, 9
      }
User avatar
Karai17
Party member
Posts: 930
Joined: Sun Sep 02, 2012 10:46 pm

Re: Simple Tiled Implementation - STI v0.7.4

Post by Karai17 »

Send me a .love
STI - An awesome Tiled library
LÖVE3D - A 3D library for LÖVE 0.10+

Dev Blog | GitHub | excessive ❤ moé
User avatar
Cryogenical
Prole
Posts: 49
Joined: Mon Apr 28, 2014 5:23 pm

Re: Simple Tiled Implementation - STI v0.7.4

Post by Cryogenical »

Here, I had my partner teach me how to make a .love because I'm bad
Attachments
Game.love
(38.17 KiB) Downloaded 130 times
Riesenbeck
Prole
Posts: 1
Joined: Fri May 16, 2014 7:04 pm

Re: Simple Tiled Implementation - STI v0.7.4

Post by Riesenbeck »

Cryogenical wrote:my partner
Hey, I'm Cryo's "partner", and the code you were given is basically our attempt of figuring this out. We're really new to lua and we figured that learning STI would be a great way to start with tile implementation, so sorry if we sound at all uneducated.
User avatar
Karai17
Party member
Posts: 930
Joined: Sun Sep 02, 2012 10:46 pm

Re: Simple Tiled Implementation - STI v0.7.4

Post by Karai17 »

Okay so the problem here is that your act_x and act_y are out of bounds. you player is waaaay off the grid. You rgrid is 16x16 but your player is at 24,36.
STI - An awesome Tiled library
LÖVE3D - A 3D library for LÖVE 0.10+

Dev Blog | GitHub | excessive ❤ moé
User avatar
Cryogenical
Prole
Posts: 49
Joined: Mon Apr 28, 2014 5:23 pm

Re: Simple Tiled Implementation - STI v0.7.4

Post by Cryogenical »

I looked at the Documentation of STI and saw the Properties section, and figured as much.

Should I be separating the layers using "map.layers" or something? I also saw the data array but there's a comment saying to not do that.

Code: Select all

function love.load()
    map = sti.new("assets/maps/map01")
    
    local groundLayer = map.layers["Ground"]
    
    -- Change a tile  --[[ THIS DOES NOT WORK ANYMORE AND WILL BE REPLACED WITH A NEW FUNCTION SOON! ]]--
    local x = 8 -- x coordinate of the tile
    local y = 15 -- y coordinate of the tile
    local gid = 572 -- Global ID of the new tile
    
    groundLayer.data[y][x] = map.tiles[gid]
    
    -- Stop drawing layer
    groundLayer.visible = false -- true to draw again
    
    -- Layer opacity
    groundLayer.opacity = 0.75 -- 0 for transparent, 1 for opaque
    
    -- Offset layer in pixels (this can be useful for parallax)
    groundLayer.x = -17 -- negative numbers offset left/up
    groundLayer.y = 34 -- positive numbers offset right/down
end
Post Reply

Who is online

Users browsing this forum: Bing [Bot], Majestic-12 [Bot] and 2 guests