-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Refactor game flow and components: remove in_game module, add game ev…
…ents, and update spaceship and health mechanics
- Loading branch information
Showing
23 changed files
with
548 additions
and
319 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
use bevy::prelude::*; | ||
|
||
use crate::{ | ||
game_events::trigger::{SpaceShipMovement, SpaceShipMovementEvent}, | ||
res::{ControlMode, ControlOption}, | ||
states::GameState, | ||
ui_component::{ControlButton, ControlButtonPanel}, | ||
}; | ||
pub struct ControlPlugin; | ||
|
||
impl Plugin for ControlPlugin { | ||
fn build(&self, app: &mut App) { | ||
app.add_systems(OnEnter(GameState::InPlay), spawn_control_button_panel) | ||
.add_systems( | ||
Update, | ||
( | ||
handle_clicking_interaction, | ||
handle_spaceship_keyboard_interaction, | ||
) | ||
.run_if(in_state(GameState::InPlay)), | ||
); | ||
} | ||
} | ||
|
||
fn spawn_control_button_panel(mut commands: Commands, control_option: Res<ControlOption>) { | ||
if control_option.mode == ControlMode::Keyboard { | ||
return; | ||
} | ||
commands.spawn(ControlButtonPanel); | ||
} | ||
|
||
// Button Mode | ||
fn handle_clicking_interaction( | ||
mut commands: Commands, | ||
mut control_button_query: Query<(&Interaction, &mut BackgroundColor, &ControlButton)>, | ||
control_option: Res<ControlOption>, | ||
) { | ||
if control_option.mode == ControlMode::Keyboard { | ||
return; | ||
} | ||
let mut all_not_pressed = true; | ||
for (interaction, mut background_color, button_direction) in control_button_query.iter_mut() { | ||
if *interaction == Interaction::Pressed { | ||
background_color.0.set_alpha(0.1); | ||
all_not_pressed = false; | ||
let movement = match button_direction { | ||
ControlButton::Up => SpaceShipMovement::Up, | ||
ControlButton::UpRight => SpaceShipMovement::UpRight, | ||
ControlButton::Right => SpaceShipMovement::Right, | ||
ControlButton::DownRight => SpaceShipMovement::DownRight, | ||
ControlButton::Down => SpaceShipMovement::Down, | ||
ControlButton::DownLeft => SpaceShipMovement::DownLeft, | ||
ControlButton::Left => SpaceShipMovement::Left, | ||
ControlButton::UpLeft => SpaceShipMovement::UpLeft, | ||
}; | ||
commands.trigger(SpaceShipMovementEvent(movement)); | ||
} | ||
background_color.0.set_alpha(0.5); | ||
} | ||
if all_not_pressed { | ||
commands.trigger(SpaceShipMovementEvent(SpaceShipMovement::Rest)); | ||
} | ||
} | ||
|
||
// Keyboard Mode | ||
fn handle_spaceship_keyboard_interaction( | ||
mut commands: Commands, | ||
keys: Res<ButtonInput<KeyCode>>, | ||
control_option: Res<ControlOption>, | ||
) { | ||
if control_option.mode != ControlMode::Keyboard { | ||
return; | ||
} | ||
let movement = match ( | ||
keys.pressed(KeyCode::ArrowUp), | ||
keys.pressed(KeyCode::ArrowDown), | ||
keys.pressed(KeyCode::ArrowLeft), | ||
keys.pressed(KeyCode::ArrowRight), | ||
) { | ||
(true, false, true, false) => SpaceShipMovement::UpLeft, | ||
(true, false, false, true) => SpaceShipMovement::UpRight, | ||
(false, true, true, false) => SpaceShipMovement::DownLeft, | ||
(false, true, false, true) => SpaceShipMovement::DownRight, | ||
(true, false, _, _) => SpaceShipMovement::Up, | ||
(false, true, _, _) => SpaceShipMovement::Down, | ||
(_, _, true, false) => SpaceShipMovement::Left, | ||
(_, _, false, true) => SpaceShipMovement::Right, | ||
_ => SpaceShipMovement::Rest, | ||
}; | ||
commands.trigger(SpaceShipMovementEvent(movement)) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
use bevy::app::{App, Plugin}; | ||
use bevy::prelude::*; | ||
|
||
use crate::game_component::{Health, Player}; | ||
use crate::states::GameState; | ||
use crate::util::cleanup; | ||
|
||
pub struct HealthDisplayPlugin; | ||
|
||
impl Plugin for HealthDisplayPlugin { | ||
fn build(&self, app: &mut App) { | ||
app.add_systems(OnEnter(GameState::InPlay), display_health) | ||
.add_systems(OnExit(GameState::InPlay), cleanup::<HealthDisplay>) | ||
.add_observer(update_health_text); | ||
} | ||
} | ||
|
||
#[derive(Component)] | ||
struct HealthDisplay; | ||
|
||
#[derive(Component)] | ||
struct PlayerHealthText(u8); | ||
|
||
fn display_health(mut commands: Commands, health_q: Query<(&Health, &Player)>) { | ||
commands | ||
.spawn(( | ||
HealthDisplay, | ||
Node { | ||
position_type: PositionType::Absolute, | ||
top: Val::Px(5.), | ||
left: Val::Px(5.), | ||
display: Display::Flex, | ||
flex_direction: FlexDirection::Column, | ||
..default() | ||
}, | ||
)) | ||
.with_children(|health_display| { | ||
health_display.spawn(Text::new("Health:")); | ||
for (health, player) in health_q.iter() { | ||
health_display | ||
.spawn((Text::new(format!("Player {}: ", player.0)),)) | ||
.with_child(( | ||
PlayerHealthText(player.0), | ||
TextSpan::new(health.0.to_string()), | ||
)); | ||
} | ||
}); | ||
} | ||
|
||
fn update_health_text( | ||
ev: Trigger<OnReplace, Health>, | ||
health_q: Query<(&Health, &Player)>, | ||
mut player_health_text_q: Query<(&mut TextSpan, &PlayerHealthText)>, | ||
) { | ||
let Ok((health, player)) = health_q.get(ev.entity()) else { | ||
warn!("Cannot find player with updated health"); | ||
return; | ||
}; | ||
|
||
for (mut text_span, player_health_text) in player_health_text_q.iter_mut() { | ||
if player_health_text.0 == player.0 { | ||
text_span.0 = health.0.to_string(); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
mod control; | ||
mod health_display; | ||
mod score_display; | ||
|
||
use bevy::prelude::*; | ||
pub struct InPlayPlugin; | ||
|
||
impl Plugin for InPlayPlugin { | ||
fn build(&self, app: &mut App) { | ||
app.add_plugins(( | ||
control::ControlPlugin, | ||
health_display::HealthDisplayPlugin, | ||
score_display::ScoreDisplayPlugin, | ||
)); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
use bevy::app::{App, Plugin}; | ||
use bevy::prelude::*; | ||
|
||
use crate::game_component::{Player, Score}; | ||
use crate::states::GameState; | ||
use crate::util::cleanup; | ||
|
||
pub struct ScoreDisplayPlugin; | ||
|
||
impl Plugin for ScoreDisplayPlugin { | ||
fn build(&self, app: &mut App) { | ||
app.add_systems(OnEnter(GameState::InPlay), display_score) | ||
.add_systems(OnExit(GameState::InPlay), cleanup::<ScoreDisplay>) | ||
.add_observer(update_score_text); | ||
} | ||
} | ||
|
||
#[derive(Component)] | ||
struct ScoreDisplay; | ||
|
||
#[derive(Component)] | ||
struct PlayerScoreText(u8); | ||
|
||
fn display_score(mut commands: Commands, score_q: Query<(&Score, &Player)>) { | ||
commands | ||
.spawn(( | ||
ScoreDisplay, | ||
Node { | ||
position_type: PositionType::Absolute, | ||
left: Val::Px(5.), | ||
top: Val::Px(100.), | ||
display: Display::Flex, | ||
flex_direction: FlexDirection::Column, | ||
..default() | ||
}, | ||
)) | ||
.with_children(|score_display| { | ||
score_display.spawn(Text::new("Score:")); | ||
for (score, player) in score_q.iter() { | ||
score_display | ||
.spawn((Text::new(format!("Player {}: ", player.0)),)) | ||
.with_child(( | ||
PlayerScoreText(player.0), | ||
TextSpan::new(score.0.to_string()), | ||
)); | ||
} | ||
}); | ||
} | ||
|
||
fn update_score_text( | ||
ev: Trigger<OnReplace, Score>, | ||
score_q: Query<(&Score, &Player)>, | ||
mut player_score_text_q: Query<(&mut TextSpan, &PlayerScoreText)>, | ||
) { | ||
let Ok((score, player)) = score_q.get(ev.entity()) else { | ||
warn!("Cannot find player with updated score"); | ||
return; | ||
}; | ||
|
||
for (mut text_span, player_score_text) in player_score_text_q.iter_mut() { | ||
if player_score_text.0 == player.0 { | ||
text_span.0 = score.0.to_string(); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,10 @@ | ||
mod in_game; | ||
mod in_play; | ||
mod ready; | ||
|
||
use bevy::prelude::{App, Plugin}; | ||
pub struct AppGamePlugin; | ||
impl Plugin for AppGamePlugin { | ||
fn build(&self, app: &mut App) { | ||
app.add_plugins(in_game::InGamePlugin); | ||
app.add_plugins((ready::ReadyPlugin, in_play::InPlayPlugin)); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
use bevy::prelude::*; | ||
|
||
use crate::{ | ||
constant::{MOBILE_WINDOW_SIZE, SPACESHIP_SIZE}, | ||
game_component::{Health, Player, Score, Spaceship}, | ||
states::GameState, | ||
ui_component::Velocity, | ||
}; | ||
|
||
pub struct ReadyPlugin; | ||
|
||
impl Plugin for ReadyPlugin { | ||
fn build(&self, app: &mut App) { | ||
app.add_systems( | ||
OnEnter(GameState::Ready), | ||
(spawn_spaceship, setup_score_and_health), | ||
) | ||
.add_systems( | ||
Update, | ||
check_spaceship_position.run_if(in_state(GameState::Ready)), | ||
); | ||
} | ||
} | ||
|
||
fn setup_score_and_health(mut commands: Commands) { | ||
commands.spawn((Score::new(), Player(1))); | ||
commands.spawn((Health::new(), Player(1))); | ||
} | ||
|
||
fn spawn_spaceship(mut commands: Commands) { | ||
commands.spawn(( | ||
Player(1), | ||
Spaceship::new(Vec2::new(0., -MOBILE_WINDOW_SIZE.y / 2. - SPACESHIP_SIZE.y)), | ||
Velocity { x: 0., y: 5. }, | ||
)); | ||
} | ||
|
||
fn check_spaceship_position( | ||
mut next_state: ResMut<NextState<GameState>>, | ||
mut spaceship_query: Query<(&Transform, &mut Velocity), With<Spaceship>>, | ||
) { | ||
let (transform, mut velocity) = spaceship_query.get_single_mut().unwrap(); | ||
if transform.translation.y >= -MOBILE_WINDOW_SIZE.y / 2. + SPACESHIP_SIZE.y { | ||
velocity.y = 0.; | ||
next_state.set(GameState::InPlay); | ||
} | ||
} |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.