Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hide all or tileset / layer tiles #530

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 24 additions & 14 deletions examples/helpers/tiled.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ use std::sync::Arc;

use bevy::{
asset::{io::Reader, AssetLoader, AssetPath, AsyncReadExt},
log,
prelude::{
Added, Asset, AssetApp, AssetEvent, AssetId, Assets, Bundle, Commands, Component,
DespawnRecursiveExt, Entity, EventReader, GlobalTransform, Handle, Image, Plugin, Query,
Expand Down Expand Up @@ -54,15 +53,24 @@ pub struct TiledMap {
}

// Stores a list of tiled layers.
#[derive(Component, Default)]
pub struct TiledLayersStorage {
pub storage: HashMap<u32, Entity>,
#[derive(Component, Default, Debug)]
pub struct TilesetLayerToStorageEntity {
pub storage: HashMap<u32, HashMap<u32, Entity>>,
}

impl TilesetLayerToStorageEntity {
pub fn get_entities(&self) -> Vec<&Entity> {
self.storage
.values()
.flat_map(|layer| layer.values())
.collect()
}
}

#[derive(Default, Bundle)]
pub struct TiledMapBundle {
pub tiled_map: Handle<TiledMap>,
pub storage: TiledLayersStorage,
pub storage: TilesetLayerToStorageEntity,
pub transform: Transform,
pub global_transform: GlobalTransform,
pub render_settings: TilemapRenderSettings,
Expand Down Expand Up @@ -203,7 +211,7 @@ pub fn process_loaded_maps(
tile_storage_query: Query<(Entity, &TileStorage)>,
mut map_query: Query<(
&Handle<TiledMap>,
&mut TiledLayersStorage,
&mut TilesetLayerToStorageEntity,
&TilemapRenderSettings,
)>,
new_maps: Query<&Handle<TiledMap>, Added<Handle<TiledMap>>>,
Expand Down Expand Up @@ -235,21 +243,21 @@ pub fn process_loaded_maps(
}

for changed_map in changed_maps.iter() {
for (map_handle, mut layer_storage, render_settings) in map_query.iter_mut() {
for (map_handle, mut tileset_layer_entity, render_settings) in map_query.iter_mut() {
// only deal with currently changed map
if map_handle.id() != *changed_map {
continue;
}
if let Some(tiled_map) = maps.get(map_handle) {
// TODO: Create a RemoveMap component..
for layer_entity in layer_storage.storage.values() {
if let Ok((_, layer_tile_storage)) = tile_storage_query.get(*layer_entity) {
for tile in layer_tile_storage.iter().flatten() {
for entity in tileset_layer_entity.get_entities() {
if let Ok((_, map_tiles)) = tile_storage_query.get(*entity) {
for tile in map_tiles.iter().flatten() {
commands.entity(*tile).despawn_recursive()
}
}
// commands.entity(*layer_entity).despawn_recursive();
}
// commands.entity(*layer_entity).despawn_recursive();

// The TilemapBundle requires that all tile images come exclusively from a single
// tiled texture or from a Vec of independent per-tile images. Furthermore, all of
Expand All @@ -274,6 +282,7 @@ pub fn process_loaded_maps(
};

// Once materials have been created/added we need to then create the layers.
let mut layers_map = HashMap::new();
for (layer_index, layer) in tiled_map.map.layers().enumerate() {
let offset_x = layer.offset_x;
let offset_y = layer.offset_y;
Expand Down Expand Up @@ -391,10 +400,11 @@ pub fn process_loaded_maps(
..Default::default()
});

layer_storage
.storage
.insert(layer_index as u32, layer_entity);
layers_map.insert(layer_index as u32, layer_entity);
}
tileset_layer_entity
.storage
.insert(tileset_index as u32, layers_map);
}
}
}
Expand Down
51 changes: 50 additions & 1 deletion examples/tiled.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
use bevy::prelude::*;
use bevy::{ecs::query::QueryFilter, prelude::*};
use bevy_ecs_tilemap::prelude::*;

use crate::helpers::tiled::TilesetLayerToStorageEntity;

mod helpers;

#[derive(Resource, Deref, DerefMut)]
pub struct DebouncedTimer(Timer);

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

Expand All @@ -29,7 +34,51 @@ fn main() {
)
.add_plugins(TilemapPlugin)
.add_plugins(helpers::tiled::TiledMapPlugin)
.insert_resource(DebouncedTimer(Timer::from_seconds(0.5, TimerMode::Once)))
.add_systems(Startup, startup)
.add_systems(Update, helpers::camera::movement)
.add_systems(Update, show_hide_tiles)
.run();
}

fn show_hide_tiles(
time: Res<Time>,
mut timer: ResMut<DebouncedTimer>,
keyboard_input: Res<ButtonInput<KeyCode>>,
tile_storage_query: Query<&TileStorage>,
map_query: Query<&TilesetLayerToStorageEntity>,
mut tile_query: Query<&mut TileVisible>,
) {
timer.0.tick(time.delta());

if keyboard_input.pressed(KeyCode::Space) && timer.0.finished() {
timer.0.reset();
info!("Hide/Show all tiles");
let tileset_layer_entity = map_query.single();
for entity in tileset_layer_entity.get_entities() {
toggle_tiles_visibility(&tile_storage_query, &mut tile_query, entity);
}
}
if keyboard_input.pressed(KeyCode::KeyC) && timer.0.finished() {
timer.0.reset();
info!("Hide/Show castle tiles");
let tileset_layer_entity = map_query.single();
for entity in tileset_layer_entity.storage.get(&2).unwrap().values() {
toggle_tiles_visibility(&tile_storage_query, &mut tile_query, entity);
}
}
}

fn toggle_tiles_visibility(
tile_storage_query: &Query<&TileStorage>,
tile_query: &mut Query<&mut TileVisible>,
entity: &Entity,
) {
if let Ok(map_tiles) = tile_storage_query.get(*entity) {
for tile in map_tiles.iter().flatten() {
if let Ok(mut t) = tile_query.get_mut(*tile) {
t.0 = !t.0;
}
}
}
}