Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Is there a way to access the texture of a tile? #166

Open
alexispurslane opened this issue Feb 12, 2018 · 7 comments
Open

Is there a way to access the texture of a tile? #166

alexispurslane opened this issue Feb 12, 2018 · 7 comments

Comments

@alexispurslane
Copy link

I'm trying to render each tile individually so that I can interleave sprites into the map so that they draw in the correct Z-order (this is an isometric map, so the sprite needs to be behind some walls and in front of others.), and I need to be able to access the texture of a tile in order to do that. Here's my current draw code:

function love.draw()
   -- Draw world
   tiles = map.tileInstances
   table.sort(tiles, function (a,b)
                 return a.x < b.x
   end)
   for k,v in ipairs(tiles) do
      local tile = map.tiles[v.gid]
      local texture = nil --what goes here?
      love.graphics.draw(texture, tile.quad, v.x, v.y)
   end
end

Thanks!

@karai17
Copy link
Owner

karai17 commented Feb 12, 2018 via email

@alexispurslane
Copy link
Author

Okay, that makes sense, but the spritebatch is nil for the tileInstances list (which I think is actually the correct list to use when you want all the tiles in the map?). Here's my code now:

function love.draw()
   -- Draw world
   tiles = map.tileInstances
   for k,v in ipairs(tiles) do
      local tile = map.tiles[v.gid]
      local texture = v.batch.getTexture()
      love.graphics.draw(texture, tile.quad, v.x, v.y)
   end
end

@karai17
Copy link
Owner

karai17 commented Feb 16, 2018

I believe v is actually a list of tile instances of that global tile, so you may need to search inside one of those tiles for the batch.

What might be easier is to get the X/Y position of a tile and use the coordinate convert function to get that exact tile in the appropriate layer.

@khamarr3524
Copy link

khamarr3524 commented Feb 17, 2018

I'm having issues with this as well. What I'm trying to do is probably a little different, but I have 2 layers in the map. One layer for the textures and one for the normals. I'm trying to get the texture for each tile in the normals layer so that I can pass it to the light library I'm using for each tile in the normal map but I'm not finding it very easy. I couldn't see any way in Tiled or STI to implement normal maps any easier either. The only thing I can think of is assign a custom property to tiles in the Tiled tileset and use that value to do a lookup in my own list of textures.

Edit: To answer the original question, you can access the spritebatches and quads via map.layers["layerName"]. Store the batches table locally and loop through the tiles in map.layers["layerName"].data[y][x] and you get the Quad quad and number tileset, use those to draw the specific tile.

An example of this would be

function love.draw()
    local batches = map.layers[1].batches
    for y = 1, map.layers[1].height do
      for x = 1, map.layers[1].width do
        local tile = map.layers[1].data[y][x]
        love.graphics.draw(batches[tile.tileset], tile.quad, x*tileSize, y*tileSize)
      end
    end
end

This somewhat addresses the issue I brought up because it demonstrates that what I'm trying to do is impossible and I have to find another way because I need an actual image and I don't think there's a way to get an Image object from a SpriteBatch and quad. If there is, then great, but for now I have to create my own means of indexing the tile normal maps.

@alexispurslane
Copy link
Author

The way I get access to the actual image now is actually a modification to the STI library itself. It looks like this:

-- @param number Tile location on Y axis (in tiles)
function Map:addNewLayerTile(layer, tile, x, y)
    local tileset = tile.tileset
    local image   = self.tilesets[tile.tileset].image

    layer.batches[tileset] = layer.batches[tileset]
        or lg.newSpriteBatch(image, layer.width * layer.height)

    local batch = layer.batches[tileset]
    local tileX, tileY = self:getLayerTilePosition(layer, tile, x, y)

    local tab = {
        layer = layer,
        gid   = tile.gid,
        x     = tileX,
        y     = tileY,
        r     = tile.r,
        oy    = 0
    }

    if batch then
        tab.batch = batch
        tab.id = batch:add(tile.quad, tileX, tileY, tile.r, tile.sx, tile.sy)
    end

    self.tileInstances[tile.gid] = self.tileInstances[tile.gid] or {}
    table.insert(self.tileInstances[tile.gid], tab)
    table.insert(layer.tiles, {
                     tileset = self.tilesets[tile.tileset].image,
                     gid     = tile.gid,
                     x       = tileX,
                     y       = tileY,
                     z       = tileY,
                     r       = tile.r,
                     offset  = self.tiles[tile.gid].offset,
                     oy     = 0,
                     quad   = tile.quad,
                     kind   = "tile",
    })
end

Just replace the origional function in sti/init.lua with this and then loop through each layer's .tiles property and they'll have a tileset property that contains your image.

@khamarr3524
Copy link

khamarr3524 commented Feb 18, 2018

This looks like it'll work for your needs, there definitely needed to be a cleaner way to do what I wrote that script to do, not sure if @karai17 will want to have this added or not, but it likely won't help me much since the nature of the issue is that I need an Image object that is explicitly only that specific tile, without having to apply a Quad.

Also, not sure if this is accurate since I don't have the time to dig into it right now but this might be a big memory issue because it looks like you're copying the image repeatedly. But again, I'm not 100% sure of that.

@karai17
Copy link
Owner

karai17 commented Feb 25, 2018

I will definitely admit that STI coudl use with some quality of life improvements. I've largely neglected this library over the past year or so but if anyone wants to send some PRs, I'd be happy to accept help in improving STI.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants