GithubHelp home page GithubHelp logo

bevy_tiled's Introduction

bevy_tiled

Welcome to bevy_tiled!

This is a plugin for rendering tiled maps. Specfically, maps from the "Tiled" editor which can be found here:

https://www.mapeditor.org/

Feel free to use this code as a reference for your own custom tile mapping solution as well.

Bevy Versions

The main branch of this repository targets Bevy 0.5. When using bevy_tiled, please make sure your version of Bevy matches the version referenced by this library. There are versions for 0.4 and 0.3 as well.

If you were using framp's fork for Bevy 0.4, it is currently merged in and mirrored by the v0.1.0-bevy-0.4 release. For a few more bugfixes, you can point to the v0.1.1-bevy-0.4 tag. Object support in Bevy 0.4 is usable, and is an open PR, targetting the bevy-0.4 branch and published as the v0.2.1-rc1-bevy-0.4 tag.

For those of you relying on the old bevy_tiled, you will want to point your Cargo.toml to the bevy-0.3 branch or the v0.1.0-bevy-0.3 tag. There is a small fix there for map positioning, and it is otherwise unchanged.

Basic Setup

Follow the Rust Getting Started and make sure you have rustc compiler and cargo build system available on yor machine.

Clone this repo and try running some of the examples:

# Runs the orthographic tile map example
cargo run --example ortho_main
# Runs the isometric tile map example
cargo run --example iso_main

In these examples, you should be able to use the wasd keys to pan across the maps. You can follow a similar pattern in your own Bevy project. For more information, follow the [Bevy Setup] guide.

Features

Toplevel Entity Support

For now, TiledMapBundle is just a configuration object. If you would like access to a toplevel entity that can be transformed, pass into the configuration:

parent_option: Some(entity)

Then, both chunks and objects will be inserted as children to this entity, which will be tagged with MapRoot. This API is likely to change, but we have an example for how it currently works.

Object Group Support

Object Grous are now supported. They will be skipped if not visible. Individual objects that are invisible will be spawned with is_visible set to false. You may pass into the configuration object:

debug_config: DebugConfig { enabled: true, material: None }

to show a color mesh for objects that have no tile sprite. material: None will use the default material. This is only supported for rects at this time. Some other objects will show up as small squares until we improve support.

To see objects and debugging in action, run the ortho_debug example which will enable debug viewing of objects. Use the spacebar to toggle objects.

# Runs the debug/objects example
cargo run --example ortho_debug

Events

There are two events that you can listen for when you spawn a map.

  • ObjectReadyEvent fires when an object has been spawned.
  • MapReadyEvent fires when all objects and layers have been spawned.

These both have: pub map_entity_option: Option, pub map_handle: Handle,

and ObjectReadyEvent additionally includes entity: Entity for what the object was spawned as.

Hot reload

Limited support for hot reload is provided. Old entities are removed based on the asset handles (for now).

asset_server.watch_for_changes().expect("watch for changes failed");

Then when you save your map, it should update in the application.

WASM and bevy_webgl2

Use default-features=false, features=["web"] in your project's Cargo.toml. Tiled maps using Zstd compression are not supported.

Top-needed features

  • better support for isometric maps
  • support for embeded objects in tiles
  • support for embedded images in Tmx files
  • support for animations

bevy_tiled's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

bevy_tiled's Issues

Individual Meshes

Currently, each chunk uses its own mesh. Could this be optimized? Depending on Orientation the mesh stays the same. Right now the position is also encoded in the mesh itself, this seems rather wasteful in terms of memory transfer+usage to me.

