Trouv / bevy_ecs_ldtk

ECS-friendly ldtk plugin for bevy, leveraging bevy_ecs_tilemap
Other
664 stars 75 forks source link

Example manipulating tiles, layers and levels? #148

Open jruiss opened 1 year ago

jruiss commented 1 year ago

I can't seem to figure out how to manipulate(or add) a specific tile in a specific layer and level.

The best option I found so far for changing a tiles texture to another is to Query TileStorage but there's no way to know which layer or level the storage references.

It would be very helpful with small examples showing basic manipulation/adding etc.

Trouv commented 1 year ago

I think the crux of this issue is that it isn't very well-documented the hierarchy of entities spawned by the plugin. I think plugins that do any automated spawning like this one need to be super transparent about it, and even though this plugin is very well documented, we could do better. I'd like to make a diagram somewhere showing the hierarchy of things.

Parental relationships are currently the only way of telling which tiles/entities belong to which layers, and which layers belong to which levels, etc. Tiles are children of Layers, Layers are children of Levels, and Levels are children of Worlds. The components to query for each of these would be:

Things complicate even more when you consider that LdtkEntitys spawned by the plugin for Ldtk's Entity layers don't have a LayerMetadata component as their parent (their parent is simply the level entity by default). I hope to change this soon so that entity layers are more similar to the other layers, and have a LayerMetadata parent.

So, to figure out which layer a tile belongs to, you'd need to not only query for the tiles, but also request the Parent component of those tiles, and use that to get a particular LayerMetadata entity from a different query:

fn my_system(
    tile_query: Query<&Parent, With<MyTileComponent>>,
    layer_query: Query<&LayerMetadata>,
) {
    for my_tile_parent in tile_query.iter() {
        let layer_for_this_tile = layer_query.get(my_tile_parent.get());
    }
}

Or something like that. You could do something similar for figuring out which level a layer or tile belongs to, or you could do the reverse of this using the Children component of the parent entity.

Personally, I haven't had to do any tile manipulation in any of my projects using this plugin yet, so I'm curious what your particular use-case is that may be good inspiration for an example? Changing tile texture will involve more manipulation of bevy_ecs_tilemap components than ones provided by this plugin, but doing some filtering by layer/level in addition to performing those manipulations like you're suggesting may be pretty relevant.

jruiss commented 1 year ago

Thanks, this helps a lot!

Personally, I haven't had to do any tile manipulation in any of my projects using this plugin yet, so I'm curious what your particular use-case is that may be good inspiration for an example? Changing tile texture will involve more manipulation of bevy_ecs_tilemap components than ones provided by this plugin, but doing some filtering by layer/level in addition to performing those manipulations like you're suggesting may be pretty relevant.

I'm trying to implement a effect that can be found in the game Lords and Villeins, awesome game btw, where if a NPC walks enough times on a grass tile, it becomes a dirt path tile instead, creating natural paths for NPCs over the time making the world feel a bit more dynamic and alive.