Code Monkey home page Code Monkey logo

bevy_ecs_tilemap's People

Contributors

alice-i-cecile avatar antoinepaulinb7 avatar b-reif avatar bjorn avatar bzm3r avatar dauthdaert avatar devusercontact avatar divark avatar elabajaba avatar frederickjjoubert avatar inodentry avatar johanhelsing avatar johnthecoolingfan avatar martinmolin avatar mbolt35 avatar meomix avatar mrgvsv avatar mwbryant avatar noahshomette avatar perlindgren avatar piefayth avatar piturnah avatar rparrett avatar st0rmbtw avatar stararawn avatar tec27 avatar thebluefish avatar theleonsver1 avatar theseatoad avatar trouv avatar

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  avatar  avatar  avatar  avatar  avatar

bevy_ecs_tilemap's Issues

Add borders to default assets

This will make it easier for users to clearly understand the effects of changes to their code when experimenting with the examples.

Is there any easy method to get the map dimensions?

I've imported a iso map using Tiled and was trying to center the map but I would need the map dimensions for that.
Since I might use a lot of different maps and not always know its size it would be nice to have a method like .dimensions().
Is there any method like this available? If not I think it would be a nice simple feature.

Edit: I tried to get the asset from the Handle<TiledMap> but asset is usually not loaded and working with references to the TiledMapBundle is a bit tricky.

Question about accessing additional information from a map made with Tiled

Hello, I'd like to use your library with a map I made using Tiled. In Tiled I have added collision shapes to some of the tiles, they are stored as objects in an objectgroup on a tile in the tmx file in the following hierarchy:

<map ...>
  <tileset ...>
    ...
    <tile id="1">
      <objectgroup ...>
        <object ... />
      </objectgroup>
    </tile>
  </tileset>
</map>

I saw that you're using the tiled library when the tiled_map feature is enabled, the data structures in the tiled Rust library seem to map pretty directly to the XML in the tmx file so the hierarchy is similar. Given this, I had a couple of questions:

  1. Is there any way to access the data structures present in the tiled library following map creation?
  2. If not, is there a way you would recommend iterating over Tiles in the tilemap to attach additional bundles to them? I thought something like the below may work, based loosely on the accessing_tiles example, however I wanted to ask the question in case there is a better/simpler way to achieve the same result:
const TILE_HEIGHT: f32 = 16.;
const TILE_WIDTH: f32 = 16.;

fn add_collision_to_tiles(
  mut query: Query<(Entity, &mut Tile, &UVec2)>
) {
  // use `tiled` library to parse original map file
  let tiled_info = tiled::parse(...);
  // iterate over tiles in map at startup and add collision information
  for (entity, mut tile, position) in query.iter_mut() {
    ... // add ColliderBundle and RigidBodyBundle to entity
  }
}

Where ColliderBundle and RigidBodyBundle are from bevy_rapier2d.

ldtk tilemap src vs t field

The ldtk tilemap texture index code uses the src field to calculate the tilemap index based on the pixel dimensions. There seems to be a bug in the current implementation that offsets the index by 1 for the first row, and 2 for every row after that in the tilemap.

Here's an image showing the current behavior:

Screen Shot 2021-08-24 at 1 00 22 PM

There seems to be an index for the tilemap in the t field in the same struct. Changing the above code to access the t field instead results in the following, seemingly correct output for the tilemap.

layer_builder.set_tile(
    pos,
    Tile {
        texture_index: tile.t as u16,
        ..Default::default()
    }.into()
).unwrap();

image

I don't know enough about tdlk to know if this is correct, but it seemed useful to file an issue for

Remove editor specific code in favor of including them as basic examples.

I've had a lot of people ask me very similar questions along the lines of:

How can I access tiled/ldtk data on load.

I don't mind answering those questions, but I don't think bevy_ecs_tilemap should support things like:

  • Collisions
  • Tiled map editor objects
  • Backgrounds
  • Non tile map stuff.

