NicMagnier / PlaydateLDtkImporter

Load tilemaps created with LDtk in your playdate games
MIT License
102 stars 15 forks source link

Question about adding the tilemap layer sprites manually #4

Closed agmcleod closed 2 years ago

agmcleod commented 2 years ago

Hi there, trying this out i initially had some pretty basic code and got a map rendering:

local tilemap
function setup()
  LDtk.load("./levels/levelone.ldtk")
  tilemap = LDtk.create_tilemap("Level_0")
end

setup()

function playdate.update()
  tilemap:draw(0, 0)

  gfx.sprite.update()
end

However when i tried adding the collisions as per the README:

  local collisionTiles = LDtk.get_empty_tileIDs("Level_0", "Collider", "Tiles")
  if collisionTiles then
    gfx.sprite.addWallSprites(tilemap, collisionTiles)
  end

I can see the collision shapes in the right spot but the map no longer renders. I see in the game.lua file of this repo that you have a bunch of code to loop through the layers and add a bunch of sprites. Re-implementing that code on my side does fix the problem, but I'm a bit confused as to why it's necessary.

NicMagnier commented 2 years ago

Hey,

in the example we go through the different layer just to support whatever layers are added in the ldtk file. When you call LDtk.create_tilemap("Level_0") it might be better to specify which layer you want to handle with LDtk.create_tilemap("Level_0", "Tiles")

if you still have an issue, that would be useful to have a copy of your ldtk file so I can try out and figure out the issue.

agmcleod commented 2 years ago

Here's the file im working with here: https://gist.github.com/agmcleod/395af1dd6d58d49e29771d331d6888f4. I ended up changing tilesets, but once i re-applied some of the collider enums, the result turned out the same.

I did try tilemap = LDtk.create_tilemap("Level_0", "Tiles") but no luck i'm afraid. Thanks for the reply!

NicMagnier commented 2 years ago

ok I finally had time to look into the issue.

The issue is that you need to call the sprite update function to handle the sprite collision, but it will also manage the overall drawing of the game. So the game is blank because you don't have any sprite or background to display.

One solution is to treat the tilemap as a sprite (which is unusual for other system but normal on the playdate SDK) This one tend to be more performant and flexible.

function game.init()
    tilemap = LDtk.create_tilemap( "Level_0" )

    local layerSprite = playdate.graphics.sprite.new()
    layerSprite:setTilemap( tilemap )
    layerSprite:add()
end

The other solution is to display your tilemap as a background. Instead of a blank background, you can ask the playdate SDK to call a custom background drawing.

function game.init()
    tilemap = LDtk.create_tilemap( "Level_0" )

    playdate.graphics.sprite.setBackgroundDrawingCallback(
        function( x, y, width, height )
            tilemap:draw(0,0)
        end
    )
end
agmcleod commented 2 years ago

Ah thanks! I was wondering if it was the adding of sprites in the code here: https://github.com/NicMagnier/PlaydateLDtkImporter/blob/main/code/game.lua#L30 that maybe got it to work in the example. I am using a version of that code, but wondered if there was something simpler i was missing. Thank you :)