estivate / ldtk_rust

Parse LDtk JSON files into typed Rust objects.
MIT License
63 stars 13 forks source link

Tileset offset is different in LDTK vs Rust #4

Closed jguhlin closed 3 years ago

jguhlin commented 3 years ago

Left is bevy (using engine example almost verbatim) and right is LDTK. As you can see the offset is a bit off. Debugging now but wanted to pass it along if you had any ideas. Using git version of ldtk_rust (although I don't think there are many changes, just because I'm on 0.7.2 for LDTK).

image

This is the tileset I'm using, by the way.

magecity

estivate commented 3 years ago

My first guess would be something to do with the tile size and/or tile scale. I think the tileset I used was pretty small and I scaled it up a good bit. It looks at first glance like your tiles are indexing correctly but aren't quite "fitting" the way they should. I'll swap out the tileset I used with a different sized one and see if I can generalize the example better.

I'll probably start by switching tile sets, setting the tile scale to 1 and then checking the math in the convert_to_world function. Hopefully that would lead me somewhere :)

estivate commented 3 years ago

Oh hmmmm... you mention tile offsets... it may be in `TextureAtlas::from_grid() ~ line 16 in my example... I don't think my tiles had an offset of any kind, so I might not have factored in some data coming from LDTK. But I'm not sure Bevy has a lot of options here yet.

estivate commented 3 years ago

So I was close with my second guess... looks like your tile set is 256x1450 pixels with 16px square tiles. The width is fine because 16x16=256, but the height isn't correct, at least not for Bevy's TextureAtlas::from_grid() method. When I trim off the bottom 10 pixels of your tile set (making it 256x1440) it works perfectly.

LDTK seems to quietly let the last row of tiles render out of frame but Bevy seems to use the full height in a calculation somewhere, and that messes up the way it divides out the tiles. That's why the grass at the top of the set looks right but the lower you go placing tiles, the worse the issue becomes.

You could process your sprites into Bevy another way (I think this would be hard but I'm not a Bevy expert) but it's way easier to just make sure your tile sets are evenly divisible by the tile size you're using. I'll add a comment to the example code noting this because it's something I didn't know about LDTK/Bevy.

I don't know if Bevy would consider this a bug or not, technically their method asks for tile size, columns and rows but it's not clear what the expected behavior would be if the columns/rows don't match the pixel size exactly.

jguhlin commented 3 years ago

Ahhhh yeah. It's a free tileset so I just used it without checking anything. This is good to know. I really appreciate it.

I don't think it's a bevy bug more of a gotcha, you can change the tile size in the TextureAtlas to do scaling, since it only calculates off of the columns and rows, IIRC.