Is there a way to reuse parts of this across chunks, and decouple the offset from the mesh itself? (Related to #3?)

Support for animated tiles and collision

Hi all,

I'm looking into adding support for animated tiles and collision support and I'm curious to see if anyone has already spent some time thinking / working on this before I do

For reference, I've used this library in the past which implements the same functionality (but in JS): https://github.com/colinvella/phaser-tilemap-plus

There may be some work needed in tiled-rs to support object layers and animated tiles

My general idea is to:

  • Expose the object layer so that you can plug that data manually in your collision detector system
  • Copy bevy spritesheet approach for animations

Update for bevy 0.4

Bevy 0.4 was released a few days ago, and seems this library doesn't work with it because of the hard dependency on 0.3

error: failed to select a version for `shaderc-sys`.
    ... required by package `shaderc v0.6.3`
    ... which is depended on by `bevy_render v0.3.0`
    ... which is depended on by `bevy v0.3.0`
    ... which is depended on by `bevy_tiled_prototype v0.1.0 (https://github.com/StarArawn/bevy_tiled.git?branch=master#1506b554)`
    ... which is depended on by `shadows-rs v0.1.0 (C:\dev\shadows-rs)`
versions that meet the requirements `^0.6.3` are: 0.6.3

the package `shaderc-sys` links to the native library `shaderc`, but it conflicts with a previous package which links to `shaderc` as well:
package `shaderc-sys v0.7.0`
    ... which is depended on by `shaderc v0.7.0`
    ... which is depended on by `bevy_render v0.4.0 (https://github.com/bevyengine/bevy?branch=master#3b2c6ce4)`
    ... which is depended on by `bevy_gltf v0.4.0 (https://github.com/bevyengine/bevy?branch=master#3b2c6ce4)`
    ... which is depended on by `bevy_internal v0.4.0 (https://github.com/bevyengine/bevy?branch=master#3b2c6ce4)`
    ... which is depended on by `bevy v0.4.0 (https://github.com/bevyengine/bevy?branch=master#3b2c6ce4)`
    ... which is depended on by `shadows-rs v0.1.0 (C:\dev\shadows-rs)`

Consider using a different component than `bool` for `TiledMapComponents`

Currently TiledMapComponents has a bool component. Since this is a very generic type it could be used by other libraries as well thus potentially overwriting or misreading this component. I think something like TileMapCenterer(bool) would make it clear for what its used and not clash with other libraries.

Missing object fields

In my tower defense game, I'm using objects in a hidden object layer in a few ways:

  • To define PolyLines that enemies will follow
  • To define properties for waves of enemies that will spawn
  • To define the location and size of the "home base" health bar
  • To define the locations on the map where the player may build a tower (and some associated properties)

I am using Tiled's "Object Types" to create templates for the properties of these objects.

image

Right now, I am using map.map.object_groups to access the tiled::Object because bevy_prototype_tiled::Object doesn't contain data about the object's type or size.

I need "type" so that I can differentiate these objects when iterating over all of them, and seemingly the size in order to properly position the tower slots.

https://github.com/rparrett/bevy_tiled/commit/70786579d54a2f3f8a90e21b803822077e320a62 is a change set that adds what I currently need.

I think this is technically a breaking change, so some discussion might be warranted.

The differences that currently exist between tiled::Object and bevy_prototype_tiled::Object seem sort of arbitrary. Should we add the rest of the missing stuff? Is it correct to use the provided map.map? Should we add object.object?

In the change set above I just added the minimum for my application and attempted to match the style of bevy_prototype_tiled.

Support Image Collection-based Tilesets

Currently we only support tilemaps that use a single image, but Tiled supports tilesets with multiple images used in one tileset.

It would be nice to support both, especially for sprite objects, which can often be various sizes.

winit error: Please select a feature to build for unix: `x11`, `wayland`

Building the repository as of 5e802b8, dependency winit v0.24.0 requires Cargo.toml configuration to select a feature to build for unix: x11, wayland. I've tried adding that configuration to Cargo.toml without success. Can the README.md be updated to provide guidance on the syntax for doing this, and the feature defaults updated to enable the x11 option?

cargo run --example ortho_main
   ...
   Compiling winit v0.24.0
   Compiling chrono v0.4.19
error: Please select a feature to build for unix: `x11`, `wayland`
  --> /home/myuser/.cargo/registry/src/github.com-1ecc6299db9ec823/winit-0.24.0/src/platform_impl/linux/mod.rs:10:1
   |
10 | compile_error!("Please select a feature to build for unix: `x11`, `wayland`");
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error[E0392]: parameter `T` is never used
  --> /home/myuser/.cargo/registry/src/github.com-1ecc6299db9ec823/winit-0.24.0/src/event_loop.rs:32:22
   |
32 | pub struct EventLoop<T: 'static> {
   |                      ^ unused parameter
   |
   = help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`
   = help: if you intended `T` to be a const parameter, use `const T: usize` instead

error[E0392]: parameter `T` is never used
  --> /home/myuser/.cargo/registry/src/github.com-1ecc6299db9ec823/winit-0.24.0/src/event_loop.rs:43:34
   |
43 | pub struct EventLoopWindowTarget<T: 'static> {
   |                                  ^ unused parameter
   |
   = help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`
   = help: if you intended `T` to be a const parameter, use `const T: usize` instead

error[E0392]: parameter `T` is never used
   --> /home/myuser/.cargo/registry/src/github.com-1ecc6299db9ec823/winit-0.24.0/src/event_loop.rs:196:27
    |
196 | pub struct EventLoopProxy<T: 'static> {
    |                           ^ unused parameter
    |
    = help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`
    = help: if you intended `T` to be a const parameter, use `const T: usize` instead

error[E0392]: parameter `T` is never used
   --> /home/myuser/.cargo/registry/src/github.com-1ecc6299db9ec823/winit-0.24.0/src/platform_impl/linux/mod.rs:532:20
    |
532 | pub enum EventLoop<T: 'static> {
    |                    ^ unused parameter
    |
    = help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`
    = help: if you intended `T` to be a const parameter, use `const T: usize` instead

error[E0392]: parameter `T` is never used
   --> /home/myuser/.cargo/registry/src/github.com-1ecc6299db9ec823/winit-0.24.0/src/platform_impl/linux/mod.rs:539:25
    |
539 | pub enum EventLoopProxy<T: 'static> {
    |                         ^ unused parameter
    |
    = help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`
    = help: if you intended `T` to be a const parameter, use `const T: usize` instead

error[E0392]: parameter `T` is never used
   --> /home/myuser/.cargo/registry/src/github.com-1ecc6299db9ec823/winit-0.24.0/src/platform_impl/linux/mod.rs:666:32
    |
666 | pub enum EventLoopWindowTarget<T> {
    |                                ^ unused parameter
    |
    = help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`
    = help: if you intended `T` to be a const parameter, use `const T: usize` instead

For more information about this error, try `rustc --explain E0392`.
error: could not compile `winit` due to 7 previous errors
warning: build failed, waiting for other jobs to finish...
error: build failed

wasm builds fail on get_root_path

Since eb124a3

error[E0599]: no function or associated item named `get_root_path` found for struct `WasmAssetIo` in the current scope
  --> /Users/robparrett/.cargo/git/checkouts/bevy_tiled-85a429c236b45725/d997e92/src/map.rs:61:44
   |
61 |         let root_dir = asset::WasmAssetIo::get_root_path();
   |                                            ^^^^^^^^^^^^^ function or associated item not found in `WasmAssetIo`

Things are generally working very well prior to this commit.

Tile alpha channel

Please pardon my naivety if this is already an issue that is being looked at. I've just been having a play with this and basically my tiles aren't picking up the alpha channel (please see below - when I walk behind the tree or any tile for that matter - there's not alpha). I've tried reordering my layers in tiled and double checked TRANS is not set on the image and the tilemap image is definitely a .png with alpha set. It's got me totally baffled. Thanks in advance and again please forgive me - but I'm new to rust and bevy.

image

"Index out of bounds" when TMX data is missing newlines

Hello,

bevy_tiled crashes with Index out of bounds when a TMX's data (CSV) is missing new-lines. I used ldtk's TMX export to create my TMX file. Here's a small file to reproduce the issue:

<map version="1.4" tiledversion="1.4.2" orientation="orthogonal" renderorder="right-down" compressionlevel="0" width="4" height="4" tilewidth="32" tileheight="32" infinite="0" backgroundcolor="#696A79" nextlayerid="2" nextobjectid="1">
<tileset firstgid="1" name="Mountain_landscape" tilewidth="32" tileheight="32" tilecount="256" columns="16" objectalignment="topleft" margin="0" spacing="0">
    <image source="../../mountain_landscape.png" width="512" height="512"/>
</tileset>
<layer id="1" name="Ground" width="4" height="4" opacity="1">
    <data encoding="csv">
236,236,236,236,252,252,252,252,236,96,79,80,252,95,95,79
    </data>
</layer>
</map>

It works if I change data node to this:

    <data encoding="csv">
236,236,236,236,
252,252,252,252,
236,96,79,80,
252,95,95,79
    </data>

Here's how I use bevy_tiled

commands.spawn_bundle(bevy_tiled_prototype::TiledMapBundle {
      map_asset: assets.load("map/stuff/tiled/Arena01.tmx"),
      center: TiledMapCenter(true),
      origin: Transform::from_scale(Vec3::new(1.0, 1.0, 1.0)),
        ..Default::default()
});

Here's the error:
thread 'IO Task Pool (0)' panicked at 'index out of bounds: the len is 1 but the index is 1', /*/github.com-1ecc6299db9ec823/bevy_tiled_prototype-0.2.3/src/map.rs:186:46

It works if I break the lines manually or first import my TMX into Tiled editor and then save.

Individual Tiles

Is it possible to update the tilemap at run time? For example, changing a land tile to a water tile? If so, how do I get the individual tiles via a system or event? I've tried adding the entity to resources at the point of creation of the TiledMapComponents, but I'm unsure which struct I should be looking for. Is it the tiled::Map struct?

I'd really appreciate any help.

Update to bevy 0.3

Hey there,

bevy_tiled is incompatible with bevy 0.3, most notably because of changes in the Asset Loading API.

I'm working on a fix to get this crate to compile with the new version, should not be too much of a problem right ?

Scales other than 4x?

Hello!

I really, really, really want to use this library, but it seems to be hard-coded to a 4x scale? Is there really no way to change that...? I want something more like 1x or 2x for my project, and it seems like a very strange omission...

iso example broken with rs-tiled upgrade v0.9.3

I got this error when building my project:

error[E0608]: cannot index into a value of type `LayerData`
  --> /Users/qb/.cargo/git/checkouts/bevy_tiled-85a429c236b45725/872e31a/src/loader.rs:81:52
   |
81 | ...                   let map_tile = layer.tiles[lookup_y][lookup_x];
   |                                      ^^^^^^^^^^^^^^^^^^^^^

bevy_tiled code is here: https://github.com/StarArawn/bevy_tiled/blob/master/src/loader.rs#L81

I suspect this change: mapeditor/rs-tiled@8366cf8#diff-b4aea3e418ccdb71239b96952d9cddb6L669-R672

rs-tiled was upgraded to version 0.9.3 a few hours ago.

bevy tiled must declare indice types

Due to this commit: bevyengine/bevy@f7c8882

Bevy enforces the need to declare what kind of indices you're using, either U32 or U16

It results in this error when using the current master of bevy:

C:\ProjectFiles\bevy_tiled>cargo run --example iso_main
   Compiling bevy_tiled v0.1.0 (C:\ProjectFiles\bevy_tiled)
error[E0433]: failed to resolve: use of undeclared type or module `Indices`
   --> src\loader.rs:264:47
    |
264 | ...                   indices: Some(Indices::U32(indices)),
    |                                     ^^^^^^^ not found in this scope
    |
help: consider importing this enum
    |
1   | use crate::shape::Indices;
    |

Changin rendered maps

Hi!

I'm using this plugin to make a game and I'm trying to be able to change from main menu to a map, and from the map to another map.

My idea was to load a default instance of TiledMapComponents at startup, and then use a system where I query the componetn with:
mut tiled_map: Query<&mut TiledMapComponents>,

and make something like:

            for mut c in tiled_map.iter_mut() {
                println!("Showing map...");
                c.map_asset = asset_server.load(map_path.as_str()); // here we load the new map
                c.center = TiledMapCenter::default(); // This centers the map view again, I guess?
            }

The problem is that I don't know why the query comes empty, when it should have the only TiledMapComponents component that was spawned at startup, so I can't make any changes on rendered map.

Also, if I try to commands.despawn, or despawn_recursive, the game crashes at:
(line 454 of maps.rs file.

let map = maps.get_mut(changed_map).unwrap();

Any idea what could be happening?

Z Blending with other pipelines

I noticed an issue when adding a bevy sprite sheet. There is something odd occurring where the frame buffer is not blending the components of different passes.

In the screen shot you'll notice that the two layers in the tile map are blended correctly but the sprite is ignored.

I've tried changing bevy upstream to use depth_compare: CompareFunction::LessEqual but that didn't seem to have any effect. It looks like the frame buffer is being overridden on the tile map draw pass.

master...wmiller848:sprite_blend_issue

depth_issue

Map scaling introduces artifacts

Running cargo run --example ortho_main and zooming out with Z, there is visible artifacts between tiles, as can be seen in attached video (Windows 10). Same issue is seen on macOS.

Using git master from today (bevy 0.5)

The issue starts to show in the video about 4 seconds in.

bevy.2021-04-07.12-23-03.mp4

Adding some light documentation

I was trying to get through some of the code on how the map was processed and loaded, like in functions TiledMapLoader and process_loaded_tile_maps, but the code is a little dense and sparsely documented. I'd like to help contribute to this project, and having a little bit more info on how the main processes worked would be a great help.

Object support for Isometric maps

Orthographic map object support will be merge to the main branch, but isometric is not ready yet. Need help from someone who is making an isometric game to work on placement of sprite objects as well as transformation of rectangle (And other shape) objects in the isometric grid.

Incomplete path passed to tiled::parse_with_path

├── Cargo.toml
├── src/
│      └──  main.rs
├── assets/
│       ├── world.tmx
│       ├── tiles_world.tsx
│       └── tiles_world.png

For a project with the above file structure and where tiles_world.tsx is an external tileset used by world.tmx

when we try to run asset_server.load("working_map.tmx")

bevy_tiled/src/loader.rs

Lines 25 to 32 in 2af6208

fn load<'a>(
&'a self,
bytes: &'a [u8],
load_context: &'a mut LoadContext,
) -> BoxedFuture<'a, Result<(), anyhow::Error>> {
Box::pin(async move {
let path = load_context.path();
let mut map = Map::try_from_bytes(path, bytes.into())?;

load_context.path() returns the path relative to the assets folder (i.e. "world.tmx")

bevy_tiled/src/map.rs

Lines 53 to 54 in 2af6208

pub fn try_from_bytes(asset_path: &Path, bytes: Vec<u8>) -> Result<Map> {
let map = tiled::parse_with_path(BufReader::new(bytes.as_slice()), asset_path).unwrap();

this asset_path is then used in tiled::parse_with_path to resolve external tilesets which panics with

Other("External tileset file not found: \"tiles_world.tsx\"")

because it will try to look for "<execution path>/tiles_world.tsx" instead of "<execution path>/assets/tiles_world.tsx"

Hexagonal map support ?

The Tiled Map Editor supports the creation of hexagonal maps. Is it possible to load them ?
When I try to load a hexagonal map it is not displayed. Not sure if I am doing something wrong or if this feature is not supported yet.

Refactor entity setup.

Currently the map entity just loads the mesh and the spawns a bunch of chunk entities. Instead we should think about having the map entity stick around and contain a transform for moving the entire map around. The chunk entities can be children of the map entity.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.