Skip to content

Commit

Permalink
Update breakout to use Required Components (#16577)
Browse files Browse the repository at this point in the history
# 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 <[email protected]>
Co-authored-by: Joona Aalto <[email protected]>
  • Loading branch information
3 people authored Dec 7, 2024
1 parent f5de3f0 commit 48fb4aa
Showing 1 changed file with 20 additions and 23 deletions.
43 changes: 20 additions & 23 deletions examples/games/breakout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,9 +89,6 @@ struct Ball;
#[derive(Component, Deref, DerefMut)]
struct Velocity(Vec2);

#[derive(Component)]
struct Collider;

#[derive(Event, Default)]
struct CollisionEvent;

Expand All @@ -101,15 +98,14 @@ struct Brick;
#[derive(Resource, Deref)]
struct CollisionSound(Handle<AudioSource>);

// 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 {
Expand Down Expand Up @@ -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),
Expand All @@ -165,8 +163,7 @@ impl WallBundle {
scale: location.size().extend(1.0),
..default()
},
collider: Collider,
}
)
}
}

Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit 48fb4aa

Please sign in to comment.