fix: character fusion without player

This commit is contained in:
Pascal Engélibert 2022-08-24 18:51:18 +02:00
parent ec7d04c8c8
commit b42a032cfd
Signed by: tuxmain
GPG key ID: 3504BC6D362F7DCA
4 changed files with 67 additions and 115 deletions

View file

@ -6,9 +6,10 @@ pub use crate::filters::*;
use crate::AppState; use crate::AppState;
use bevy::{ use bevy::{
ecs::system::EntityCommands,
input::{keyboard::KeyCode, Input}, input::{keyboard::KeyCode, Input},
prelude::{shape::Quad, *}, prelude::{shape::Quad, *},
sprite::Mesh2dHandle, ecs::system::EntityCommands, sprite::Mesh2dHandle,
}; };
use bevy_rapier2d::prelude::*; use bevy_rapier2d::prelude::*;
@ -41,9 +42,9 @@ impl Plugin for GamePlugin {
.with_system(player_movement_system) .with_system(player_movement_system)
.with_system(move_camera) .with_system(move_camera)
.with_system(character_particle_effect_system), .with_system(character_particle_effect_system),
) )
.add_system_set( .add_system_set(
SystemSet::on_update(AppState::Win) SystemSet::on_update(AppState::Win)
.with_system(player_movement_system) .with_system(player_movement_system)
.with_system(move_camera) .with_system(move_camera)
.with_system(character_particle_effect_system), .with_system(character_particle_effect_system),
@ -107,34 +108,23 @@ fn setup(
); );
} }
pub fn spawn_characters( pub fn spawn_characters<I: IntoIterator<Item = (Transform, Color)>>(
commands: &mut Commands, commands: &mut Commands,
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>>,
transforms: &mut Vec<Transform>, characters: I,
colors: &Vec<Color>,
) { ) {
spawn_character( for (i, (transform, color)) in characters.into_iter().enumerate() {
commands,
character_meshes,
materials,
audio,
transforms[0],
colors[0],
true,
);
for c in 1 .. transforms.len() {
spawn_character( spawn_character(
commands, commands,
character_meshes, character_meshes,
materials, materials,
audio, audio,
transforms[c], transform,
colors[c], color,
false, i == 0,
); );
} }
} }
@ -198,8 +188,8 @@ fn collision_event_system(
if flags.is_empty() { if flags.is_empty() {
if let ( if let (
Ok((c1_color, c1_transform, c1_player)), Ok((c1_color, c1_transform, c1_player)),
Ok((c2_color, c2_transform, c2_player))) = Ok((c2_color, c2_transform, c2_player)),
(character_query.get(*e1), character_query.get(*e2)) ) = (character_query.get(*e1), character_query.get(*e2))
{ {
commands.entity(*e1).despawn_recursive(); commands.entity(*e1).despawn_recursive();
commands.entity(*e2).despawn_recursive(); commands.entity(*e2).despawn_recursive();
@ -215,27 +205,23 @@ fn collision_event_system(
} }
// position character based on current player location // position character based on current player location
if let Some(_player) = c1_player { spawn_character(
spawn_character( &mut commands,
&mut commands, &character_meshes,
&character_meshes, &mut materials,
&mut materials, &audio,
&audio, if c1_player.is_some() {
*c1_transform, *c1_transform
new_color.into(), } else if c2_player.is_some() {
true, *c2_transform
); } else {
} else if let Some(_player) = c2_player { Transform::identity().with_translation(
spawn_character( (c1_transform.translation + c2_transform.translation) / 2.,
&mut commands, )
&character_meshes, },
&mut materials, new_color.into(),
&audio, c1_player.is_some() || c2_player.is_some(),
*c2_transform, );
new_color.into(),
true,
);
}
audio.send(AudioMsg::Fusion).ok(); audio.send(AudioMsg::Fusion).ok();
} }
@ -251,14 +237,16 @@ fn change_character_system(
characters: Query<(Entity, &CharacterColor, Option<&Player>)>, characters: Query<(Entity, &CharacterColor, Option<&Player>)>,
audio: Res<crossbeam_channel::Sender<AudioMsg>>, audio: Res<crossbeam_channel::Sender<AudioMsg>>,
) { ) {
if !keyboard_input.just_pressed(KeyCode::Tab) { return; } if !keyboard_input.just_pressed(KeyCode::Tab) {
return;
}
let mut player_idx: usize = 0; let mut player_idx: usize = 0;
let mut player_count: usize = 0; let mut player_count: usize = 0;
// find player idx // find player idx
for (_entity, _color, player) in characters.iter() { for (_entity, _color, player) in characters.iter() {
if let Some(_player) = player { if player.is_some() {
player_idx = player_count; player_idx = player_count;
} }
player_count += 1; player_count += 1;
@ -279,7 +267,7 @@ fn change_character_system(
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; player_count += 1;
@ -292,20 +280,19 @@ fn player_movement_system(
mut app_state: ResMut<State<AppState>>, mut app_state: ResMut<State<AppState>>,
audio: Res<crossbeam_channel::Sender<AudioMsg>>, audio: Res<crossbeam_channel::Sender<AudioMsg>>,
) { ) {
let right_pressed: bool =
keyboard_input.pressed(KeyCode::Right) || keyboard_input.pressed(KeyCode::D);
let left_pressed: bool =
keyboard_input.pressed(KeyCode::Left) || keyboard_input.pressed(KeyCode::A);
let right_pressed: bool = for mut velocity in characters.iter_mut() {
keyboard_input.pressed(KeyCode::Right) || keyboard_input.pressed(KeyCode::D); velocity.linvel.x = 200. * (right_pressed as i8 - left_pressed as i8) as f32;
let left_pressed: bool =
keyboard_input.pressed(KeyCode::Left) || keyboard_input.pressed(KeyCode::A);
for mut velocity in characters.iter_mut() { if keyboard_input.just_pressed(KeyCode::Space) {
velocity.linvel.x = 200. * (right_pressed as i8 - left_pressed as i8) as f32; audio.send(AudioMsg::Jump).ok();
velocity.linvel.y = 500.;
if keyboard_input.just_pressed(KeyCode::Space) { }
audio.send(AudioMsg::Jump).ok(); }
velocity.linvel.y = 500.;
}
}
if app_state.current() == &AppState::Win && keyboard_input.just_pressed(KeyCode::Return) { if app_state.current() == &AppState::Win && keyboard_input.just_pressed(KeyCode::Return) {
app_state.replace(AppState::Game).unwrap(); app_state.replace(AppState::Game).unwrap();
@ -349,17 +336,17 @@ fn move_camera(
const FOLLOW_SPEED: f32 = std::f32::consts::PI; const FOLLOW_SPEED: f32 = std::f32::consts::PI;
for character_transform in characters.iter() { for character_transform in characters.iter() {
let (camera, mut camera_transform) = let (camera, mut camera_transform) = camera_query.single_mut();
camera_query.single_mut();
let size: Vec2 = camera.logical_viewport_size().unwrap(); let size: Vec2 = camera.logical_viewport_size().unwrap();
let half_height: f32 = size.y * 0.5; let half_height: f32 = size.y * 0.5;
camera_transform.translation = camera_transform.translation.lerp( camera_transform.translation = camera_transform.translation.lerp(
character_transform.translation, time.delta_seconds() * FOLLOW_SPEED character_transform.translation,
time.delta_seconds() * FOLLOW_SPEED,
); );
// prevent camera from going too low // prevent camera from going too low
camera_transform.translation.y = camera_transform.translation.y.max(half_height-MARGIN); camera_transform.translation.y = camera_transform.translation.y.max(half_height - MARGIN);
// always make sure that camera is away from the object in order to render them // always make sure that camera is away from the object in order to render them
camera_transform.translation.z = 999.0; camera_transform.translation.z = 999.0;
} }

View file

@ -15,10 +15,7 @@ pub fn setup_level(
camera_query: &mut Query<&mut Transform, With<Camera>>, camera_query: &mut Query<&mut Transform, With<Camera>>,
level_id: LevelId, level_id: LevelId,
) { ) {
let level_entity = commands let level_entity = commands.spawn().insert(Level).id();
.spawn()
.insert(Level)
.id();
current_level.0 = Some(level_id); current_level.0 = Some(level_id);
camera_query.single_mut().translation = Default::default(); camera_query.single_mut().translation = Default::default();
@ -43,7 +40,7 @@ pub fn post_setup_level(
asset_server: Res<AssetServer>, asset_server: Res<AssetServer>,
audio: Res<crossbeam_channel::Sender<AudioMsg>>, audio: Res<crossbeam_channel::Sender<AudioMsg>>,
) { ) {
for LevelStartupEvent(level_entity) in level_startup_event.iter() { for LevelStartupEvent(_level_entity) in level_startup_event.iter() {
if let Some(level_id) = current_level.0 { if let Some(level_id) = current_level.0 {
match level_id.0 { match level_id.0 {
0 => level0::setup( 0 => level0::setup(

View file

@ -25,31 +25,15 @@ pub fn setup(
.insert(Collider::cuboid(400., 8.)) .insert(Collider::cuboid(400., 8.))
.insert(Level); .insert(Level);
spawn_character( spawn_characters(
commands, commands,
character_meshes, character_meshes,
materials, materials,
audio, audio,
Transform::from_xyz(-128., -64., 0.), [
Color::RED, (Transform::from_xyz(-128., -64., 0.), Color::RED),
true, (Transform::from_xyz(0., -64., 0.), Color::GREEN),
); (Transform::from_xyz(128., -64., 0.), Color::BLUE),
spawn_character( ],
commands,
character_meshes,
materials,
audio,
Transform::from_xyz(0., -64., 0.),
Color::GREEN,
false,
);
spawn_character(
commands,
character_meshes,
materials,
audio,
Transform::from_xyz(128., -64., 0.),
Color::BLUE,
false,
); );
} }

View file

@ -39,32 +39,16 @@ pub fn setup(
.insert(Collider::cuboid(200., 8.)) .insert(Collider::cuboid(200., 8.))
.insert(Level); .insert(Level);
spawn_character( spawn_characters(
commands, commands,
character_meshes, character_meshes,
materials, materials,
audio, audio,
Transform::from_xyz(128., 64., 0.), [
Color::BLUE, (Transform::from_xyz(128., 64., 0.), Color::BLUE),
true, (Transform::from_xyz(-128., -128., 0.), Color::RED),
); (Transform::from_xyz(0., -128., 0.), Color::GREEN),
spawn_character( ],
commands,
character_meshes,
materials,
audio,
Transform::from_xyz(-128., -128., 0.),
Color::RED,
false,
);
spawn_character(
commands,
character_meshes,
materials,
audio,
Transform::from_xyz(0., -128., 0.),
Color::GREEN,
false,
); );
commands commands