Skip to main content

cubes_demo/
cubes_demo.rs

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}