Skip to content

Commit

Permalink
Refactor game flow and components: remove in_game module, add game ev…
Browse files Browse the repository at this point in the history
…ents, and update spaceship and health mechanics
  • Loading branch information
ianlauyin committed Feb 21, 2025
1 parent d5864fe commit 9fc41ee
Show file tree
Hide file tree
Showing 23 changed files with 548 additions and 319 deletions.
4 changes: 2 additions & 2 deletions game/src/constant/z_index.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ pub enum ZIndex {
}

impl ZIndex {
pub fn value(&self) -> f32 {
pub fn z_value(&self) -> f32 {
match self {
ZIndex::BACKGROUND => 0.,
ZIndex::STARS => 1.,
Expand All @@ -24,6 +24,6 @@ impl ZIndex {
}

pub fn component(&self) -> BevyZIndex {
BevyZIndex(self.value() as i32)
BevyZIndex(self.z_value() as i32)
}
}
38 changes: 0 additions & 38 deletions game/src/flow/app_game/in_game/control_panel.rs

This file was deleted.

10 changes: 0 additions & 10 deletions game/src/flow/app_game/in_game/mod.rs

This file was deleted.

91 changes: 91 additions & 0 deletions game/src/flow/app_game/in_play/control.rs
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))
}
65 changes: 65 additions & 0 deletions game/src/flow/app_game/in_play/health_display.rs
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();
}
}
}
16 changes: 16 additions & 0 deletions game/src/flow/app_game/in_play/mod.rs
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,
));
}
}
65 changes: 65 additions & 0 deletions game/src/flow/app_game/in_play/score_display.rs
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();
}
}
}
5 changes: 3 additions & 2 deletions game/src/flow/app_game/mod.rs
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));
}
}
47 changes: 47 additions & 0 deletions game/src/flow/app_game/ready.rs
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.
4 changes: 3 additions & 1 deletion game/src/flow/app_menu/main_menu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use bevy::prelude::*;
use crate::res::{ControlMode, ControlOption};
use crate::states::AppState;
use crate::ui_component::{Blink, InteractionUI, MainContainer, SelectableText};
use crate::util::cleanup;

pub struct MainMenuPlugin;

Expand All @@ -21,7 +22,8 @@ impl Plugin for MainMenuPlugin {
handle_start_button_interaction,
)
.run_if(in_state(AppState::MainMenu)),
);
)
.add_systems(OnExit(AppState::MainMenu), cleanup::<MainMenu>);
}
}

Expand Down
2 changes: 1 addition & 1 deletion game/src/flow/shared_system/stars.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ fn spawn_star(commands: &mut Commands, stars_handle: Handle<Image>) {
},
Transform {
scale: Vec2::new(0.8, 0.8).extend(0.),
translation: Vec3::new(0., MOBILE_WINDOW_SIZE.y, ZIndex::STARS.value()),
translation: Vec3::new(0., MOBILE_WINDOW_SIZE.y, ZIndex::STARS.z_value()),
..default()
},
));
Expand Down
Loading

0 comments on commit 9fc41ee

Please sign in to comment.