adding some gamestate timers

main
Jordan Orelli 1 year ago
parent 9275445bfe
commit 042e7357fa

@ -1,7 +1,7 @@
use crate::game::Throw; use crate::game::Throw;
use bevy::prelude::*; use bevy::prelude::*;
#[derive(Event, Default)] #[derive(Event, Default, Debug)]
pub(crate) struct Play; pub(crate) struct Play;
#[derive(Event)] #[derive(Event)]

@ -6,13 +6,6 @@ use crate::{events::Events, play::Play, start_menu::StartMenu};
/// The top-level structure of our game, which is a bevy plugin /// The top-level structure of our game, which is a bevy plugin
pub struct Game {} pub struct Game {}
#[derive(Debug)]
pub(crate) enum Throw {
Rock,
Paper,
Scissors,
}
impl Plugin for Game { impl Plugin for Game {
fn build(&self, app: &mut App) { fn build(&self, app: &mut App) {
info!("Building rps Plugin"); info!("Building rps Plugin");
@ -25,3 +18,10 @@ impl Default for Game {
Self {} Self {}
} }
} }
#[derive(Debug, Clone)]
pub(crate) enum Throw {
Rock,
Paper,
Scissors,
}

@ -2,6 +2,7 @@ mod events;
mod game; mod game;
mod play; mod play;
mod start_menu; mod start_menu;
mod ui;
use bevy::prelude::*; use bevy::prelude::*;

@ -1,19 +1,80 @@
use crate::{events, game::Throw}; use crate::{events, game::Throw, ui};
use bevy::ecs::system::EntityCommand; use bevy::ecs::system::EntityCommand;
use bevy::prelude::*; use bevy::prelude::*;
use bevy::text::DEFAULT_FONT_HANDLE; use bevy::text::DEFAULT_FONT_HANDLE;
use bevy::time::Stopwatch;
use std::time::Duration;
#[derive(Debug)]
pub enum Phase {
BeforePlay,
Countdown(Timer),
Reveal(Timer),
AfterPlay,
}
#[derive(Resource, Debug)]
pub struct Board {
phase: Phase,
p1_throw: Option<Throw>,
p2_throw: Option<Throw>,
}
impl Board {
fn new() -> Self {
Self {
phase: Phase::BeforePlay,
p1_throw: None,
p2_throw: None,
}
}
}
pub struct Play {} pub struct Play {}
pub(crate) enum GameEvent {
RoundBegin,
RoundEnd,
}
#[derive(Component, Debug)] #[derive(Component, Debug)]
struct Action { struct Action {
throw: Throw, throw: Throw,
} }
fn handle_actions(actions: Query<(&Interaction, &Action), (Changed<Interaction>, With<Action>)>) { fn advance_game_state(time: Res<Time>, mut board: ResMut<Board>) {
// add some stuff here
match &mut board.phase {
Phase::BeforePlay => {}
Phase::Countdown(timer) => {
timer.tick(time.delta());
if timer.just_finished() {
info!("Countdown timer finished");
board.phase = Phase::Reveal(Timer::new(Duration::from_secs(3), TimerMode::Once));
}
}
Phase::Reveal(timer) => {
timer.tick(time.delta());
if timer.just_finished() {
info!("Reveal timer finished");
board.phase = Phase::AfterPlay;
}
}
Phase::AfterPlay => {}
}
}
fn handle_actions(
actions: Query<(&Interaction, &Action), (Changed<Interaction>, With<Action>)>,
mut board: ResMut<Board>,
) {
for (interaction, action) in actions.iter() { for (interaction, action) in actions.iter() {
if matches!(interaction, Interaction::Pressed) { if matches!(interaction, Interaction::Pressed) {
info!("Clicked {throw:?}", throw = action.throw); info!("Clicked {throw:?}", throw = action.throw);
if board.p1_throw.is_some() {
info!("Replacing existing throw");
}
board.p1_throw = Some(action.throw.clone())
} }
} }
} }
@ -28,22 +89,27 @@ impl EntityCommand for ActionButton {
let style = TextStyle { let style = TextStyle {
font: DEFAULT_FONT_HANDLE.typed(), font: DEFAULT_FONT_HANDLE.typed(),
font_size: 24.0, font_size: 24.0,
color: Color::WHITE, color: Color::BLACK,
}; };
let button = world let button = world
.spawn(( .spawn((
Name::new(format!("{action} button", action = &self.text)), Name::new(format!("{action} button", action = &self.text)),
Action { throw: self.throw }, Action { throw: self.throw },
ui::HoverColor {
on: Color::BEIGE.into(),
off: Color::BISQUE.into(),
},
ButtonBundle { ButtonBundle {
style: Style { style: Style {
align_items: AlignItems::Center,
width: Val::Percent(100.0), width: Val::Percent(100.0),
height: Val::Percent(100.0), height: Val::Percent(100.0),
border: UiRect::all(Val::Px(2.0)), border: UiRect::all(Val::Px(2.0)),
align_items: AlignItems::Center,
justify_content: JustifyContent::Center,
..default() ..default()
}, },
border_color: Color::RED.into(), border_color: Color::BLACK.into(),
background_color: Color::GRAY.into(), background_color: Color::GRAY.into(),
..default() ..default()
}, },
@ -60,44 +126,62 @@ impl EntityCommand for ActionButton {
} }
} }
fn handle_play(mut events: EventReader<events::Play>, mut commands: Commands) { fn header() -> impl Bundle {
for _ in events.iter() { (
let mut bg = commands.spawn(( Name::new("Header"),
Name::new("Play Container"),
NodeBundle { NodeBundle {
style: Style { style: Style {
display: Display::Flex, display: Display::Flex,
flex_direction: FlexDirection::Column, height: Val::Percent(10.0),
height: Val::Percent(100.0),
width: Val::Percent(100.0), width: Val::Percent(100.0),
border: UiRect {
bottom: Val::Px(2.0),
..default() ..default()
}, },
border_color: Color::RED.into(), ..default()
},
border_color: Color::BLACK.into(),
background_color: Color::GRAY.into(), background_color: Color::GRAY.into(),
..default() ..default()
}, },
)); )
}
bg.with_children(|bg| { fn handle_play(
bg.spawn(( mut events: EventReader<events::Play>,
Name::new("Header"), mut commands: Commands,
mut board: ResMut<Board>,
) {
if events.is_empty() {
return;
}
info!("handling play events");
for e in events.iter() {
info!("play event {e:?}");
}
board.phase = Phase::Countdown(Timer::new(Duration::from_millis(3000), TimerMode::Once));
info!("Starting countdown");
let mut bg = commands.spawn((
Name::new("Play Container"),
NodeBundle { NodeBundle {
style: Style { style: Style {
display: Display::Flex, display: Display::Flex,
height: Val::Percent(10.0), flex_direction: FlexDirection::Column,
height: Val::Percent(100.0),
width: Val::Percent(100.0), width: Val::Percent(100.0),
border: UiRect {
bottom: Val::Px(2.0),
..default() ..default()
}, },
..default() border_color: Color::RED.into(),
},
border_color: Color::BLACK.into(),
background_color: Color::GRAY.into(), background_color: Color::GRAY.into(),
..default() ..default()
}, },
)); ));
bg.with_children(|bg| {
// bg.add_command(x);
bg.spawn(header());
bg.spawn(( bg.spawn((
Name::new("Play"), Name::new("Play"),
NodeBundle { NodeBundle {
@ -126,6 +210,7 @@ fn handle_play(mut events: EventReader<events::Play>, mut commands: Commands) {
display: Display::Flex, display: Display::Flex,
height: Val::Percent(40.0), height: Val::Percent(40.0),
width: Val::Percent(100.0), width: Val::Percent(100.0),
padding: UiRect::all(Val::Px(30.0)),
..default() ..default()
}, },
background_color: Color::GRAY.into(), background_color: Color::GRAY.into(),
@ -147,10 +232,10 @@ fn handle_play(mut events: EventReader<events::Play>, mut commands: Commands) {
}); });
}); });
} }
}
impl Plugin for Play { impl Plugin for Play {
fn build(&self, app: &mut App) { fn build(&self, app: &mut App) {
app.add_systems(Update, (handle_play, handle_actions)); app.add_systems(Update, (handle_play, handle_actions, advance_game_state));
app.insert_resource(Board::new());
} }
} }

@ -1,4 +1,7 @@
use crate::events; use crate::{
events,
ui::{self, HoverColor},
};
use bevy::ecs::system::EntityCommand; use bevy::ecs::system::EntityCommand;
use bevy::prelude::*; use bevy::prelude::*;
use bevy::text::DEFAULT_FONT_HANDLE; use bevy::text::DEFAULT_FONT_HANDLE;
@ -9,12 +12,6 @@ pub struct StartMenu {}
#[derive(Component)] #[derive(Component)]
struct MainMenu; struct MainMenu;
#[derive(Component)]
struct HoverColor {
on: Color,
off: Color,
}
#[derive(Component)] #[derive(Component)]
struct Title; struct Title;
@ -48,31 +45,13 @@ fn thicc_button() -> impl Bundle {
} }
} }
fn hover_colors(
mut actions: Query<
(&Interaction, &mut BackgroundColor, &HoverColor),
(Changed<Interaction>, With<HoverColor>),
>,
) {
for (act, mut bg, colors) in &mut actions {
match act {
Interaction::Pressed => {}
Interaction::Hovered => {
bg.0 = colors.on;
}
Interaction::None => {
bg.0 = colors.off;
}
}
}
}
fn click_play( fn click_play(
mut actions: Query<&Interaction, (Changed<Interaction>, With<PlayButton>)>, mut actions: Query<&Interaction, (Changed<Interaction>, With<PlayButton>)>,
mut play: EventWriter<events::Play>, mut play: EventWriter<events::Play>,
) { ) {
for interaction in &mut actions { for interaction in &mut actions {
if matches!(interaction, Interaction::Pressed) { if matches!(interaction, Interaction::Pressed) {
info!("sending play event");
play.send_default(); play.send_default();
} }
} }
@ -83,8 +62,9 @@ fn handle_play(
mut events: EventReader<events::Play>, mut events: EventReader<events::Play>,
mut commands: Commands, mut commands: Commands,
) { ) {
for _ in events.iter() { for e in events.iter() {
info!("Handling Play event"); info!("Handling Play event");
for m in menu.iter() { for m in menu.iter() {
commands.entity(m).despawn_recursive(); commands.entity(m).despawn_recursive();
} }
@ -202,7 +182,8 @@ fn setup(mut commands: Commands) {
impl Plugin for StartMenu { impl Plugin for StartMenu {
fn build(&self, app: &mut App) { fn build(&self, app: &mut App) {
app.add_plugins(ui::Plugin {});
app.add_systems(Startup, setup); app.add_systems(Startup, setup);
app.add_systems(Update, (hover_colors, click_quit, click_play, handle_play)); app.add_systems(Update, (click_quit, click_play, handle_play));
} }
} }

@ -0,0 +1,60 @@
use bevy::prelude::*;
#[derive(Component)]
pub(crate) struct HoverColor {
pub on: Color,
pub off: Color,
}
pub struct Plugin;
impl bevy::app::Plugin for Plugin {
fn build(&self, app: &mut App) {
app.add_systems(Update, hover_colors);
}
}
fn hover_colors(
mut actions: Query<
(&Interaction, &mut BackgroundColor, &HoverColor),
(Changed<Interaction>, With<HoverColor>),
>,
) {
for (act, mut bg, colors) in &mut actions {
match act {
Interaction::Pressed => {}
Interaction::Hovered => {
bg.0 = colors.on;
}
Interaction::None => {
bg.0 = colors.off;
}
}
}
}
pub(crate) fn row() -> NodeBundle {
NodeBundle {
style: Style {
display: Display::Flex,
flex_direction: FlexDirection::Row,
height: Val::Percent(100.0),
width: Val::Percent(100.0),
..default()
},
..default()
}
}
pub(crate) fn column() -> NodeBundle {
NodeBundle {
style: Style {
display: Display::Flex,
flex_direction: FlexDirection::Column,
height: Val::Percent(100.0),
width: Val::Percent(100.0),
..default()
},
..default()
}
}
Loading…
Cancel
Save