diff --git a/Cargo.lock b/Cargo.lock index 2ca3d90d..20846253 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -171,6 +171,14 @@ dependencies = [ "libc", ] +[[package]] +name = "another-boids-in-rust" +version = "0.1.0" +dependencies = [ + "bevy", + "bevy_spatial", +] + [[package]] name = "approx" version = "0.5.1" @@ -303,14 +311,6 @@ dependencies = [ "bevy_internal", ] -[[package]] -name = "bevy-testing" -version = "0.1.0" -dependencies = [ - "bevy", - "bevy_spatial", -] - [[package]] name = "bevy_a11y" version = "0.14.0" @@ -412,7 +412,7 @@ dependencies = [ "bevy_macro_utils", "proc-macro2", "quote", - "syn 2.0.69", + "syn 2.0.70", ] [[package]] @@ -496,7 +496,7 @@ checksum = "c8a8173bad3ed53fa158806b1beda147263337d6ef71a093780dd141b74386b1" dependencies = [ "bevy_macro_utils", "quote", - "syn 2.0.69", + "syn 2.0.70", ] [[package]] @@ -545,7 +545,7 @@ dependencies = [ "bevy_macro_utils", "proc-macro2", "quote", - "syn 2.0.69", + "syn 2.0.70", ] [[package]] @@ -605,7 +605,7 @@ dependencies = [ "bevy_macro_utils", "proc-macro2", "quote", - "syn 2.0.69", + "syn 2.0.70", ] [[package]] @@ -732,8 +732,8 @@ checksum = "c3ad860d35d74b35d4d6ae7f656d163b6f475aa2e64fc293ee86ac901977ddb7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.69", - "toml_edit 0.22.14", + "syn 2.0.70", + "toml_edit 0.22.15", ] [[package]] @@ -820,7 +820,7 @@ dependencies = [ "bevy_macro_utils", "proc-macro2", "quote", - "syn 2.0.69", + "syn 2.0.70", "uuid", ] @@ -881,7 +881,7 @@ dependencies = [ "bevy_macro_utils", "proc-macro2", "quote", - "syn 2.0.69", + "syn 2.0.70", ] [[package]] @@ -965,7 +965,7 @@ dependencies = [ "bevy_macro_utils", "proc-macro2", "quote", - "syn 2.0.69", + "syn 2.0.70", ] [[package]] @@ -1085,7 +1085,7 @@ checksum = "ad9db261ab33a046e1f54b35f885a44f21fcc80aa2bc9050319466b88fe58fe3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.69", + "syn 2.0.70", ] [[package]] @@ -1149,7 +1149,7 @@ dependencies = [ "regex", "rustc-hash", "shlex", - "syn 2.0.69", + "syn 2.0.70", ] [[package]] @@ -1246,7 +1246,7 @@ checksum = "1ee891b04274a59bd38b412188e24b849617b2e45a0fd8d057deb63e7403761b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.69", + "syn 2.0.70", ] [[package]] @@ -1277,9 +1277,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.106" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "066fce287b1d4eafef758e89e09d724a24808a9196fe9756b8ca90e86d0719a2" +checksum = "eaff6f8ce506b9773fa786672d63fc7a191ffea1be33f72bbd4aeacefca9ffc8" dependencies = [ "jobserver", "libc", @@ -1659,7 +1659,7 @@ checksum = "fd31dbbd9743684d339f907a87fe212cb7b51d75b9e8e74181fe363199ee9b47" dependencies = [ "proc-macro2", "quote", - "syn 2.0.69", + "syn 2.0.70", ] [[package]] @@ -1785,7 +1785,7 @@ checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742" dependencies = [ "proc-macro2", "quote", - "syn 2.0.69", + "syn 2.0.70", ] [[package]] @@ -1857,9 +1857,9 @@ dependencies = [ [[package]] name = "gilrs-core" -version = "0.5.12" +version = "0.5.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b922f294d9f062af517ea0bd0a036ddcf11c2842211c2f9c71a3ceee859e10b6" +checksum = "bbb5e8d912059b33b463831c16b838d15c4772d584ce332e4a80f6dffdae2bc1" dependencies = [ "core-foundation", "inotify", @@ -1873,7 +1873,7 @@ dependencies = [ "vec_map", "wasm-bindgen", "web-sys", - "windows 0.57.0", + "windows 0.58.0", ] [[package]] @@ -1937,7 +1937,7 @@ dependencies = [ "inflections", "proc-macro2", "quote", - "syn 2.0.69", + "syn 2.0.70", ] [[package]] @@ -2561,7 +2561,7 @@ checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" dependencies = [ "proc-macro2", "quote", - "syn 2.0.69", + "syn 2.0.70", ] [[package]] @@ -2591,7 +2591,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.69", + "syn 2.0.70", ] [[package]] @@ -2947,7 +2947,7 @@ checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" dependencies = [ "proc-macro2", "quote", - "syn 2.0.69", + "syn 2.0.70", ] [[package]] @@ -3272,7 +3272,7 @@ checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222" dependencies = [ "proc-macro2", "quote", - "syn 2.0.69", + "syn 2.0.70", ] [[package]] @@ -3374,9 +3374,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.69" +version = "2.0.70" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "201fcda3845c23e8212cd466bfebf0bd20694490fc0356ae8e428e0824a915a6" +checksum = "2f0209b68b3613b093e0ec905354eccaedcfe83b8cb37cbdeae64026c3064c16" dependencies = [ "proc-macro2", "quote", @@ -3385,9 +3385,9 @@ dependencies = [ [[package]] name = "sysinfo" -version = "0.30.12" +version = "0.30.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "732ffa00f53e6b2af46208fba5718d9662a421049204e156328b66791ffa15ae" +checksum = "0a5b4ddaee55fb2bea2bf0e5000747e5f5c0de765e5a5ff87f4cd106439f4bb3" dependencies = [ "cfg-if", "core-foundation-sys", @@ -3436,7 +3436,7 @@ checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533" dependencies = [ "proc-macro2", "quote", - "syn 2.0.69", + "syn 2.0.70", ] [[package]] @@ -3451,9 +3451,9 @@ dependencies = [ [[package]] name = "tinyvec" -version = "1.7.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce6b6a2fb3a985e99cebfaefa9faa3024743da73304ca1c683a36429613d3d22" +checksum = "445e881f4f6d382d5f27c034e25eb92edd7c784ceab92a0937db7f2e9471b938" dependencies = [ "tinyvec_macros", ] @@ -3483,9 +3483,9 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.22.14" +version = "0.22.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f21c7aaf97f1bd9ca9d4f9e73b0a6c74bd5afef56f2bc931943a6e1c37e04e38" +checksum = "d59a3a72298453f564e2b111fa896f8d07fabb36f51f06d7e875fc5e0b5a3ef1" dependencies = [ "indexmap", "toml_datetime", @@ -3511,7 +3511,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.69", + "syn 2.0.70", ] [[package]] @@ -3618,9 +3618,9 @@ checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" [[package]] name = "uuid" -version = "1.9.1" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5de17fd2f7da591098415cff336e12965a28061ddace43b59cb3c430179c9439" +checksum = "81dfa00651efa65069b0b6b651f4aaa31ba9e3c3ce0137aaad053604ee7e0314" dependencies = [ "getrandom", "serde", @@ -3681,7 +3681,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.69", + "syn 2.0.70", "wasm-bindgen-shared", ] @@ -3715,7 +3715,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.69", + "syn 2.0.70", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -3916,11 +3916,11 @@ dependencies = [ [[package]] name = "windows" -version = "0.57.0" +version = "0.58.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12342cb4d8e3b046f3d80effd474a7a02447231330ef77d71daa6fbc40681143" +checksum = "dd04d41d93c4992d421894c18c8b43496aa748dd4c081bac0dc93eb0489272b6" dependencies = [ - "windows-core 0.57.0", + "windows-core 0.58.0", "windows-targets 0.52.6", ] @@ -3939,19 +3939,20 @@ version = "0.54.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "12661b9c89351d684a50a8a643ce5f608e20243b9fb84687800163429f161d65" dependencies = [ - "windows-result", + "windows-result 0.1.2", "windows-targets 0.52.6", ] [[package]] name = "windows-core" -version = "0.57.0" +version = "0.58.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2ed2439a290666cd67ecce2b0ffaad89c2a56b976b736e6ece670297897832d" +checksum = "6ba6d44ec8c2591c134257ce647b7ea6b20335bf6379a27dac5f1641fcf59f99" dependencies = [ - "windows-implement 0.57.0", - "windows-interface 0.57.0", - "windows-result", + "windows-implement 0.58.0", + "windows-interface 0.58.0", + "windows-result 0.2.0", + "windows-strings", "windows-targets 0.52.6", ] @@ -3963,18 +3964,18 @@ checksum = "942ac266be9249c84ca862f0a164a39533dc2f6f33dc98ec89c8da99b82ea0bd" dependencies = [ "proc-macro2", "quote", - "syn 2.0.69", + "syn 2.0.70", ] [[package]] name = "windows-implement" -version = "0.57.0" +version = "0.58.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9107ddc059d5b6fbfbffdfa7a7fe3e22a226def0b2608f72e9d552763d3e1ad7" +checksum = "2bbd5b46c938e506ecbce286b6628a02171d56153ba733b6c741fc627ec9579b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.69", + "syn 2.0.70", ] [[package]] @@ -3985,18 +3986,18 @@ checksum = "da33557140a288fae4e1d5f8873aaf9eb6613a9cf82c3e070223ff177f598b60" dependencies = [ "proc-macro2", "quote", - "syn 2.0.69", + "syn 2.0.70", ] [[package]] name = "windows-interface" -version = "0.57.0" +version = "0.58.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29bee4b38ea3cde66011baa44dba677c432a78593e202392d1e9070cf2a7fca7" +checksum = "053c4c462dc91d3b1504c6fe5a726dd15e216ba718e84a0e46a88fbe5ded3515" dependencies = [ "proc-macro2", "quote", - "syn 2.0.69", + "syn 2.0.70", ] [[package]] @@ -4008,6 +4009,25 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "windows-result" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-strings" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" +dependencies = [ + "windows-result 0.2.0", + "windows-targets 0.52.6", +] + [[package]] name = "windows-sys" version = "0.45.0" @@ -4346,5 +4366,5 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.69", + "syn 2.0.70", ] diff --git a/Cargo.toml b/Cargo.toml index 43645bf9..1e76c205 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "bevy-testing" +name = "another-boids-in-rust" version = "0.1.0" edition = "2021" diff --git a/src/breakout_plugin.rs b/src/breakout_plugin.rs deleted file mode 100644 index b9ecaaee..00000000 --- a/src/breakout_plugin.rs +++ /dev/null @@ -1,371 +0,0 @@ -use bevy::{ - math::bounding::{Aabb2d, BoundingCircle, BoundingVolume, IntersectsVolume}, - prelude::*, - sprite::MaterialMesh2dBundle, -}; - -// Using the default 2D camera they correspond 1:1 with screen pixels. -const PADDLE_SIZE: Vec2 = Vec2::new(120.0, 20.0); -const GAP_BETWEEN_PADDLE_AND_FLOOR: f32 = 60.0; -const PADDLE_SPEED: f32 = 500.0; -// How close can the paddle get to the wall -const PADDLE_PADDING: f32 = 10.0; - -// We set the z-value of the ball to 1 so it renders on top in the case of overlapping sprites. -const BALL_STARTING_POSITION: Vec3 = Vec3::new(0.0, -50.0, 1.0); -const BALL_DIAMETER: f32 = 30.; -const BALL_SPEED: f32 = 400.0; -const INITIAL_BALL_DIRECTION: Vec2 = Vec2::new(0.5, -0.5); - -const WALL_THICKNESS: f32 = 10.0; -// x coordinates -const LEFT_WALL: f32 = -450.; -const RIGHT_WALL: f32 = 450.; -// y coordinates -const BOTTOM_WALL: f32 = -300.; -const TOP_WALL: f32 = 300.; - -const BRICK_SIZE: Vec2 = Vec2::new(100., 30.); -// These values are exact -const GAP_BETWEEN_PADDLE_AND_BRICKS: f32 = 270.0; -const GAP_BETWEEN_BRICKS: f32 = 5.0; -// These values are lower bounds, as the number of bricks is computed -const GAP_BETWEEN_BRICKS_AND_CEILING: f32 = 20.0; -const GAP_BETWEEN_BRICKS_AND_SIDES: f32 = 20.0; - -const SCOREBOARD_FONT_SIZE: f32 = 40.0; -const SCOREBOARD_TEXT_PADDING: Val = Val::Px(5.0); - -const BACKGROUND_COLOR: Color = Color::srgb(0.9, 0.9, 0.9); -const PADDLE_COLOR: Color = Color::srgb(0.3, 0.3, 0.7); -const BALL_COLOR: Color = Color::srgb(1.0, 0.5, 0.5); -const BRICK_COLOR: Color = Color::srgb(0.5, 0.5, 1.0); -const WALL_COLOR: Color = Color::srgb(0.8, 0.8, 0.8); -const TEXT_COLOR: Color = Color::srgb(0.5, 0.5, 1.0); -const SCORE_COLOR: Color = Color::srgb(1.0, 0.5, 0.5); - -#[derive(Component)] -struct Paddle; - -#[derive(Component)] -struct Ball; - -#[derive(Component, Deref, DerefMut)] -struct Velocity(Vec2); - -#[derive(Component)] -struct Collider; - -#[derive(Event, Default)] -struct CollisionEvent; - -#[derive(Component)] -struct Brick; - -#[derive(Resource, Deref, DerefMut)] -struct Score(usize); - -#[derive(Component)] -struct ScoreboardUi; - -#[derive(Bundle)] -struct WallBundle { - sprite_bundle: SpriteBundle, - collider: Collider, -} - -impl WallBundle { - fn new(location: WallLocation) -> Self { - WallBundle { - sprite_bundle: SpriteBundle { - transform: Transform { - translation: location.position().extend(0.0), - scale: location.size().extend(1.0), - ..default() - }, - sprite: Sprite { - color: WALL_COLOR, - ..default() - }, - ..default() - }, - collider: Collider, - } - } -} -enum WallLocation { - Right, - Top, - Left, - Bottom, -} - -impl WallLocation { - fn position(&self) -> Vec2 { - match self { - WallLocation::Right => Vec2::new(RIGHT_WALL, 0.0), - WallLocation::Top => Vec2::new(0.0, TOP_WALL), - WallLocation::Left => Vec2::new(LEFT_WALL, 0.0), - WallLocation::Bottom => Vec2::new(0.0, BOTTOM_WALL), - } - } - fn size(&self) -> Vec2 { - let arena_height = TOP_WALL - BOTTOM_WALL; - let arena_width = RIGHT_WALL - LEFT_WALL; - assert!(arena_height > 0.0); - assert!(arena_width > 0.0); - - match self { - WallLocation::Left | WallLocation::Right => { - Vec2::new(WALL_THICKNESS, arena_height + WALL_THICKNESS) - } - WallLocation::Top | WallLocation::Bottom => { - Vec2::new(WALL_THICKNESS + arena_width, WALL_THICKNESS) - } - } - } -} - -enum Collision { - Right, - Top, - Left, - Bottom, -} - -fn ball_collision(ball: BoundingCircle, bounding_box: Aabb2d) -> Option { - if !ball.intersects(&bounding_box) { - return None; - } - - let closest = bounding_box.closest_point(ball.center()); - let offset = ball.center() - closest; - let side = if offset.x.abs() > offset.y.abs() { - if offset.x < 0.0 { - Collision::Left - } else { - Collision::Right - } - } else if offset.y > 0.0 { - Collision::Top - } else { - Collision::Bottom - }; - - Some(side) -} - -pub struct BreakoutPlugin; -impl Plugin for BreakoutPlugin { - fn build(&self, app: &mut App) { - app.insert_resource(Score(0)) - .insert_resource(ClearColor(BACKGROUND_COLOR)) - .add_event::() - .add_systems(Startup, setup) - .add_systems(FixedUpdate, (apply_velocity, move_paddle).chain()) - .add_systems(FixedUpdate, (check_for_collisions, update_scoreboard)); - } -} - -fn setup( - mut commands: Commands, - mut meshes: ResMut>, - mut materials: ResMut>, -) { - commands.spawn(Camera2dBundle::default()); - - // paddle - let paddle_y = BOTTOM_WALL + GAP_BETWEEN_PADDLE_AND_FLOOR; - commands.spawn(( - SpriteBundle { - transform: Transform { - translation: Vec3::new(0.0, paddle_y, 0.0), - scale: PADDLE_SIZE.extend(1.0), - ..default() - }, - sprite: Sprite { - color: PADDLE_COLOR, - ..default() - }, - ..default() - }, - Paddle, - Collider, - )); - - // ball - commands.spawn(( - MaterialMesh2dBundle { - mesh: meshes.add(Circle::default()).into(), - material: materials.add(BALL_COLOR), - transform: Transform::from_translation(BALL_STARTING_POSITION) - .with_scale(Vec2::splat(BALL_DIAMETER).extend(1.0)), - ..default() - }, - Ball, - Velocity(INITIAL_BALL_DIRECTION.normalize() * BALL_SPEED), - )); - - // scoreboard - commands.spawn(( - ScoreboardUi, - TextBundle::from_sections([ - TextSection::new( - "Score: ", - TextStyle { - font_size: SCOREBOARD_FONT_SIZE, - color: TEXT_COLOR, - ..default() - }, - ), - TextSection::from_style(TextStyle { - font_size: SCOREBOARD_FONT_SIZE, - color: SCORE_COLOR, - ..default() - }), - ]) - .with_style(Style { - position_type: PositionType::Absolute, - top: SCOREBOARD_TEXT_PADDING, - left: SCOREBOARD_TEXT_PADDING, - ..default() - }), - )); - - // walls - commands.spawn(WallBundle::new(WallLocation::Left)); - commands.spawn(WallBundle::new(WallLocation::Right)); - commands.spawn(WallBundle::new(WallLocation::Bottom)); - commands.spawn(WallBundle::new(WallLocation::Top)); - - // bricks - let total_width_of_bricks = (RIGHT_WALL - LEFT_WALL) - 2.0 * GAP_BETWEEN_BRICKS_AND_SIDES; - let bottom_edge_of_bricks = paddle_y + GAP_BETWEEN_PADDLE_AND_BRICKS; - let total_height_of_bricks = TOP_WALL - bottom_edge_of_bricks - GAP_BETWEEN_BRICKS_AND_CEILING; - - assert!(total_width_of_bricks > 0.0); - assert!(total_height_of_bricks > 0.0); - - // brick count is dynamic based on available game board space (and brick size, but that's a constant) - let n_columns = (total_width_of_bricks / (BRICK_SIZE.x + GAP_BETWEEN_BRICKS)).floor() as usize; - let n_rows = (total_height_of_bricks / (BRICK_SIZE.y + GAP_BETWEEN_BRICKS)).floor() as usize; - let n_vertical_gaps = n_columns - 1; - - let center_of_bricks = (LEFT_WALL + RIGHT_WALL) / 2.0; - let left_edge_of_bricks = center_of_bricks - - (n_columns as f32 / 2.0 * BRICK_SIZE.x) - - n_vertical_gaps as f32 / 2.0 * GAP_BETWEEN_BRICKS; - - // Bevy uses the center as the origin of an entity - // so calculate offset from left-edge to get the correct position - let offset_x = left_edge_of_bricks + BRICK_SIZE.x / 2.0; - let offset_y = bottom_edge_of_bricks + BRICK_SIZE.y / 2.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), - ); - // spawn sprite, brick, collider - commands.spawn(( - SpriteBundle { - transform: Transform { - translation: brick_position.extend(0.0), - scale: BRICK_SIZE.extend(1.0), - ..default() - }, - sprite: Sprite { - color: BRICK_COLOR, - ..default() - }, - ..default() - }, - Brick, - Collider, - )); - } - } -} - -fn apply_velocity(mut query: Query<(&mut Transform, &Velocity)>, time: Res