Which makes me think that the ldtk/tiled features should be removed in favor of using clearly defined examples.

Why examples?

  1. Less complexity. Tiled/LDTK are level editors and as such they provide a lot more data specific to the game you are making. As such its almost impossible to support all the different ways people will use loaded data.
  2. The code for the tiled/ltdk loaders are very small. Moving them into well documented example files allows users to learn how that data is loaded in and how to create the tile maps using bevy_ecs_tilemap.
  3. If I support collisions for example it locks bevy_ecs_tilemap into a collision library. I would like to avoid that at all costs.

I want to reach out to the community first before I go ahead and make this change. Anyone who wants to voice any concerns/comments feel free!

Reference issues:
#82
#80
#21

Map.build panicking at runtime 'attempt to create unaligned or null slice'

I've just started learning rust, so sorry in advance if my explanation is not too helpful. I am running into an issue when adopting or running your examples.

`
cargo run --release --example iso
Finished release [optimized] target(s) in 0.37s
Running "/tmp/bevy_ecs_tilemap/target/release/examples/iso"

[2021-05-02T14:50:04Z WARN gfx_backend_vulkan] Skipping memory type with unknown flags DEVICE_LOCAL | DEVICE_COHERENT_AMD | DEVICE_UNCACHED_AMD
[2021-05-02T14:50:04Z WARN gfx_backend_vulkan] Skipping memory type with unknown flags HOST_VISIBLE | HOST_COHERENT | DEVICE_COHERENT_AMD | DEVICE_UNCACHED_AMD
[2021-05-02T14:50:04Z WARN gfx_backend_vulkan] Skipping memory type with unknown flags DEVICE_LOCAL | HOST_VISIBLE | HOST_COHERENT | DEVICE_COHERENT_AMD | DEVICE_UNCACHED_AMD
[2021-05-02T14:50:04Z WARN gfx_backend_vulkan] Skipping memory type with unknown flags HOST_VISIBLE | HOST_COHERENT | HOST_CACHED | DEVICE_COHERENT_AMD | DEVICE_UNCACHED_AMD
[2021-05-02T14:50:04Z INFO winit::platform_impl::platform::x11::window] Guessed window scale factor: 1
[2021-05-02T14:50:04Z INFO bevy_ecs_tilemap::chunk] Re-meshing chunk at: MapVec2 { x: 0, y: 0 } layer id of: 0
[2021-05-02T14:50:04Z INFO bevy_ecs_tilemap::chunk] Re-meshing chunk at: MapVec2 { x: 0, y: 1 } layer id of: 0
[2021-05-02T14:50:04Z INFO bevy_ecs_tilemap::chunk] Re-meshing chunk at: MapVec2 { x: 1, y: 0 } layer id of: 0
[2021-05-02T14:50:04Z INFO bevy_ecs_tilemap::chunk] Re-meshing chunk at: MapVec2 { x: 1, y: 1 } layer id of: 0
[2021-05-02T14:50:04Z INFO bevy_ecs_tilemap::chunk] Re-meshing chunk at: MapVec2 { x: 1, y: 1 } layer id of: 1
[2021-05-02T14:50:04Z INFO bevy_ecs_tilemap::chunk] Re-meshing chunk at: MapVec2 { x: 1, y: 0 } layer id of: 1
[2021-05-02T14:50:04Z INFO bevy_ecs_tilemap::chunk] Re-meshing chunk at: MapVec2 { x: 0, y: 0 } layer id of: 1
[2021-05-02T14:50:04Z INFO bevy_ecs_tilemap::chunk] Re-meshing chunk at: MapVec2 { x: 0, y: 1 } layer id of: 1
[2021-05-02T14:50:04Z INFO bevy_ecs_tilemap::chunk] Re-meshing chunk at: MapVec2 { x: 1, y: 0 } layer id of: 2
[2021-05-02T14:50:04Z INFO bevy_ecs_tilemap::chunk] Re-meshing chunk at: MapVec2 { x: 0, y: 1 } layer id of: 2
[2021-05-02T14:50:04Z INFO bevy_ecs_tilemap::chunk] Re-meshing chunk at: MapVec2 { x: 0, y: 0 } layer id of: 2
[2021-05-02T14:50:04Z INFO bevy_ecs_tilemap::chunk] Re-meshing chunk at: MapVec2 { x: 1, y: 1 } layer id of: 2
thread 'main' panicked at 'attempt to create unaligned or null slice', /usr/lib/rust/1.51.0/lib/rustlib/src/rust/library/core/src/slice/raw.rs:90:5
note: run with RUST_BACKTRACE=1 environment variable to display a backtrace
Segmentation fault
`

