fix: character ordering
This commit is contained in:
parent
9f04ec861e
commit
84ba344597
2 changed files with 46 additions and 30 deletions
57
src/game.rs
57
src/game.rs
|
@ -13,6 +13,7 @@ use bevy::{
|
||||||
};
|
};
|
||||||
use bevy_rapier2d::prelude::*;
|
use bevy_rapier2d::prelude::*;
|
||||||
use rapier2d::geometry::CollisionEventFlags;
|
use rapier2d::geometry::CollisionEventFlags;
|
||||||
|
use std::collections::BTreeSet;
|
||||||
|
|
||||||
pub enum AudioMsg {
|
pub enum AudioMsg {
|
||||||
Color([f32; 3]),
|
Color([f32; 3]),
|
||||||
|
@ -33,6 +34,7 @@ impl Plugin for GamePlugin {
|
||||||
app.add_event::<LevelStartupEvent>()
|
app.add_event::<LevelStartupEvent>()
|
||||||
.init_resource::<CharacterMeshes>()
|
.init_resource::<CharacterMeshes>()
|
||||||
.insert_resource(CurrentLevel(None))
|
.insert_resource(CurrentLevel(None))
|
||||||
|
.init_resource::<CharacterList>()
|
||||||
.add_system_set(SystemSet::on_enter(AppState::Game).with_system(setup))
|
.add_system_set(SystemSet::on_enter(AppState::Game).with_system(setup))
|
||||||
.add_system_set(SystemSet::on_enter(AppState::Win).with_system(win_setup))
|
.add_system_set(SystemSet::on_enter(AppState::Win).with_system(win_setup))
|
||||||
.add_system_set(
|
.add_system_set(
|
||||||
|
@ -67,6 +69,9 @@ pub struct LevelStartupEvent;
|
||||||
|
|
||||||
pub struct CurrentLevel(pub Option<LevelId>);
|
pub struct CurrentLevel(pub Option<LevelId>);
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
pub struct CharacterList(pub BTreeSet<Entity>);
|
||||||
|
|
||||||
pub struct CharacterMeshes {
|
pub struct CharacterMeshes {
|
||||||
square: Mesh2dHandle,
|
square: Mesh2dHandle,
|
||||||
}
|
}
|
||||||
|
@ -125,6 +130,7 @@ pub fn spawn_characters<I: IntoIterator<Item = (Transform, Color)>>(
|
||||||
character_meshes: &Res<CharacterMeshes>,
|
character_meshes: &Res<CharacterMeshes>,
|
||||||
materials: &mut ResMut<Assets<ColorMaterial>>,
|
materials: &mut ResMut<Assets<ColorMaterial>>,
|
||||||
audio: &Res<crossbeam_channel::Sender<AudioMsg>>,
|
audio: &Res<crossbeam_channel::Sender<AudioMsg>>,
|
||||||
|
character_list: &mut ResMut<CharacterList>,
|
||||||
|
|
||||||
characters: I,
|
characters: I,
|
||||||
) {
|
) {
|
||||||
|
@ -134,6 +140,7 @@ pub fn spawn_characters<I: IntoIterator<Item = (Transform, Color)>>(
|
||||||
character_meshes,
|
character_meshes,
|
||||||
materials,
|
materials,
|
||||||
audio,
|
audio,
|
||||||
|
character_list,
|
||||||
transform,
|
transform,
|
||||||
color,
|
color,
|
||||||
i == 0,
|
i == 0,
|
||||||
|
@ -146,6 +153,7 @@ pub fn spawn_character(
|
||||||
character_meshes: &Res<CharacterMeshes>,
|
character_meshes: &Res<CharacterMeshes>,
|
||||||
materials: &mut ResMut<Assets<ColorMaterial>>,
|
materials: &mut ResMut<Assets<ColorMaterial>>,
|
||||||
audio: &Res<crossbeam_channel::Sender<AudioMsg>>,
|
audio: &Res<crossbeam_channel::Sender<AudioMsg>>,
|
||||||
|
character_list: &mut ResMut<CharacterList>,
|
||||||
mut transform: Transform,
|
mut transform: Transform,
|
||||||
color: Color,
|
color: Color,
|
||||||
is_player: bool,
|
is_player: bool,
|
||||||
|
@ -185,6 +193,8 @@ pub fn spawn_character(
|
||||||
.insert(CollisionCount(0));
|
.insert(CollisionCount(0));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
character_list.0.insert(entity_commands.id());
|
||||||
|
|
||||||
if is_player {
|
if is_player {
|
||||||
entity_commands.insert(Player);
|
entity_commands.insert(Player);
|
||||||
audio
|
audio
|
||||||
|
@ -273,6 +283,7 @@ fn collision_event_system(
|
||||||
mut collision_counter_query: Query<&mut CollisionCount>,
|
mut collision_counter_query: Query<&mut CollisionCount>,
|
||||||
mut app_state: ResMut<State<AppState>>,
|
mut app_state: ResMut<State<AppState>>,
|
||||||
audio: Res<crossbeam_channel::Sender<AudioMsg>>,
|
audio: Res<crossbeam_channel::Sender<AudioMsg>>,
|
||||||
|
mut character_list: ResMut<CharacterList>,
|
||||||
) {
|
) {
|
||||||
for collision_event in collision_events.iter() {
|
for collision_event in collision_events.iter() {
|
||||||
match collision_event {
|
match collision_event {
|
||||||
|
@ -283,6 +294,8 @@ fn collision_event_system(
|
||||||
Ok((c2_color, c2_transform, _c2_material, c2_player)),
|
Ok((c2_color, c2_transform, _c2_material, c2_player)),
|
||||||
) = (character_query.get(*e1), character_query.get(*e2))
|
) = (character_query.get(*e1), character_query.get(*e2))
|
||||||
{
|
{
|
||||||
|
character_list.0.remove(e1);
|
||||||
|
character_list.0.remove(e2);
|
||||||
commands.entity(*e1).despawn_recursive();
|
commands.entity(*e1).despawn_recursive();
|
||||||
commands.entity(*e2).despawn_recursive();
|
commands.entity(*e2).despawn_recursive();
|
||||||
|
|
||||||
|
@ -301,6 +314,7 @@ fn collision_event_system(
|
||||||
&character_meshes,
|
&character_meshes,
|
||||||
&mut materials,
|
&mut materials,
|
||||||
&audio,
|
&audio,
|
||||||
|
&mut character_list,
|
||||||
if c1_player.is_some() {
|
if c1_player.is_some() {
|
||||||
*c1_transform
|
*c1_transform
|
||||||
} else if c2_player.is_some() {
|
} else if c2_player.is_some() {
|
||||||
|
@ -404,41 +418,32 @@ fn change_character_system(
|
||||||
keyboard_input: Res<Input<KeyCode>>,
|
keyboard_input: Res<Input<KeyCode>>,
|
||||||
characters: Query<(Entity, &CharacterColor, Option<&Player>)>,
|
characters: Query<(Entity, &CharacterColor, Option<&Player>)>,
|
||||||
audio: Res<crossbeam_channel::Sender<AudioMsg>>,
|
audio: Res<crossbeam_channel::Sender<AudioMsg>>,
|
||||||
|
character_list: Res<CharacterList>,
|
||||||
) {
|
) {
|
||||||
if !keyboard_input.just_pressed(KeyCode::Tab) {
|
if !keyboard_input.just_pressed(KeyCode::Tab) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut player_idx: usize = 0;
|
if let Some((player_entity, _color, _)) = characters
|
||||||
let mut player_count: usize = 0;
|
.iter()
|
||||||
|
.find(|(_entity, _color, player)| player.is_some())
|
||||||
// find player idx
|
.or_else(|| characters.iter().next())
|
||||||
for (_entity, _color, player) in characters.iter() {
|
{
|
||||||
if player.is_some() {
|
commands.entity(player_entity).remove::<Player>();
|
||||||
player_idx = player_count;
|
if let Some(new_player_entity) = character_list
|
||||||
}
|
.0
|
||||||
player_count += 1;
|
.range(player_entity..)
|
||||||
}
|
.nth(1)
|
||||||
|
.or_else(|| character_list.0.iter().next())
|
||||||
// calculate next player index
|
{
|
||||||
let next_player_idx = (player_idx + 1) % player_count;
|
commands.entity(*new_player_entity).insert(Player);
|
||||||
player_count = 0;
|
if let Ok((_entity, color, _player)) = characters.get(*new_player_entity) {
|
||||||
|
|
||||||
// exchange `Player` component from old `player_idx` to new `next_player_idx`
|
|
||||||
for (entity, color, _player) in characters.iter() {
|
|
||||||
if player_count == player_idx {
|
|
||||||
commands.entity(entity).remove::<Player>();
|
|
||||||
}
|
|
||||||
|
|
||||||
if player_count == next_player_idx {
|
|
||||||
commands.entity(entity).insert(Player);
|
|
||||||
audio
|
audio
|
||||||
.send(AudioMsg::Color([color.0.r(), color.0.g(), color.0.b()]))
|
.send(AudioMsg::Color([color.0.r(), color.0.g(), color.0.b()]))
|
||||||
.ok();
|
.ok();
|
||||||
audio.send(AudioMsg::Switch).ok();
|
audio.send(AudioMsg::Switch).ok();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
player_count += 1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -557,6 +562,7 @@ fn level_keyboard_system(
|
||||||
mut level_startup_event: EventWriter<LevelStartupEvent>,
|
mut level_startup_event: EventWriter<LevelStartupEvent>,
|
||||||
mut camera_query: Query<&mut Transform, With<Camera>>,
|
mut camera_query: Query<&mut Transform, With<Camera>>,
|
||||||
keyboard_input: Res<Input<KeyCode>>,
|
keyboard_input: Res<Input<KeyCode>>,
|
||||||
|
mut character_list: ResMut<CharacterList>,
|
||||||
level_query: Query<Entity, With<Level>>,
|
level_query: Query<Entity, With<Level>>,
|
||||||
mut app_state: ResMut<State<AppState>>,
|
mut app_state: ResMut<State<AppState>>,
|
||||||
) {
|
) {
|
||||||
|
@ -568,6 +574,7 @@ fn level_keyboard_system(
|
||||||
}
|
}
|
||||||
|
|
||||||
if keyboard_input.just_pressed(KeyCode::R) {
|
if keyboard_input.just_pressed(KeyCode::R) {
|
||||||
|
character_list.0.clear();
|
||||||
for entity in level_query.iter() {
|
for entity in level_query.iter() {
|
||||||
commands.entity(entity).despawn_recursive();
|
commands.entity(entity).despawn_recursive();
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,12 @@ pub fn setup_level(
|
||||||
level_startup_event.send(LevelStartupEvent);
|
level_startup_event.send(LevelStartupEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn despawn_level(mut commands: Commands, level_query: Query<Entity, With<Level>>) {
|
pub fn despawn_level(
|
||||||
|
mut commands: Commands,
|
||||||
|
mut character_list: ResMut<CharacterList>,
|
||||||
|
level_query: Query<Entity, With<Level>>,
|
||||||
|
) {
|
||||||
|
character_list.0.clear();
|
||||||
for entity in level_query.iter() {
|
for entity in level_query.iter() {
|
||||||
commands.entity(entity).despawn_recursive();
|
commands.entity(entity).despawn_recursive();
|
||||||
}
|
}
|
||||||
|
@ -32,6 +37,7 @@ pub fn post_setup_level(
|
||||||
mut level_startup_event: EventReader<LevelStartupEvent>,
|
mut level_startup_event: EventReader<LevelStartupEvent>,
|
||||||
asset_server: Res<AssetServer>,
|
asset_server: Res<AssetServer>,
|
||||||
audio: Res<crossbeam_channel::Sender<AudioMsg>>,
|
audio: Res<crossbeam_channel::Sender<AudioMsg>>,
|
||||||
|
mut character_list: ResMut<CharacterList>,
|
||||||
stored_levels_assets: Res<Assets<StoredLevels>>,
|
stored_levels_assets: Res<Assets<StoredLevels>>,
|
||||||
stored_levels_handle: Res<Handle<StoredLevels>>,
|
stored_levels_handle: Res<Handle<StoredLevels>>,
|
||||||
) {
|
) {
|
||||||
|
@ -50,6 +56,7 @@ pub fn post_setup_level(
|
||||||
&mut materials,
|
&mut materials,
|
||||||
&asset_server,
|
&asset_server,
|
||||||
&audio,
|
&audio,
|
||||||
|
&mut character_list,
|
||||||
stored_level,
|
stored_level,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -64,6 +71,7 @@ pub fn spawn_stored_level(
|
||||||
materials: &mut ResMut<Assets<ColorMaterial>>,
|
materials: &mut ResMut<Assets<ColorMaterial>>,
|
||||||
asset_server: &Res<AssetServer>,
|
asset_server: &Res<AssetServer>,
|
||||||
audio: &Res<crossbeam_channel::Sender<AudioMsg>>,
|
audio: &Res<crossbeam_channel::Sender<AudioMsg>>,
|
||||||
|
character_list: &mut ResMut<CharacterList>,
|
||||||
|
|
||||||
stored_level: &StoredLevel,
|
stored_level: &StoredLevel,
|
||||||
) {
|
) {
|
||||||
|
@ -84,6 +92,7 @@ pub fn spawn_stored_level(
|
||||||
character_meshes,
|
character_meshes,
|
||||||
materials,
|
materials,
|
||||||
audio,
|
audio,
|
||||||
|
character_list,
|
||||||
stored_level.characters.iter().map(|character| {
|
stored_level.characters.iter().map(|character| {
|
||||||
(
|
(
|
||||||
Transform::from_xyz(character.pos.x, character.pos.y, 0.),
|
Transform::from_xyz(character.pos.x, character.pos.y, 0.),
|
||||||
|
|
Loading…
Reference in a new issue