Replace fixed timestep in alien_cake_addict example with timer (#5760)

# 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.
This commit is contained in:
Cameron 2022-09-30 11:37:33 +00:00
parent 6b8cc2652a
commit 6929d95f7f

View file

@ -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)]
@ -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)
@ -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();
}
@ -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();