This happens with Rust 1.51.0 (no nightly) and line map.build(&mut commands, &mut meshes, material_handle.clone(), map_entity, true); seems to be the offending line.

That is as far as my Rust debugging skills go at the moment though. Any idea what might be the issue here?

MapTileError doesn't impl Error

I tried using ? to return from a function that returns an anyhow::Result<()> but it couldn't convert the Result because Error is not implemented.

Is there a way to use TextureAtlas?

I am trying to use this lib but I could not find a way to set my TextureAtlasHandler with my textures in it. Is it possible?
[edit]
I found that the Tile has a property for texture_index but could not find any property to set the atlas.

/// The texture index in the atlas or array.
    pub texture_index: u16,

Tilemap fails to render all chunks when given a negative transform

If you give the tilemap a negative transform, it seems to fail to render anymore chunks at some point (near the transition from negative to positive?).

The screenshot below shows tiles rendering out to roughly 1000px or so on the x-axis, when the code should be generating over 8000px of tiles.

Screenshot:
image

Here is a code sample to demonstrate.

use bevy::prelude::*;
use bevy_ecs_tilemap::prelude::*;

// With a world size of 8 chunks, a chunk size of 64 tiles, and a tile size of 16 pixels,
// we should get a tilemap of 8,192 pixels wide and high. Much larger than the default
// window size of 1280, 720.
const WORLD_CHUNK_SIZE: u32 = 8;
const CHUNK_TILE_SIZE: u32 = 64;

// Code is otherwise identical to examples/map.rs for simplicity's sake.
fn startup(
    mut commands: Commands,
    asset_server: Res<AssetServer>,
    windows: Res<Windows>,
    mut meshes: ResMut<Assets<Mesh>>,
    mut materials: ResMut<Assets<ColorMaterial>>,
) {
    let window = windows.get_primary().unwrap();
    let window_width = window.width();
    let window_height = window.height();

    commands.spawn_bundle(OrthographicCameraBundle::new_2d());

    let texture_handle = asset_server.load("tiles.png");
    let material_handle = materials.add(ColorMaterial::texture(texture_handle));

    let mut map = Map::new(MapSettings::new(
        UVec2::new(WORLD_CHUNK_SIZE, WORLD_CHUNK_SIZE),
        UVec2::new(CHUNK_TILE_SIZE, CHUNK_TILE_SIZE),
        Vec2::new(16.0, 16.0),
        Vec2::new(96.0, 256.0),
        0,
    ));

    let map_entity = commands.spawn().id();
    map.build(
        &mut commands,
        &mut meshes,
        material_handle,
        map_entity,
        true,
    );

    // Set up the origin point of the tilemap to be the bottom-left
    // corner of the camera, such that it _should_ fill the entire viewport and more.
    // Adding a 5 pixel offset to show that it isn't rendering off the left/bottom
    // of the camera. 
    let origin_x = -(window_width / 2.0) + 5.0;
    let origin_y = -(window_height / 2.0) + 5.0;
    commands.entity(map_entity).insert_bundle(MapBundle {
        map,
        transform: Transform::from_xyz(origin_x, origin_y, 0.0),
        ..Default::default()
    });
}

