use bevy::prelude::*;
use bevy_ecs_tiled::prelude::*;
mod helper;
fn main() {
App::new()
.add_plugins(DefaultPlugins.build().set(ImagePlugin::default_nearest()))
.add_plugins(TiledPlugin::default())
.add_plugins(helper::HelperPlugin)
.init_state::<MapState>()
.add_systems(Startup, startup)
.add_systems(
Update,
(
handle_load.run_if(in_state(MapState::Unloaded)),
(handle_unload, handle_reload).run_if(in_state(MapState::Loaded)),
log_transitions,
),
)
.run();
}
fn startup(
mut commands: Commands,
asset_server: Res<AssetServer>,
mut next_state: ResMut<NextState<MapState>>,
) {
commands.spawn(Camera2d);
commands.spawn(Text::from(
"U = Unload map by removing asset\nI = Unload map by despawning entity\nL = Load finite map\nK = Replace loaded map component without unloading\nR = Reload map using the RespawnTiledMap component",
));
commands.spawn((
TiledMap(asset_server.load("maps/orthogonal/finite.tmx")),
TilemapAnchor::Center,
));
next_state.set(MapState::Loaded);
}
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Hash, States)]
enum MapState {
Loaded,
#[default]
Unloaded,
}
fn handle_load(
mut commands: Commands,
asset_server: Res<AssetServer>,
keyboard_input: Res<ButtonInput<KeyCode>>,
mut next_state: ResMut<NextState<MapState>>,
) {
if keyboard_input.just_pressed(KeyCode::KeyL) {
info!("Load map");
commands.spawn((
TiledMap(asset_server.load("maps/orthogonal/finite.tmx")),
TilemapAnchor::Center,
));
next_state.set(MapState::Loaded);
}
}
fn handle_reload(
mut commands: Commands,
asset_server: Res<AssetServer>,
keyboard_input: Res<ButtonInput<KeyCode>>,
maps_query: Query<Entity, With<TiledMap>>,
mut next_state: ResMut<NextState<MapState>>,
) {
if keyboard_input.just_pressed(KeyCode::KeyK) {
if let Ok(entity) = maps_query.single() {
info!("Reload map");
commands
.entity(entity)
.insert(TiledMap(asset_server.load("maps/orthogonal/infinite.tmx")));
next_state.set(MapState::Loaded);
} else {
warn!("Cannot reload: no map loaded ?");
}
}
if keyboard_input.just_pressed(KeyCode::KeyR) {
if let Ok(entity) = maps_query.single() {
info!("Respawn map");
commands.entity(entity).insert(RespawnTiledMap);
next_state.set(MapState::Loaded);
} else {
warn!("Cannot respawn: no map loaded ?");
}
}
}
fn handle_unload(
mut commands: Commands,
mut maps: ResMut<Assets<TiledMapAsset>>,
keyboard_input: Res<ButtonInput<KeyCode>>,
maps_query: Query<Entity, With<TiledMap>>,
mut next_state: ResMut<NextState<MapState>>,
) {
if keyboard_input.just_pressed(KeyCode::KeyU) {
info!("Unload map");
let handles: Vec<_> = maps.iter().map(|(handle, _)| handle).collect();
for handle in handles {
maps.remove(handle);
}
next_state.set(MapState::Unloaded);
} else if keyboard_input.just_pressed(KeyCode::KeyI) {
info!("Remove map entities");
for entity in maps_query.iter() {
commands.entity(entity).despawn();
}
next_state.set(MapState::Unloaded);
}
}
fn log_transitions(mut transitions: EventReader<StateTransitionEvent<MapState>>) {
for transition in transitions.read() {
info!(
"transition: {:?} => {:?}",
transition.exited, transition.entered
);
}
}