From 48fb4aa6d549f3dcb915db2fed3193a1de930b31 Mon Sep 17 00:00:00 2001 From: Emad Ali <70924991+Mclilzee@users.noreply.github.com> Date: Sat, 7 Dec 2024 01:21:26 +0100 Subject: [PATCH] Update breakout to use Required Components (#16577) # Objective This PR update breakout to use the new 0.15 Required Component feature instead of the Bundle. Add more information in the comment about where to find more info about Required Components. ## Solution Replace `#[derive(Bundle)]` with a new Wall component and `#[require()]` Macro to include the other components. ## Testing Tested with `cargo test` as well tested the game manually with `cargo run --example breakout` It looks to me that it works like it used to before the changes. Tested on Arch Linux, Wayland --------- Co-authored-by: Arnav Mummineni <45217840+RCoder01@users.noreply.github.com> Co-authored-by: Joona Aalto --- examples/games/breakout.rs | 43 ++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 23 deletions(-) diff --git a/examples/games/breakout.rs b/examples/games/breakout.rs index dc1fd1a9281d0..cc53437519410 100644 --- a/examples/games/breakout.rs +++ b/examples/games/breakout.rs @@ -89,9 +89,6 @@ struct Ball; #[derive(Component, Deref, DerefMut)] struct Velocity(Vec2); -#[derive(Component)] -struct Collider; - #[derive(Event, Default)] struct CollisionEvent; @@ -101,15 +98,14 @@ struct Brick; #[derive(Resource, Deref)] struct CollisionSound(Handle); -// This bundle is a collection of the components that define a "wall" in our game -#[derive(Bundle)] -struct WallBundle { - // You can nest bundles inside of other bundles like this - // Allowing you to compose their functionality - sprite: Sprite, - transform: Transform, - collider: Collider, -} +// Default must be implemented to define this as a required component for the Wall component below +#[derive(Component, Default)] +struct Collider; + +// This is a collection of the components that define a "Wall" in our game +#[derive(Component)] +#[require(Sprite, Transform, Collider)] +struct Wall; /// Which side of the arena is this wall located on? enum WallLocation { @@ -149,13 +145,15 @@ impl WallLocation { } } -impl WallBundle { +impl Wall { // This "builder method" allows us to reuse logic across our wall entities, // making our code easier to read and less prone to bugs when we change the logic - fn new(location: WallLocation) -> WallBundle { - WallBundle { - sprite: Sprite::from_color(WALL_COLOR, Vec2::ONE), - transform: Transform { + // Notice the use of Sprite and Transform alongside Wall, overwriting the default values defined for the required components + fn new(location: WallLocation) -> (Wall, Sprite, Transform) { + ( + Wall, + Sprite::from_color(WALL_COLOR, Vec2::ONE), + Transform { // We need to convert our Vec2 into a Vec3, by giving it a z-coordinate // This is used to determine the order of our sprites translation: location.position().extend(0.0), @@ -165,8 +163,7 @@ impl WallBundle { scale: location.size().extend(1.0), ..default() }, - collider: Collider, - } + ) } } @@ -242,10 +239,10 @@ fn setup( )); // 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)); + commands.spawn(Wall::new(WallLocation::Left)); + commands.spawn(Wall::new(WallLocation::Right)); + commands.spawn(Wall::new(WallLocation::Bottom)); + commands.spawn(Wall::new(WallLocation::Top)); // Bricks let total_width_of_bricks = (RIGHT_WALL - LEFT_WALL) - 2. * GAP_BETWEEN_BRICKS_AND_SIDES;