fn main() {
    App::build()
        .add_plugins(DefaultPlugins)
        .add_plugin(TilemapPlugin)
        .add_startup_system(startup.system())
        .run();
}

Use two generics in MapQuery API

Many methods on MapQuery expose a generic, which must impl Into<u16>.

This is a great pattern, to allow people to use smarter, clearer types rather than passing around magical u16 values for the map and layer. However, the standard use of this (or at least, how I want to use it!) is to implement two enums (or other data types): one for the map, and one for the layer. However the generic type used must be the same in both instances, causing this pattern to create a compile error.

Swapping to two seperate generic types with the same bounds will resolve this problem.

Add height tiles to isometric example

The isometric example only allows for flat tiles at the moment. I have a fix ready for the renderer but am still working on placing the correct tiles. For this I have to look into how the tile atlas works so I can place the correct adjacent tiles. This may make the example a lot more complicated.

Issue with ldtk map size

After loading an ldtk map, requesting a layer size outputs the wrong value. For example, in a map of size 15x8, the following line:
println!("Layer size is {}", layer.settings.map_size);
Outputs:
Layer size is [1, 1]
I'd say the problem has to do with lines 137 and 138 in ldtk.rs, where the map size is divided unnecessarily.

Skipped tile texture

I had this working in 0.2.0 and it's broken in 0.3.0. I'm not sure if this is a bug or a problem with the way I'm using it. I have a 700px by 700px png that I'm cutting into 140px by 140px tiles and then manually inserting them into the map. When doing so, the tile I'm expecting at texture_index 4 is missing and replaced with the tile from texture_index 5. This happens with every fifth tile, so instead of getting 25 tiles, I only have 20.

Screen Shot 2021-05-06 at 7 14 42 AM

fn setup(
    mut commands: Commands,
    mut materials: ResMut<Assets<ColorMaterial>>,
    mut meshes: ResMut<Assets<Mesh>>,
    assets: Res<AssetServer>,
) {
    commands.spawn_bundle(OrthographicCameraBundle::new_2d());

    let map = assets.load("maps/5x5.jpg");
    let map_material = materials.add(map.into());

    let tile_map_entity = commands.spawn().id();

    let tile_map_settings = MapSettings::new(
        UVec2::new(5, 5), 
        UVec2::new(1, 1), 
        Vec2::new(140., 140.), 
        Vec2::new(700., 700.), 
        0
    );

    let mut tile_map = Map::new(tile_map_settings);
    tile_map.build(
        &mut commands,
        &mut meshes,
        map_material,
        tile_map_entity,
        false,
    );

    let _  = tile_map.add_tile(&mut commands, UVec2::new(0, 4), Tile { texture_index: 0, ..Default::default() }, true);
    let _  = tile_map.add_tile(&mut commands, UVec2::new(1, 4), Tile { texture_index: 1, ..Default::default() }, true);
    let _  = tile_map.add_tile(&mut commands, UVec2::new(2, 4), Tile { texture_index: 2, ..Default::default() }, true);
    let _  = tile_map.add_tile(&mut commands, UVec2::new(3, 4), Tile { texture_index: 3, ..Default::default() }, true);
    let _e  = tile_map.add_tile(&mut commands, UVec2::new(4, 4), Tile { texture_index: 4, ..Default::default() }, true);

    commands.entity(tile_map_entity).insert_bundle(MapBundle {
        map: tile_map,
        ..Default::default()
    });
}

Improve clarity of LayerBuilder initialization

Initializing LayerSettings with the new method is not very explicit or type safe, and map_id and layer_id types use unclear types.

New users will see

        LayerSettings::new(
            UVec2::new(2, 2),
            UVec2::new(8, 8),
            Vec2::new(16.0, 16.0),
            Vec2::new(96.0, 256.0),
        ),

in https://github.com/StarArawn/bevy_ecs_tilemap/blob/main/examples/map.rs and be at a loss for what the magic numbers do.

