Tiled utilities and an AssetLoader for the [Bevy game engine](https://bevyengine.org/).
> [!CAUTION]
> There are still quite a few bugs, missing / un-intuitive functionality, missing docs, etc.
> Usage, feedback, and contribution will help to improve support.
> [!NOTE]
> Colliders are generated by marking the object with a `bool` property called `collider`, and setting it to `true`
> [!NOTE]
> Objects in a Tile via their Tileset spawn Children Entities of the Parent Tile Entity. This is the case for both
> Tiles in a TileLayer and Tile Objects `ObjectType::Tile`.
> [!NOTE]
> Polygon colliders are generated using [convex_hull](https://docs.rs/avian2d/0.2.0/avian2d/collision/collider/struct.Collider.html#method.convex_hull). Eventually some method of distinguishing how to generate colliders can be used.
---
## Features
- Parse Group, Tile, and Object layers, Tile and object properties.
- Loads the scene into Bevy.
- Generate Tiled Colliders as [bevy_rapier2d](https://docs.rs/bevy_rapier2d/latest/bevy_rapier2d/geometry/struct.Collider.html) or [avian2d](https://docs.rs/avian2d/0.2.0/avian2d/collision/collider/struct.Collider.html) Colliders.
## Documentation
- [Bevy Plugin documentation](DOCS_URL)
- [Parser documentation](DOCS_URL)
## Bevy Usage Example
Add `bevy_tiled_loader` to `Cargo.toml`:
```toml
# For 2D applications:
[dependencies]
bevy_tiled_loader = {version = "*", features = "avian2d_colliders"} # You should explicitly set the version.
```
Add the plugin and load a `*.tmx`:
```rust
app.add_plugins(
TiledScenePlugin
)
// ...
fn spawn_tiled_scene(mut commands: Commands, asset_server: Res<AssetServer>) {
let tiled_map_handle: Handle<TiledMapAsset> = asset_server.load("my_first_tiled_map.tmx");
commands.spawn(
BufferedMapScene(tiled_map_handle)
);
}
fn reading_tiled_properties_example(
tiled_map_assets: Res<Assets<TiledMapAsset>>,
query_scenes: Query<(Entity, &TiledMapScene), Added<SceneRoot>>,
children: Query<&Children>,
query_tiled_id: Query<&TiledId>,
) {
query_scenes.iter().for_each(|(entity, TiledMapScene(tiled_map_handle))| {
let Some(tma) = tiled_map_assets.get(tiled_map_handle) else {return};
children
.iter_descendants(entity)
.filter_map(|child_e| query_tiled_id.get(child_e).ok().map(|tile_id| (child_e, tile_id)))
.for_each(|(child_e, tile_id)| {
match tile_id {
TiledId::Object(o_id) => {
// For Tile objects `ObjectType::Tile`, you may also want to include the properties placed on
// the tile itself with the object's properties, done like so :
let object = tma.map.get_scene_object(*o_id).unwrap();
object.properties.iter().chain(
try_match::match_ok!(object.otype, ObjectType::Tile(t_guid))
.and_then(|t_guid| tma.map.get_tile_properties(t_guid))
.iter()
.flat_map(|hm| hm.iter()),
)
}
.for_each(|(k, v)| match k.as_str() {
"my_property" => todo!(),
_ => println!("Un-implemented object property : {}", k),
}),
TiledId::Layer(_) => todo!(),
TiledId::Tile(_) => todo!(),
}
})
})
}
```
Also, see [load_tiled_components](https://github.com/CMorrison82z/tiled_import/blob/master/crates/bevy_tiled_loader/examples/load_tiled_components.rs) which shows how to extract properties from Tiled objects.
# 
## Supported Bevy Versions
| 0.15 | 0.1 |
## Future Features
- Settings to control how the `*.tmx` is parsed and how / what gets generated.
## Contributing
If you encounter any problems, feel free to open issues or create pull requests.
## Acknowledgements
Bevy is awesome.