aboutsummaryrefslogtreecommitdiff
path: root/examples/breakout/server.rs
diff options
context:
space:
mode:
authorHenauxg <19689618+Henauxg@users.noreply.github.com>2022-11-03 16:57:55 +0100
committerHenauxg <19689618+Henauxg@users.noreply.github.com>2022-11-03 16:57:55 +0100
commita6f63d755caf51cd9866ba5aaf0c9fd3c0d56bde (patch)
tree8c9a9498ea877d6df02893caddf5717e57152c0b /examples/breakout/server.rs
parent4103125aa0f3ad3368ccf97fbdae5eedbe6e7233 (diff)
[breakout:example] Networked bricks spawn
Diffstat (limited to 'examples/breakout/server.rs')
-rw-r--r--examples/breakout/server.rs97
1 files changed, 92 insertions, 5 deletions
diff --git a/examples/breakout/server.rs b/examples/breakout/server.rs
index 663cd00..fb430f4 100644
--- a/examples/breakout/server.rs
+++ b/examples/breakout/server.rs
@@ -15,9 +15,10 @@ use bevy_quinnet::{
use crate::{
protocol::{ClientMessage, PaddleInput, ServerMessage},
- Brick, Collider, Scoreboard, Velocity, BALL_SIZE, BALL_SPEED, BOTTOM_WALL,
+ Collider, Scoreboard, Velocity, BALL_SIZE, BALL_SPEED, BOTTOM_WALL, BRICK_SIZE,
+ GAP_BETWEEN_BRICKS, GAP_BETWEEN_BRICKS_AND_SIDES, GAP_BETWEEN_PADDLE_AND_BRICKS,
GAP_BETWEEN_PADDLE_AND_FLOOR, LEFT_WALL, PADDLE_PADDING, PADDLE_SIZE, PADDLE_SPEED, RIGHT_WALL,
- TIME_STEP, TOP_WALL, WALL_THICKNESS,
+ SERVER_PORT, TIME_STEP, TOP_WALL, WALL_THICKNESS,
};
const GAP_BETWEEN_PADDLE_AND_BALL: f32 = 35.;
@@ -58,13 +59,21 @@ pub(crate) struct Paddle {
player_id: ClientId,
}
+pub type BrickId = u64;
+#[derive(Component)]
+pub(crate) struct Brick(BrickId);
+
#[derive(Component)]
pub(crate) struct Ball;
pub(crate) fn start_listening(mut server: ResMut<Server>) {
server
.start(
- ServerConfigurationData::new("127.0.0.1".to_string(), 6000, "0.0.0.0".to_string()),
+ ServerConfigurationData::new(
+ "127.0.0.1".to_string(),
+ SERVER_PORT,
+ "0.0.0.0".to_string(),
+ ),
CertificateRetrievalMode::GenerateSelfSigned,
)
.unwrap();
@@ -219,7 +228,7 @@ pub(crate) fn apply_velocity(mut query: Query<(&mut Transform, &Velocity), With<
}
fn start_game(commands: &mut Commands, server: &mut ResMut<Server>, players: &ResMut<Players>) {
- // Paddles
+ // Spawn paddles
for (index, (client_id, _)) in players.map.iter().enumerate() {
let paddle = spawn_paddle(commands, *client_id, &PADDLES_STARTING_POSITION[index]);
server
@@ -234,7 +243,7 @@ fn start_game(commands: &mut Commands, server: &mut ResMut<Server>, players: &Re
.unwrap();
}
- // Balls
+ // Spawn balls
for (position, direction) in BALLS_STARTING_POSITION
.iter()
.zip(INITIAL_BALLS_DIRECTION.iter())
@@ -252,6 +261,84 @@ fn start_game(commands: &mut Commands, server: &mut ResMut<Server>, players: &Re
.unwrap();
}
+ // Spawn bricks
+ // Negative scales result in flipped sprites / meshes,
+ // which is definitely not what we want here
+ assert!(BRICK_SIZE.x > 0.0);
+ assert!(BRICK_SIZE.y > 0.0);
+
+ let total_width_of_bricks = (RIGHT_WALL - LEFT_WALL) - 2. * GAP_BETWEEN_BRICKS_AND_SIDES;
+ let bottom_edge_of_bricks =
+ BOTTOM_WALL + GAP_BETWEEN_PADDLE_AND_FLOOR + GAP_BETWEEN_PADDLE_AND_BRICKS;
+ let available_height_for_bricks = TOP_WALL
+ - bottom_edge_of_bricks
+ - (GAP_BETWEEN_PADDLE_AND_FLOOR + GAP_BETWEEN_PADDLE_AND_BRICKS);
+
+ assert!(total_width_of_bricks > 0.0);
+ assert!(available_height_for_bricks > 0.0);
+
+ // Given the space available, compute how many rows and columns of bricks we can fit
+ let n_columns = (total_width_of_bricks / (BRICK_SIZE.x + GAP_BETWEEN_BRICKS)).floor() as usize;
+ let n_rows =
+ (available_height_for_bricks / (BRICK_SIZE.y + GAP_BETWEEN_BRICKS)).floor() as usize;
+ let height_occupied_by_bricks =
+ n_rows as f32 * (BRICK_SIZE.y + GAP_BETWEEN_BRICKS) - GAP_BETWEEN_BRICKS;
+ let n_vertical_gaps = n_columns - 1;
+
+ // Because we need to round the number of columns,
+ // the space on the top and sides of the bricks only captures a lower bound, not an exact value
+ let center_of_bricks = (LEFT_WALL + RIGHT_WALL) / 2.0;
+ let left_edge_of_bricks = center_of_bricks
+ // Space taken up by the bricks
+ - (n_columns as f32 / 2.0 * BRICK_SIZE.x)
+ // Space taken up by the gaps
+ - n_vertical_gaps as f32 / 2.0 * GAP_BETWEEN_BRICKS;
+
+ // In Bevy, the `translation` of an entity describes the center point,
+ // not its bottom-left corner
+ let offset_x = left_edge_of_bricks + BRICK_SIZE.x / 2.;
+ let offset_y = bottom_edge_of_bricks
+ + BRICK_SIZE.y / 2.
+ + (available_height_for_bricks - height_occupied_by_bricks) / 2.; // Offset so that both players are at an equal distance of the bricks
+
+ let mut brick_id = 0;
+ for row in 0..n_rows {
+ for column in 0..n_columns {
+ let brick_position = Vec2::new(
+ offset_x + column as f32 * (BRICK_SIZE.x + GAP_BETWEEN_BRICKS),
+ offset_y + row as f32 * (BRICK_SIZE.y + GAP_BETWEEN_BRICKS),
+ );
+
+ // brick
+ commands
+ .spawn()
+ .insert(Brick(brick_id))
+ .insert_bundle(TransformBundle {
+ local: Transform {
+ translation: brick_position.extend(0.0),
+ scale: Vec3::new(BRICK_SIZE.x, BRICK_SIZE.y, 1.0),
+ ..default()
+ },
+ ..default()
+ })
+ .insert(Collider);
+ brick_id += 1;
+ }
+ }
+ server
+ .send_group_message(
+ players.map.keys().into_iter(),
+ ServerMessage::SpawnBricks {
+ offset: Vec2 {
+ x: offset_x,
+ y: offset_y,
+ },
+ rows: n_rows,
+ columns: n_columns,
+ },
+ )
+ .unwrap();
+
server
.send_group_message(players.map.keys().into_iter(), ServerMessage::StartGame {})
.unwrap();