There are a few possible improvements that immediately come to mind:

  1. Use intermediate variable names (or constants) in the examples.
  2. Use wrapper types for map_size etc.
  3. Use explicit struct construction. Probably not possible if other invariants must be upheld (and many fields are omitted).
  4. Use the builder pattern (probably too verbose and frustrating).
  5. Consistently use custom enums for map and layer ids that impl Into<u16> to increase clarity and safety.

Map settings reusability improvement suggestion

Currently Map isn't Clone (and I don't think it should be, or at least not for this issue's purposes)
and Map::new() currently takes:

size,
chunk_size,
tile_size,
texture_size,
(layer_id isn't relevant to this issue)

My suggestion would be to create a MapSettings struct that is Clone/Copy:

///The settings for tilemap layers
#[derive(Debug, Clone, Copy)]
pub struct MapSettings {
    pub map_size: MapVec2,
    pub chunk_size: MapVec2,
    pub tile_size: Vec2,
    pub texture_size: Vec2,
}

To enable making similar maps with the same settings more convenient(for example if you need layers with the same settings). The current impl kind of forces the user to create functions to reduce boilerplate which I think should be avoided)

This also enables storing these structs as/in resources for reusability
Map::new() would then take MapSettings instead of the 4 different values

*I don't mean you need to actually store this inside of Map instead of the current configuration.
you can and maybe should keep Map as is and only change Map::new() to make it more convenient for users. I'm not sure.. it might be nice to copy the settings of a Map if it's possible, idk if there'd be uses for that, maybe for bevy_tiled maps..?

Layout of hex tiles is inaccurate, with error accumulating

While working on a tile-coordinates-from-mouse-click utility, @plof27 and I noticed that coordinates of the hex tiles become progressively more inaccurate the farther from the origin you get. You can see the utility function we used for conversions at the link.

We noticed this using a point-up, Hextype::Row layout. It works perfectly for x, but gets progressively worse on the y-axis as you get further from the origin. I suspect this is a layout bug as a result; particularly as it was still an issue using an alternate pixel-based renderer.

Headless mode (for multiplayer)

Hello,

First of all thanks for this great plugin. I was thinking of using it for a multiplayer game in combination with the Tiled support that you recently added. One prerequisite for this is that the plugin should work in headless mode (i.e., without all the graphical plugins). I was wondering whether that's something that you envisioned / considered, and/or if you think this belongs elsewhere.

I like the idea of having a Tile Component in the ECS framework, and I can use it to attach some game logic on it. For multiplayer, the authorative node / server (depending on the terminology you use :) ) should be able to simulate the game (headless). So basically all the infrastructure of loading from a Tiled file + the ECS infrastructure that this crate provides is very useful, however because it links directly with the rendering, headless won't work. Specifically, this is the error I get when I don't load in the default bevy plugins in combination with this plugin:

thread 'main' panicked at 'resource does not exist: bevy_asset::assets::Assets<bevy_render::pipeline::pipeline::PipelineDescriptor>', /home/mfiers/.cargo/registry/src/github.com-1ecc6299db9ec823/bevy_ecs-0.5.0/src/world/mod.rs:674:32

