aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--examples/breakout/breakout.rs146
-rw-r--r--examples/breakout/client.rs16
-rw-r--r--examples/breakout/server.rs2
-rw-r--r--examples/chat/client.rs13
4 files changed, 83 insertions, 94 deletions
diff --git a/examples/breakout/breakout.rs b/examples/breakout/breakout.rs
index 31fcf01..56f9053 100644
--- a/examples/breakout/breakout.rs
+++ b/examples/breakout/breakout.rs
@@ -3,7 +3,7 @@
use std::net::{IpAddr, Ipv4Addr};
-use bevy::{ecs::schedule::ShouldRun, prelude::*, time::FixedTimestep};
+use bevy::prelude::*;
use bevy_quinnet::{
client::QuinnetClientPlugin,
server::{QuinnetServerPlugin, Server},
@@ -47,8 +47,9 @@ const GAP_BETWEEN_BRICKS: f32 = 5.0;
// These values are lower bounds, as the number of bricks is computed
const GAP_BETWEEN_BRICKS_AND_SIDES: f32 = 20.0;
-#[derive(Clone, Eq, PartialEq, Debug, Hash)]
+#[derive(Default, Clone, Eq, PartialEq, Debug, Hash, States)]
enum GameState {
+ #[default]
MainMenu,
HostingLobby,
JoiningLobby,
@@ -105,90 +106,75 @@ impl WallLocation {
}
}
+fn server_is_listening(server: Res<Server>) -> bool {
+ server.is_listening()
+}
+
+fn game_is_running(current_state: Res<State<GameState>>) -> bool {
+ current_state.0 == GameState::Running
+}
+
fn main() {
- App::new()
- .add_plugins(DefaultPlugins)
+ let mut app = App::new();
+ app.add_plugins(DefaultPlugins)
.add_plugin(QuinnetServerPlugin::default())
- .add_plugin(QuinnetClientPlugin::default())
- .add_event::<CollisionEvent>()
- .add_state(GameState::MainMenu)
- // Resources
- .insert_resource(ClearColor(BACKGROUND_COLOR))
+ .add_plugin(QuinnetClientPlugin::default());
+ app.add_event::<CollisionEvent>();
+ app.add_state::<GameState>();
+ app.insert_resource(ClearColor(BACKGROUND_COLOR))
.insert_resource(server::Players::default())
.insert_resource(client::Scoreboard { score: 0 })
.insert_resource(client::ClientData::default())
.insert_resource(client::NetworkMapping::default())
- .insert_resource(client::BricksMapping::default())
- // Main menu
- .add_system_set(
- SystemSet::on_enter(GameState::MainMenu).with_system(client::setup_main_menu),
- )
- .add_system_set(
- SystemSet::on_update(GameState::MainMenu).with_system(client::handle_menu_buttons),
- )
- .add_system_set(
- SystemSet::on_exit(GameState::MainMenu).with_system(client::teardown_main_menu),
+ .insert_resource(client::BricksMapping::default());
+
+ // Main menu
+ app.add_system(bevy::window::close_on_esc)
+ .add_system(client::setup_main_menu.in_schedule(OnEnter(GameState::MainMenu)))
+ .add_system(client::handle_menu_buttons.in_set(OnUpdate(GameState::MainMenu)))
+ .add_system(client::teardown_main_menu.in_schedule(OnExit(GameState::MainMenu)));
+ // Hosting a server on a client
+ app.add_systems(
+ (server::start_listening, client::start_connection)
+ .in_schedule(OnEnter(GameState::HostingLobby)),
+ )
+ .add_systems(
+ (
+ server::handle_client_messages,
+ server::handle_server_events,
+ client::handle_server_messages,
)
- // Hosting a server on a client
- .add_system_set(
- SystemSet::on_enter(GameState::HostingLobby)
- .with_system(server::start_listening)
- .with_system(client::start_connection),
+ .in_set(OnUpdate(GameState::HostingLobby)),
+ );
+ // or just Joining as a client
+ app.add_system(client::start_connection.in_schedule(OnEnter(GameState::JoiningLobby)))
+ .add_system(client::handle_server_messages.in_set(OnUpdate(GameState::JoiningLobby)));
+ // Running the game.
+ // Every app is a client
+ app.add_system(client::setup_breakout.in_schedule(OnEnter(GameState::Running)))
+ .add_systems(
+ (
+ client::handle_server_messages.before(client::apply_velocity),
+ client::apply_velocity,
+ client::move_paddle,
+ client::update_scoreboard,
+ client::play_collision_sound,
+ )
+ .distributive_run_if(game_is_running)
+ .in_schedule(CoreSchedule::FixedUpdate),
+ );
+ // But hosting apps are also a server
+ app.add_systems(
+ (
+ server::handle_client_messages.before(server::update_paddles),
+ server::update_paddles.before(server::check_for_collisions),
+ server::apply_velocity.before(server::check_for_collisions),
+ server::check_for_collisions,
)
- .add_system_set(
- SystemSet::on_update(GameState::HostingLobby)
- .with_system(server::handle_client_messages)
- .with_system(server::handle_server_events)
- .with_system(client::handle_server_messages),
- )
- // or just Joining as a client
- .add_system_set(
- SystemSet::on_enter(GameState::JoiningLobby).with_system(client::start_connection),
- )
- .add_system_set(
- SystemSet::on_update(GameState::JoiningLobby)
- .with_system(client::handle_server_messages),
- )
- // Running the game.
- // Every app is a client
- .add_system_set(SystemSet::on_enter(GameState::Running).with_system(client::setup_breakout))
- .add_system_set(
- SystemSet::new()
- // https://github.com/bevyengine/bevy/issues/1839
- // Run on a fixed Timestep,on all clients, in GameState::Running
- .with_run_criteria(FixedTimestep::step(TIME_STEP as f64).pipe(
- |In(input): In<ShouldRun>, state: Res<State<GameState>>| match state.current() {
- GameState::Running => input,
- _ => ShouldRun::No,
- },
- ))
- .with_system(client::handle_server_messages.before(client::apply_velocity))
- .with_system(client::apply_velocity)
- .with_system(client::move_paddle)
- .with_system(client::update_scoreboard)
- .with_system(client::play_collision_sound.after(client::handle_server_messages)),
- )
- // But hosting apps are also a server
- .add_system_set(
- SystemSet::new()
- // https://github.com/bevyengine/bevy/issues/1839
- // Run on a fixed Timestep, only for the hosting client, in GameState::Running
- .with_run_criteria(FixedTimestep::step(TIME_STEP as f64).pipe(
- |In(input): In<ShouldRun>,
- state: Res<State<GameState>>,
- server: Res<Server>| match state.current() {
- GameState::Running => match server.is_listening() {
- true => input,
- false => ShouldRun::No,
- },
- _ => ShouldRun::No,
- },
- ))
- .with_system(server::handle_client_messages.before(server::update_paddles))
- .with_system(server::update_paddles.before(server::check_for_collisions))
- .with_system(server::apply_velocity.before(server::check_for_collisions))
- .with_system(server::check_for_collisions),
- )
- .add_system(bevy::window::close_on_esc)
- .run();
+ .distributive_run_if(server_is_listening)
+ .distributive_run_if(game_is_running)
+ .in_schedule(CoreSchedule::FixedUpdate),
+ );
+
+ app.run();
}
diff --git a/examples/breakout/client.rs b/examples/breakout/client.rs
index be4435a..e418757 100644
--- a/examples/breakout/client.rs
+++ b/examples/breakout/client.rs
@@ -4,8 +4,8 @@ use bevy::{
prelude::{
default, AssetServer, Audio, BuildChildren, Bundle, Button, ButtonBundle, Camera2dBundle,
Changed, Color, Commands, Component, DespawnRecursiveExt, Entity, EventReader, EventWriter,
- Input, KeyCode, Local, PlaybackSettings, Query, Res, ResMut, Resource, State, TextBundle,
- Transform, Vec2, Vec3, With, Without,
+ Input, KeyCode, Local, NextState, PlaybackSettings, Query, Res, ResMut, Resource,
+ TextBundle, Transform, Vec2, Vec3, With, Without,
},
sprite::{Sprite, SpriteBundle},
text::{Text, TextSection, TextStyle},
@@ -194,7 +194,7 @@ pub(crate) fn handle_server_messages(
mut client: ResMut<Client>,
mut client_data: ResMut<ClientData>,
mut entity_mapping: ResMut<NetworkMapping>,
- mut game_state: ResMut<State<GameState>>,
+ mut next_state: ResMut<NextState<GameState>>,
mut paddles: Query<&mut Transform, With<Paddle>>,
mut balls: Query<(&mut Transform, &mut Velocity, &mut Sprite), (With<Ball>, Without<Paddle>)>,
mut bricks: ResMut<BricksMapping>,
@@ -240,7 +240,7 @@ pub(crate) fn handle_server_messages(
rows,
columns,
} => spawn_bricks(&mut commands, &mut bricks, offset, rows, columns),
- ServerMessage::StartGame {} => game_state.set(GameState::Running).unwrap(),
+ ServerMessage::StartGame {} => next_state.set(GameState::Running),
ServerMessage::BrickDestroyed {
by_client_id,
brick_id,
@@ -324,7 +324,7 @@ pub(crate) fn update_scoreboard(
}
pub(crate) fn play_collision_sound(
- collision_events: EventReader<CollisionEvent>,
+ mut collision_events: EventReader<CollisionEvent>,
audio: Res<Audio>,
sound: Res<CollisionSound>,
) {
@@ -392,15 +392,15 @@ pub(crate) fn handle_menu_buttons(
(&Interaction, &mut BackgroundColor, &MenuItem),
(Changed<Interaction>, With<Button>),
>,
- mut game_state: ResMut<State<GameState>>,
+ mut next_state: ResMut<NextState<GameState>>,
) {
for (interaction, mut color, item) in &mut interaction_query {
match *interaction {
Interaction::Clicked => {
*color = PRESSED_BUTTON_COLOR.into();
match item {
- MenuItem::Host => game_state.set(GameState::HostingLobby).unwrap(),
- MenuItem::Join => game_state.set(GameState::JoiningLobby).unwrap(),
+ MenuItem::Host => next_state.set(GameState::HostingLobby),
+ MenuItem::Join => next_state.set(GameState::JoiningLobby),
}
}
Interaction::Hovered => {
diff --git a/examples/breakout/server.rs b/examples/breakout/server.rs
index f2389bd..9be514e 100644
--- a/examples/breakout/server.rs
+++ b/examples/breakout/server.rs
@@ -1,4 +1,4 @@
-use std::{collections::HashMap};
+use std::collections::HashMap;
use bevy::{
prelude::{
diff --git a/examples/chat/client.rs b/examples/chat/client.rs
index fae4976..990efa4 100644
--- a/examples/chat/client.rs
+++ b/examples/chat/client.rs
@@ -8,8 +8,8 @@ use bevy::{
app::{AppExit, ScheduleRunnerPlugin},
log::LogPlugin,
prelude::{
- info, warn, App, Commands, CoreStage, Deref, DerefMut, EventReader, EventWriter, Res,
- ResMut, Resource,
+ info, warn, App, Commands, CoreSet, Deref, DerefMut, EventReader, EventWriter,
+ IntoSystemConfig, Res, ResMut, Resource,
},
};
use bevy_quinnet::{
@@ -128,7 +128,10 @@ fn start_connection(mut client: ResMut<Client>) {
// You can already send message(s) even before being connected, they will be buffered. In this example we will wait for a ConnectionEvent.
}
-fn handle_client_events(connection_events: EventReader<ConnectionEvent>, client: ResMut<Client>) {
+fn handle_client_events(
+ mut connection_events: EventReader<ConnectionEvent>,
+ client: ResMut<Client>,
+) {
if !connection_events.is_empty() {
// We are connected
let username: String = rand::thread_rng()
@@ -160,7 +163,7 @@ fn main() {
.add_system(handle_terminal_messages)
.add_system(handle_server_messages)
.add_system(handle_client_events)
- // CoreStage::PostUpdate so that AppExit events generated in the previous stage are available
- .add_system_to_stage(CoreStage::PostUpdate, on_app_exit)
+ // CoreSet::PostUpdate so that AppExit events generated in the previous stage are available
+ .add_system(on_app_exit.in_base_set(CoreSet::PostUpdate))
.run();
}