Breather
Let's refactor a little to give us time to process this betrayal and think of a way to get our revenge.
You can move things around and maybe create modules.
We're using an initial size in a few spots, we can abstract it.
const INIT_SIZE: f32 = 5.0;
async fn main() {
// -- SNIP --
let player = Player {
square: Square {
x,
y,
size: INIT_SIZE * 3.0,
},
};
// -- SNIP --
}
impl Friend {
fn new() -> Friend {
// -- SNIP --
Friend(Square {
x: gen_range(0.0, width - INIT_SIZE),
y: gen_range(0.0, height - INIT_SIZE),
size: INIT_SIZE,
})
}
}
fn collision(mut player: UniqueViewMut<Player>, v_friend: View<Friend>) {
for friend in v_friend.iter() {
if friend.0.size == MAX_SIZE && friend.0.collide(&player.square) {
player.square.size -= INIT_SIZE / 2.;
if player.square.size < INIT_SIZE {
panic!("Murder");
}
}
}
}
We can also handle the game over a little cleaner.
enum GameOver {
Defeat,
}
async fn main() {
// -- SNIP --
loop {
// -- SNIP --
if world.run(collision).is_err() {
panic!("Murder");
}
// -- SNIP --
}
}
fn collision(mut player: UniqueViewMut<Player>, v_friend: View<Friend>) -> Result<(), GameOver> {
for friend in v_friend.iter() {
if friend.0.size == MAX_SIZE && friend.0.collide(&player.square) {
player.square.size -= INIT_SIZE / 2.;
if player.square.size < INIT_SIZE {
return Err(GameOver::Defeat);
}
}
}
Ok(())
}
Systems can return any type, World::run
then returns when the function returns.
Moving the panic to main
isn't a big change but it allows a better control of what happens which will be useful later on.
To conclude this chapter we can better show the duplicity of the "Friends
".
fn render(player: UniqueView<Player>, v_friend: View<Friend>) {
for friend in v_friend.iter() {
if friend.0.size == MAX_SIZE {
friend.0.render(RED);
} else if friend.0.size > player.square.size {
friend.0.render(GRAY);
} else {
friend.0.render(GREEN);
}
}
player.square.render(BLUE);
}