1use bevy::prelude::*;
2use bevy_networker_multiplayer::{NetResource, Replicated, ReplicatedPlugin, sync};
3
4const ADDRESS: &str = "127.0.0.1:5003";
5
6#[sync(prefab(
7 Sprite::from_color(Color::srgb(0.2, 0.8, 1.0), Vec2::splat(32.0),),
8 Transform::from_xyz(0.0, 0.0, 0.0)
9))]
10#[derive(Component)]
11struct Position(Vec2);
12
13#[sync]
14#[derive(Component)]
15struct Velocity(Vec2);
16
17#[derive(Clone, Copy, PartialEq, Eq)]
18enum Mode {
19 Server,
20 Client,
21}
22
23#[derive(Resource, Clone, Copy)]
24struct DemoMode(Mode);
25
26fn main() {
27 let mode = parse_mode();
28
29 let mut app = App::new();
30
31 if mode == Mode::Client {
32 app.add_plugins(DefaultPlugins.set(WindowPlugin {
33 primary_window: Some(Window {
34 title: "Bevy Networker Multiplayer - Cubes".into(),
35 resolution: (960, 540).into(),
36 ..default()
37 }),
38 ..default()
39 }));
40 } else {
41 app.add_plugins(MinimalPlugins);
42 }
43
44 app.add_plugins(ReplicatedPlugin);
45 app.insert_resource(DemoMode(mode));
46 app.add_systems(Startup, setup);
47
48 match mode {
49 Mode::Server => {
50 app.add_systems(Update, server_move_cubes);
51 }
52 Mode::Client => {
53 app.add_systems(Startup, setup_client_window);
54 }
55 }
56
57 app.run();
58}
59
60fn parse_mode() -> Mode {
61 match std::env::args().nth(1).as_deref() {
62 Some("server") => Mode::Server,
63 Some("client") => Mode::Client,
64 _ => {
65 eprintln!("usage: cargo run --example cubes_demo -- [server|client]");
66 std::process::exit(1);
67 }
68 }
69}
70
71fn setup(mut commands: Commands, mut net: ResMut<NetResource>, mode: Res<DemoMode>) {
72 match mode.0 {
73 Mode::Server => {
74 net.start_server(5003);
75 println!("server listening on {ADDRESS}");
76
77 for index in 0..5 {
78 commands.spawn((
79 Replicated,
80 Position(Vec2::new(index as f32 * 80.0 - 160.0, 0.0)),
81 Velocity(Vec2::new(
82 70.0 + index as f32 * 15.0,
83 40.0 + index as f32 * 10.0,
84 )),
85 ));
86 }
87 }
88 Mode::Client => {
89 net.join_server(ADDRESS.to_string());
90 println!("client connected to {ADDRESS}");
91 }
92 }
93}
94
95fn setup_client_window(mut commands: Commands) {
96 commands.spawn(Camera2d);
97}
98
99fn server_move_cubes(time: Res<Time>, mut query: Query<(&mut Position, &mut Velocity)>) {
100 let dt = time.delta_secs();
101
102 for (mut position, mut velocity) in &mut query {
103 position.0 += velocity.0 * dt;
104
105 if position.0.x > 360.0 || position.0.x < -360.0 {
106 velocity.0.x = -velocity.0.x;
107 }
108
109 if position.0.y > 200.0 || position.0.y < -200.0 {
110 velocity.0.y = -velocity.0.y;
111 }
112 }
113}