Importing ATL tile properties

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
Post Reply
SudoCode
Citizen
Posts: 61
Joined: Fri May 04, 2012 7:05 pm

Importing ATL tile properties

Post by SudoCode »

Code: Select all

function loadMap()
	
	column = {}
	tileID = 0
	loader = require("AdvTiledLoader.Loader")
	loader.path = "assets/maps/"
	Map = loader.load("test.tmx")
	
	-- Tile Properties
	for Dirt, tileLayer in pairs(Map.tileLayers) do
		for y, column in pairs(tileLayer) do
			for x, tileID in pairs(column) do
				if Map.tiles[tileID] and Map.tiles[tileID].properties.Solid then
					Collider:newRectangle(x, y, map.tileWidth, map.tileHeight)
				end
			end
		end
	end
	
	
end

function drawMap()

	Map:draw()
	Map:autoDrawRange(x, y, 1, 3000)
	
end
I'm attempting to import tile properties and draw rectangles at solid tiles.

I've searched the forums and found code for it (above) but I'm fairly confused with the syntax (i.e. the wiki page on github says that 'Tile.properties' contains the properties of the tile set in Tiled, and 'TileSet.tileProperties' is the properties of the contained tiles index by the gid. So 'Tile.properties' and 'TileSet.tileProperties' both contain property information for a specific tile?) and what data I should be pulling from specific tables.
Attachments
topdown.love
(385.14 KiB) Downloaded 58 times
User avatar
Kadoba
Party member
Posts: 399
Joined: Mon Jan 10, 2011 8:25 am
Location: Oklahoma

Re: Importing ATL tile properties

Post by Kadoba »

Sorry about the confusion. Tiles actually do not have their own structure inside tmx files. Instead their properties are bundled inside their tilesets. So when ATL creates tile objects they have to be "cut-out" of the tileset. That is why the properties are in two places. Bascially the bundled "raw" format is inside the tileset which is populated out into the individual tiles when they are created. TileSet.tileProperties should really be private. You never have to worry about it. It's mostly there for those who are familiar with the tmx format.

Also, the code that you have is from and older version of ATL. Back was things were admittedly very confusing. Now all of the layer tiles are in map.tileLayers["layer name"].tileData. It uses a grid data structure instead of a 2d array. The easiest way to iterate over all values is to use the iterate() function.

Code: Select all

for name, layer in pairs(map.tileLayers) do
    for x, y, tile in layer.tileData:iterate() do
       if tile.properties.solid then 
          Collider:newRectangle(x, y, map.tileWidth, map.tileHeight) 
      end
   end
end
I hope that clears things up. If you still need help let me know.
SudoCode
Citizen
Posts: 61
Joined: Fri May 04, 2012 7:05 pm

Re: Importing ATL tile properties

Post by SudoCode »

Thanks for the help.

The problem now is that iterate() seems to be adding rectangles everywhere - when I load the game, I'm immediately moved on the x axis very quickly, as if being moved out of a shape.
Attachments
topdown.love
(385.14 KiB) Downloaded 67 times
Zeliarden
Party member
Posts: 139
Joined: Tue Feb 28, 2012 4:40 pm

Re: Importing ATL tile properties

Post by Zeliarden »

Yo!
Recommend that you make a layer and a tileset just for collision. (make the tileset some extra rows for future collision like water if you going to have that)
User avatar
Kadoba
Party member
Posts: 399
Joined: Mon Jan 10, 2011 8:25 am
Location: Oklahoma

Re: Importing ATL tile properties

Post by Kadoba »

It looks like the problem is in collide.lua

Code: Select all

function collide(dt, shape_a, shape_b, dx, dy)
	
	shape_a = player.hitbox
	shape_b = testshape
	
	shape_a:move(math.floor(dx), math.floor(dy))
	
end
That's setting shape_a to the player and moving it when any shape collides. You probably want something more like this:

Code: Select all

function collide(dt, shape_a, shape_b, dx, dy)

	if shape_a == player.hitbox then
		shape_a:move(math.floor(dx), math.floor(dy))
	end

end
Also my code was wrong.

Code: Select all

-- instead of this:
Collider:newRectangle(x, y, map.tileWidth, map.tileHeight) 

-- do this:
Collider:newRectangle(x * map.tileWidth, y * map.tileHeight, map.tileWidth, map.tileHeight) 
SudoCode
Citizen
Posts: 61
Joined: Fri May 04, 2012 7:05 pm

Re: Importing ATL tile properties

Post by SudoCode »

Kadoba wrote:It looks like the problem is in collide.lua

Code: Select all

function collide(dt, shape_a, shape_b, dx, dy)
	
	shape_a = player.hitbox
	shape_b = testshape
	
	shape_a:move(math.floor(dx), math.floor(dy))
	
end
That's setting shape_a to the player and moving it when any shape collides. You probably want something more like this:

Code: Select all

