Skip to content

Moving tiles to where another tile used to be fails to render properly #559

@LilithHohman

Description

@LilithHohman

When moving tiles as in the move_tiles.rs example, if multiple tiles are moved simultaneously and one moves to the coordinates where another previously was, it's rendered as blank space.

Here's code to reproduce this issue, it's just a slightly modified move_tiles.rs example. Two tiles are moved around a 2x2 square. Both are visible at first, but after the first move only one is visible.



use bevy::prelude::*;
use bevy_ecs_tilemap::prelude::*;
mod helpers;

fn startup(mut commands: Commands, asset_server: Res<AssetServer>) {
    commands.spawn(Camera2dBundle::default());

    let texture_handle: Handle<Image> = asset_server.load("tiles.png");

    let map_size = TilemapSize { x: 2, y: 2 };

    // Create a tilemap entity a little early.
    let tilemap_entity = commands.spawn_empty().id();

    let mut tile_storage = TileStorage::empty(map_size);

    // Spawn the elements of the tilemap.

    let tile_pos = TilePos { x: 0, y: 0 };
    let tile_entity = commands
        .spawn(TileBundle {
            position: tile_pos,
            tilemap_id: TilemapId(tilemap_entity),
            ..Default::default()
        })
        .id();
    tile_storage.set(&tile_pos, tile_entity);

    let tile_pos = TilePos { x: 1, y: 0 };
    let tile_entity = commands
        .spawn(TileBundle {
            position: tile_pos,
            tilemap_id: TilemapId(tilemap_entity),
            ..Default::default()
        })
        .id();
    tile_storage.set(&tile_pos, tile_entity);

    let tile_size = TilemapTileSize { x: 16.0, y: 16.0 };
    let grid_size = tile_size.into();
    let map_type = TilemapType::default();

    commands.entity(tilemap_entity).insert(TilemapBundle {
        grid_size,
        map_type,
        size: map_size,
        storage: tile_storage,
        texture: TilemapTexture::Single(texture_handle),
        tile_size,
        transform: get_tilemap_center_transform(&map_size, &grid_size, &map_type, 0.0),
        ..Default::default()
    });
}

fn swap_pos(keyboard_input: Res<ButtonInput<KeyCode>>, mut query: Query<&mut TilePos>) {
    if keyboard_input.just_pressed(KeyCode::Space) {
        for mut pos in query.iter_mut() {
            if pos.x == 0 && pos.y == 0 {
                pos.x = 1;
                pos.y = 0;
            } else if pos.x == 1 && pos.y == 0 {
                pos.x = 1;
                pos.y = 1;
            } else if pos.x == 1 && pos.y == 1 {
                pos.x = 0;
                pos.y = 1;
            } else {
                pos.x = 0;
                pos.y = 0;
            }
        }
    }
}

fn main() {
    App::new()
        .add_plugins(
            DefaultPlugins
                .set(WindowPlugin {
                    primary_window: Some(Window {
                        title: String::from("Update tile positions without despawning."),
                        ..Default::default()
                    }),
                    ..default()
                })
                .set(ImagePlugin::default_nearest()),
        )
        .add_plugins(TilemapPlugin)
        .add_systems(Startup, startup)
        .add_systems(Update, helpers::camera::movement)
        .add_systems(Update, swap_pos)
        .run();
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions