Skip to content

Commit

Permalink
Replace fixed timestep in alien_cake_addict example with timer (#5760)
Browse files Browse the repository at this point in the history
# Objective

Examples should use the correct tools for the job.

## Solution

A fixed timestep, by design, can step multiple times consecutively in a single update.

That property used to crash the `alien_cake_addict` example (#2525), which was "fixed" in #3411 (by just not panicking). The proper fix is to use a timer instead, since the system is supposed to spawn a cake every 5 seconds. 

---

A timer guarantees a minimum duration. A fixed timestep guarantees a fixed number of steps per second.
Each one works by essentially sacrificing the other's guarantee.

You can use them together, but no other systems are timestep-based in this example, so the timer is enough.
  • Loading branch information
maniwani committed Sep 30, 2022
1 parent 6b8cc26 commit 6929d95
Showing 1 changed file with 12 additions and 8 deletions.
20 changes: 12 additions & 8 deletions examples/games/alien_cake_addict.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

use std::f32::consts::PI;

use bevy::{ecs::schedule::SystemSet, prelude::*, time::FixedTimestep};
use bevy::{ecs::schedule::SystemSet, prelude::*};
use rand::Rng;

#[derive(Clone, Eq, PartialEq, Debug, Hash)]
Expand All @@ -11,9 +11,13 @@ enum GameState {
GameOver,
}

#[derive(Resource)]
struct BonusSpawnTimer(Timer);

fn main() {
App::new()
.init_resource::<Game>()
.insert_resource(BonusSpawnTimer(Timer::from_seconds(5.0, true)))
.add_plugins(DefaultPlugins)
.add_state(GameState::Playing)
.add_startup_system(setup_cameras)
Expand All @@ -23,17 +27,13 @@ fn main() {
.with_system(move_player)
.with_system(focus_camera)
.with_system(rotate_bonus)
.with_system(scoreboard_system),
.with_system(scoreboard_system)
.with_system(spawn_bonus),
)
.add_system_set(SystemSet::on_exit(GameState::Playing).with_system(teardown))
.add_system_set(SystemSet::on_enter(GameState::GameOver).with_system(display_score))
.add_system_set(SystemSet::on_update(GameState::GameOver).with_system(gameover_keyboard))
.add_system_set(SystemSet::on_exit(GameState::GameOver).with_system(teardown))
.add_system_set(
SystemSet::new()
.with_run_criteria(FixedTimestep::step(5.0))
.with_system(spawn_bonus),
)
.add_system(bevy::window::close_on_esc)
.run();
}
Expand Down Expand Up @@ -291,13 +291,17 @@ fn focus_camera(

// despawn the bonus if there is one, then spawn a new one at a random location
fn spawn_bonus(
time: Res<Time>,
mut timer: ResMut<BonusSpawnTimer>,
mut state: ResMut<State<GameState>>,
mut commands: Commands,
mut game: ResMut<Game>,
) {
if *state.current() != GameState::Playing {
// make sure we wait enough time before spawning the next cake
if !timer.0.tick(time.delta()).finished() {
return;
}

if let Some(entity) = game.bonus.entity {
game.score -= 3;
commands.entity(entity).despawn_recursive();
Expand Down

0 comments on commit 6929d95

Please sign in to comment.