Which is to be expected. The way I solved this in my game prototype was to fully split logic from rendering into two separate plugins - which seems to be a good practice in game development anyways. The headless node only needs to run the logic plugin, whereas the client runs both logic + rendering plugins. (the rendering plugin then has a system that extends all entities and attaches the necessary sprites/texture components onto all entities that don't have one yet).

I'm curious to hear your thoughts about this! Let me know if this discussion/issue belongs in the right place here as a github issue.

Load entities from ldtk

Currently I am implementing custom logic to load entities from ldtk. I am going to try adding this generically in my fork.

Unable to use ldtk

the package bevy_play depends on bevy_ecs_tilemap, with features: ldtk but bevy_ecs_tilemap does not have these features.

[package]
name = "bevy_play"
version = "0.1.0"
edition = "2018"


[dependencies]
bevy = { version = "0.5"}
bevy_ecs_tilemap = {version = "0.4.0", features = ["ldtk"]}

Frame delay on tile updates when there are many tiles

There seems to be a delay on tiles getting updated, especially noticeable when the framerate is low.

Here's a screen recording of my test project showing it by having the same source data being rendered by bevy_ecs_tilemap and bevy_tilemap side by side. Bevy_ecs_tilemap is the one on the left. I've added a "slowdown" system that intentionally tanks the framerate down to about 8fps to make the delay noticeable, but I'm also seeing this in my actual game when running it in debug mode.

2021-05-13_15-36-39.mp4

As you can see here, bevy_ecs_tilemap is consistently lagging behind with a small but noticeable delay, and it also seems to skip updates when moving the cursor fast. (tiles seemingly updating 2 at a time on the left)

I wasn't able to reproduce this at all with just a single tile, so it seems to be dependent on the number of tiles being rendered as well.

Here's the code to the test project reproducing it.
Controls are WASD to move and update tile at the new position, X to switch sprite index.
bevy_ecs_tilemap_frame_delay_repro.zip

Maps that aren't square and a power of 2 create many empty entities

Having a chunk_size or a map_size that isn't both square and a power of 2 creates many empty entities.
Eg.

let layer_settings = LayerSettings::new(
    UVec2::new(1, 1),
    UVec2::new(4, 2),
    Vec2::new(16.0, 16.0),
    Vec2::new(96.0, 256.0),
);

will create 8 empty entities (I assume for padding), while

let layer_settings = LayerSettings::new(
    UVec2::new(1, 1),
    UVec2::new(4, 4),
    Vec2::new(16.0, 16.0),
    Vec2::new(96.0, 256.0),
);

will not create any empty entities.

I don't really care about the extra memory usage, but it makes the WorldInspectorPlugin from https://github.com/jakobhellermann/bevy-inspector-egui unusable on mid-large maps that aren't perfect power of 2 squares because it pollutes the inspector with a ton of garbage empty entities, and as far as I know you also can't filter them out using a query.

eg. I use .add_plugin(WorldInspectorPlugin::new().filter::<Without<Tile>>()) due to performance issues with huge lists of entities in bevy-inspector-egui, but due to the empty entities I'm left with a ton of entities I can't filter out without making maps bigger and/or non rectangular so they're all perfect power of 2 squares.

Detect texture size from assets

Setting the texture size manually (on a per-layer basis) is somewhat error-prone, and silently results in strange errors and aberrations if the user gets it wrong.

Ideally, this would be detected automatically based on the tile assets chosen (and the material handle passed in).

Tilemap does not render new tiles until an existing tile is updated

It seems like whenever a tile is added using map.add_tile() to a position that did not already have a tile, the new tile is not rendered until another .add_tile() is performed on a position that already contains a tile.

This can be worked around by simply calling .add_tile() with the exact same parameters twice in a row, but I assume this is not intentional.

TilePos and relatives should use usize, not u32

This is an important perf and usability optimization when interfacing with external arrays (which are always indexed by usize slices).

Currently, you must repeatedly waste operations performing this conversion and littering the code base with as usize.

LDTK, large map issue

When attempting to load maps that are larger than 512px in any dimensions the program returns a panic.
thread 'main' panicked at 'calledResult::unwrap()on anErrvalue: OutOfBounds', /home/kl/.cargo/git/checkouts/bevy_ecs_tilemap-8c720d5970222b21/2a60b2a/src/ldtk.rs:177:27 note: run withRUST_BACKTRACE=1environment variable to display a backtrace Segmentation fault (core dumped)
I have tried to see what is exactly wrong, but cant seem to figure it out.

Feature request: Aseprite v1.3 tile support

I've been working on updating the asefile crate to support Aseprite's Tilemap features. Ultimately, I'd like to have an asset pipeline for tiles directly from Aseprite into bevy_ecs_tilemap.

I'd be happy to contribute work on this as a feature flag to this library. Otherwise, I can make a separate crate.

Feature request: mouse-to-tile events

It would be nice to have mouse events translated to tiles. At the minimum, a helper function which takes mouse coordinates and returns a tile. However, even better, a system which:

  • Generates custom events for:
    • a tile was clicked (left/right/middle/other, optionally subposition)
    • hover-in
    • hover-out
    • maybe a mouse-drag event which gives a list of tiles from first (tile where the button was pressed down) + all the others passed over in order + last (tile where button was released)
    • maybe also mouse-down / mouse-up on a tile (not sure how useful that really is vs "click" outside of the drag case)
  • Provides a way to query:
    • last-clicked tile (or, list of tiles clicked since last query?)
    • currently-hovered tile
    • subposition within tile of last click (scaled to tile size in view)
    • subposition within tile of hover
    • maybe the latest mouse-drag list?

I'm not sure how -- or if at all -- this should interact with non-tile sprites or other UI elements. I can image cases where it'd be nice to at least know that a click is "obstructed" by an object which is above the map.

Not able to import isometric maps correctly.

I've tried to importing a tmx from Tiled where the map his 16x8 but with a tileset of 16x16 to give it a isometric look.
The problem is that bevy is rendering the tiles with 16px of height between them, maybe because the of tile dimensions idk :P.

Really like the project btw.

Pathfinding

Sorry if this is a noob question.

I was just researching about the best way to traverse the tiles using aStar algorithm. In the past I just kept the grid data in an array or hashmap, but now with the entity system, whats the best resource non intensive way to do this?

Missing chunks

After creating a tilemap, I only see one chunk rendering when I am expecting four chunks.

fn setup_tilemap(
    // -- snip --
) {
    // 2 chunks wide, 2 chunks tall. Expecting 4 chunks total.
    let map_size = UVec2::new(2, 2);

    // Each chunk is 16 tiles wide and 9 tiles tall.
    let chunk_size = UVec2::new(16, 9);

    let layer_settings = LayerSettings::new(
        map_size,
        chunk_size,
        Vec2::new(16., 16.),
        Vec2::new(192.0, 16.0),
    );
    // -- snip --
}

Ingame this only renders one 16x9 chunk:
image

Here is a gist with the complete tilemap setup function.

Let me know what other information I can provide.

Feature: Map loader

Would it make sense to make a generic map loader trait and implement for example the loading of Tiled maps similar to your other repo bevy_tiled?

Hide entire layer

I'm working on a dwarf fortress style map with multiple z-level used to represent a 3rd dimension while keeping everything 2d.

Currently, I'm using a different layer for each z_level. When I want to change the current z_level I simply hide any layers above the current one. My problem is that, to do this I have to set every tile in each layer to be not visible. I know there's a despawn_layer (technically, depsawn_layer ๐Ÿ˜‰), but when I used it I couldn't figure out how to rebuild a layer at run time and I also don't think I should do that any way.

Essentially, what I want is a way to set an entire layer to not visible without having to loop on every tile.

Also, what's the best place to ask a question about this crate? Should I just ask in the bevy discord channel?

Future: advanced isometric view

Unlike in a top-down or side view game, In many (most?) isometric games, objects represented by a tile may be taller than the actual tile space. (Like, a tree or a wall.)

From chat:

StarToaster

I have given some thought on how to achieve that. A couple of steps need to happen for that to work:

  1. Allow isometric tiles to render larger then the actual tile grid size as this allows tiles to kind of overlap each other. You would also use the rendered size for mouse picking.
  2. Each layer is rendered top down by splitting each horizontal row into is own layer this insures that tiles are rendered correctly. > Another option would be to also calculate the z-index as being Y. This adds the further benefit of allowing sprites on the isometric tile map to render "behind" tiles. This is very similar to how some isometric games actually function(project hospital is one example).
    I don't know when I'll be able to find the time to add those things to bevy_ecs_tilemap, it certain is possible for someone to mostly do all of this currently except for point 1.

Texture Atlas is improperly divided into tiles

I'm a little out of my depth here, so apologies in advance for any mistakes.

I have a Texture Atlas with 16x16 tiles separated by a 1px gap in the x and y.

I'm using LayerSettings like this:

    let mut layer_settings = LayerSettings::new(
        MapSize(2, 2),
        ChunkSize(1, 1),
        TileSize(16.0, 16.0),
        TextureSize(628.0, 475.0),
    );
    layer_settings.tile_spacing = Vec2::new(1.0, 1.0);

TextureAtlas

That middle grass tile in the bottom left has an index of 963. I'm selecting it like this:

    let mut tile_bundle = TileBundle::default();
    tile_bundle.tile.texture_index = 963u16;

But when that runs, it outputs this:
grass

I've experimented a bit, and I can get a lot closer to what I want by using (columns * tile_size) and (rows * tile_size) as the TextureSize x and y, and removing the tile_spacing. But that leaves me with a 1px gap between tiles:
grass2

So I went into src/render/square-tilemap.vert and changed

    int columns = int(texture_size.x) / int(tile_size.x);

    float sprite_sheet_x = floor(float(texture_index % columns)) * (tile_size.x + spacing.x) - spacing.x;
    float sprite_sheet_y = floor((texture_index / columns)) * (tile_size.y + spacing.y) - spacing.y;

to

    vec2 slot_size = tile_size + spacing;

    int columns = int(floor((texture_size.x + spacing.x) / slot_size.x));

    float sprite_sheet_x = floor(mod(float(texture_index), float(columns)) * (slot_size.x));
    float sprite_sheet_y = floor((texture_index / columns)) * (slot_size.y);

This pretty much works, although it breaks if tile_index = columns.

Maybe this should be a pull request, but I'm very much not confident in my changes. I think I'm right that columns should account for spacing. I'm not sure if the Texture Atlas I'm using is up to standard. And I could be misunderstanding tile_spacing entirely. Any assistance would be appreciated.

Error setting features in cargo.toml

I am trying to make use of this library to load a ldtk map.
I added the following line to the cargo.toml:
bevy_ecs_tilemap = { version = "0.4.0", features = ["ldtk"] }
and I am getting the following error:
the package bevy-multidepends onbevy_ecs_tilemap, with features: ldtkbutbevy_ecs_tilemap does not have these features.
Also, docs.rs it does not show any feature flags.
Is there any reason why the tiled and ldtk are not published, or am I doing something wrong?

Feature Request: API to translate map coords to screen coords

For action games, the sprite entities would be 'free-floating' entities rendered on top of the map, but the game would still want to track their position relative to the map itself. It probably doesn't make sense to have the map store those entities or references to them, but it would be useful to have the map translate a position (given as a DVec2) and return a Transform or DVec2 object that corresponds to the screen coordinates of that location given the map projection and scale and vice versa.

Question/Bug? Undesired spacing between tiles from LDTK map

I understand that loading LDTK is still new in this project, but I'd like to report the issue I'm having.

I've got an open example at https://github.com/Aposhian/bevy-sandbox where you can run cargo run --example ldtk see the behavior I am talking about.

When I load the LDTK level, there is undesired spacing between tiles, and some of the tiles do not render with the proper texture. I wonder if this either due to my texture atlas being irregular, or my .ldtk file being misconfigured.

In the LDTK editor, it looks like this:
image

But Bevy is rendering it like this:

image

Question: How can you migrate a tile to a new chunk

I have created a small test with a bg layer of tiles, and a second sparse layer on top with a player tile that moves with the keys. Upon moving from one chunk to another the player tile stops moving until the position returns to the original chunk.

I'm just updating the UVec2 position, and using notify_chunk_for_tile() from mapquery. Should I be going about this in a different way?

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.