Skip to content

Commit

Permalink
[examples] Update to bevy 0.10 API
Browse files Browse the repository at this point in the history
  • Loading branch information
Henauxg committed Mar 7, 2023
1 parent 265696e commit d1c5bcf
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 94 deletions.
146 changes: 66 additions & 80 deletions examples/breakout/breakout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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},
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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();
}
16 changes: 8 additions & 8 deletions examples/breakout/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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},
Expand Down Expand Up @@ -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>,
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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>,
) {
Expand Down Expand Up @@ -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 => {
Expand Down
2 changes: 1 addition & 1 deletion examples/breakout/server.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::{collections::HashMap};
use std::collections::HashMap;

use bevy::{
prelude::{
Expand Down
13 changes: 8 additions & 5 deletions examples/chat/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::{
Expand Down Expand Up @@ -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()
Expand Down Expand Up @@ -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();
}

0 comments on commit d1c5bcf

Please sign in to comment.