adrien-bon / bevy_ecs_tiled

Helpers for working with 2D tilemaps created with the Tiled map editor
MIT License
34 stars 8 forks source link

Add support for animated tiles and fix multiple layers #4

Closed adrien-bon closed 4 months ago

adrien-bon commented 4 months ago

Hi,

here is a new PR :)

I packed several changes in the same PR because changes were not that large and it was a bit complex to separate everything. Hopefully it's not a problem!

Clippy warnings

I did not resist to fix clippy warnings, hence the complexity to separated things as it moves some code a bit everywhere. It should be fine now.

Animated tiles

I added support for animated tiles. There are quite a few limitations regarding animations in bevy_ecs_tilemap so I added some sanity checks and discard the tile + print a warning in case I detect the tile is not supported. Not supported tiles would be when we have either:

Multiple layers handling

There was an issue if we had several layers in our .TMX. Since all layers had the same Z position, it was not deterministic which one would show in case of tiles being on top of each other. I added a flat offset of 100 between each layer to resolve this.

We can discuss about this absolute value: example in bevy_ecs_tilemap uses an offset of only 1 but I wanted something "big enough" to make sure layers ordering will be preserved, even if something mess a bit with Z offset (for instance here or here)

New example with an hexagonal map

Finally, I added a new example to illustrate both hexagonal map, animated tiles and the usage of multiple layers. The asset is licensed "CC0" / "Public Domain" so it should be OK. Anyway, I added a README to list where I got the .png file.

adrien-bon commented 4 months ago

Fixed the unwrap()s, you are right we should avoid these! :)

Regarding the map loading I'm not sure to understand which settings in particular you want to give control to the user. But I'm all up to use the new hooks and observers from Bevy 0.14!

Regarding the animation, I believe this kind of stuff should go in bevy_ecs_tilemap. As I see it, bevy_ecs_tiled crate serves as a bridge between the "Tiled" world and the "Bevy" world through the bevy_ecs_tilemap crate, which handle all the rendering stuff. Here, we should only focus about "Tiled" specifics and contribute to generic stuff in bevy_ecs_tilemap (which could maybe be upstreamed in bevy one day ?)

I'll try to implement object and tile mapping to custom entities. I plan to take inspiration from both bevy_ecs_ldtk and bevy_entitiles. The idea would be to define components in Tiled, on both objects and tiles, then have these components added to Bevy entities. The user would only have to declare matching components in its code.

In a second time, we could re-use this for colliders. Currently, you add objects name you want colliders on to a list. We could instead declare a component, representing the object / tile you want collider on, and associate it a macro so it will automatically add a collider on spawn.

What do you think ?

stevepryde commented 4 months ago

Fixed the unwrap()s, you are right we should avoid these! :)

Regarding the map loading I'm not sure to understand which settings in particular you want to give control to the user. But I'm all up to use the new hooks and observers from Bevy 0.14!

I was working on my game for the current jam, and wanted to use shape or position data from an object layer in Tiled to represent other things in my game world, such as spawn point or the locations at which to spawn other entities that aren't tiles. Or you could imagine specifying a region for an enemy to patrol, and things like that.

These are outside the scope of the crate but we should still expose this data somehow. Ideally in a way that doesn't require the caller to also import the same version of the tiled crate.

Regarding the animation, I believe this kind of stuff should go in bevy_ecs_tilemap. As I see it, bevy_ecs_tiled crate serves as a bridge between the "Tiled" world and the "Bevy" world through the bevy_ecs_tilemap crate, which handle all the rendering stuff. Here, we should only focus about "Tiled" specifics and contribute to generic stuff in bevy_ecs_tilemap (which could maybe be upstreamed in bevy one day ?)

Not a bad idea. It would definitely be worth communicating upstream for things like this that are not Tiled-specific.

I'll try to implement object and tile mapping to custom entities. I plan to take inspiration from both bevy_ecs_ldtk and bevy_entitiles. The idea would be to define components in Tiled, on both objects and tiles, then have these components added to Bevy entities. The user would only have to declare matching components in its code.

Becoming more familiar with bevy_ecs_ldtk is on my todo list. That crate has been around for a while so there's a lot we can learn from. The same is true for bevy_entitiles.

I already added some components including marker components that can be queried, but I did it naively without having real-world use-cases to pull from.

In a second time, we could re-use this for colliders. Currently, you add objects name you want colliders on to a list. We could instead declare a component, representing the object / tile you want collider on, and associate it a macro so it will automatically add a collider on spawn.

What do you think ?

I'm not really following what you're suggesting. A code example would be great. No rush.

Let's move this to the Discussions tab. Feel free to start discussions or even issues for any feature proposals.