function collide(dt, shape_a, shape_b, dx, dy)

	if shape_a == player.hitbox then
		shape_a:move(math.floor(dx), math.floor(dy))
	end

end
Also my code was wrong.

Code: Select all

-- instead of this:
Collider:newRectangle(x, y, map.tileWidth, map.tileHeight) 

-- do this:
Collider:newRectangle(x * map.tileWidth, y * map.tileHeight, map.tileWidth, map.tileHeight) 
This really helped, thanks.

Also, what would be the best way to insert the new shapes into a table? I'm trying to debug the collisions (the player gets stuck in the solid tiles when you collide with them) but I would need a specific table value to draw the solid tiles as shapes.

I've tried

Code: Select all

function loadMap()

	solidTable = {}
	loader = require("AdvTiledLoader.Loader")
	loader.path = "assets/maps/"
	Map = loader.load("test.tmx")
	
	-- Tile Properties
	for name, layer in pairs(Map.tileLayers) do
		for x, y, tile in layer.tileData:iterate() do
			if tile.properties.Solid then
				for i, v in ipairs(solidTable) do
					solidTable[i] = Collider:addRectangle(x * Map.tileWidth, y * Map.tileHeight, Map.tileWidth, Map.tileHeight)
				end
			end
		end
	end
	
	
end
and

Code: Select all

function loadMap()

	solidTable = {x = 0, y = 0, width = 0, height = 0, tileID = 0}
	loader = require("AdvTiledLoader.Loader")
	loader.path = "assets/maps/"
	Map = loader.load("test.tmx")
	
	-- Tile Properties
	for name, layer in pairs(Map.tileLayers) do
		for x, y, tile in layer.tileData:iterate() do
			if tile.properties.Solid then
				table.insert(solidTable[tileID], {Collider:addRectangle(x * Map.tileWidth, y * Map.tileHeight, Map.tileWidth, Map.tileHeight)})
			end
		end
	end
	
	
end
User avatar
Kadoba
Party member
Posts: 399
Joined: Mon Jan 10, 2011 8:25 am
Location: Oklahoma

Re: Importing ATL tile properties

Post by Kadoba »

Okay let's look at what you tried to do

Code: Select all

for i, v in ipairs(solidTable) do
   solidTable[i] = Collider:addRectangle(x * Map.tileWidth, y * Map.tileHeight,  Map.tileWidth, Map.tileHeight)
end
What this would do is go through every existing ipair in solidTable and then to reassign it to a new rectangle body. The table is empty and no pairs exist so this doesn't do anything.

Code: Select all

-- first this
solidTable = {x = 0, y = 0, width = 0, height = 0, tileID = 0}

-- and later this
table.insert(solidTable[tileID], {Collider:addRectangle(x * Map.tileWidth, y * Map.tileHeight, 
                                                        Map.tileWidth, Map.tileHeight)})
This creates a table and assigns some fields in it to zero. Then table.insert tries to insert a rectangle body into solidTable.tileID, which is a number and not a table so this likely raises an error.


So I assume what you're trying to do is create a table and insert the dimensions, tile, and body of each solid tile into it. If you store the body (heh) you don't need the dimensions since the body already has that information. So you really only need to keep the tile and body. Well, the tile is probably a useful thing for the body to know about anyway so lets' just make the body remember which tile it belongs to. After that you really only need to store the body.

Code: Select all

function loadMap()

   solidTable = {}
   loader = require("AdvTiledLoader.Loader")
   loader.path = "assets/maps/"
   Map = loader.load("test.tmx")
   
   -- Tile Properties
   for name, layer in pairs(Map.tileLayers) do
      for x, y, tile in layer.tileData:iterate() do
         if tile.properties.Solid then
            -- Insert the body at the end of the table
            table.insert(solidTable, Collider:addRectangle(x * Map.tileWidth, y * Map.tileHeight,
                                                         Map.tileWidth, Map.tileHeight))
            -- Assign the tile to the last body in the table. That would be the one we just inserted.
            solidTable[#solidTable].tile = tile
            end
         end
      end
   end
end
This is unrelated but I highly recommend you store all of your global values in one table. It will make your life a lot easier later on.
SudoCode
Citizen
Posts: 61
Joined: Fri May 04, 2012 7:05 pm

Re: Importing ATL tile properties

Post by SudoCode »

Thanks, I'm able to draw shapes at the solid tiles now :awesome:

And what do you mean by global values? My global variables?
Attachments
topdown.love
(385.23 KiB) Downloaded 56 times
User avatar
Kadoba
Party member
Posts: 399
Joined: Mon Jan 10, 2011 8:25 am
Location: Oklahoma

Re: Importing ATL tile properties

Post by Kadoba »

And what do you mean by global values? My global variables?
Yep. And the reason the player gets stuck is because it gets moved in the wrong direction.
Post Reply

Who is online

Users browsing this forum: Bing [Bot], MrFariator and 6 guests