pub fn update(&mut self, ts: u32) {
        // Update the FPS counter.
        // -----------------------
        self.fps_counter.update(ts);

        // Process input.
        // --------------
        self.input.update(ts);

        // Update the player depending on input. This needs
        // a mutable reference to projectiles, so it can spawn new ones on shoot.
        // ----------------------------------------------------------------------
        self.player.update(ts, &self.input, &mut self.projectiles);

        // Get all the mutable references for fields from **Game** into lifetimes scope.
        // This has to be done to prevent confusing the closures lifetime below with the lifetime
        // of the fields. I think it is related to the fact, that the closure does not get any gurantee
        // from `game_tick.check()` regarding outliving any of the mutable resources in **Game**.
        //
        // TODO: Maybe it is possible to annotate this update function, the Game type, or the closure
        // with lifetimes.
        let game_tick = &mut self.game_tick;
        let projectiles = &mut self.projectiles;
        let enemies = &mut self.enemies;
        let enemy_tick = &mut self.enemy_tick;
        let enemy_spawn_tick = &mut self.enemy_spawn_tick;
        let explosions = &mut self.explosions;
        let explosion_tick = &mut self.explosion_tick;
        let score = &mut self.score;

        // This will check if the gametick is fired. When yes, it executes the given closure.
        // The *off* parameter for the closure tells, how many ms the timer may have missed.
        // ----------------------------------------------------------------------------------
        game_tick.check(ts, |off| {
            // Calculate how many ticks we missed (should be 1 for no misses almost always),
            // and perform all of them right here in the loop body.
            // -----------------------------------------------------------------------------
            for _ in 0..(off + TICK) / TICK {
                // Check if projectile would move into the void. The *retain()* iterator is used,
                // to signal which projectiles survive, or die in this game tick.
                // ------------------------------------------------------------------------------
                projectiles.retain(|e| {
                    if e.needs_removal() {
                        score.add(-1); //<- We lose one point when the projectile missed all enemies.
                        false //<- Also please die.
                    } else {
                        true //<- Allowed to live another day.
                    }
                });

                // Now actually update the projectile.
                // -----------------------------------
                for p in projectiles.iter_mut() {
                    p.tick();
                }

                // When the enemy tick is here, update them all.
                // ---------------------------------------------
                if *enemy_tick == 10 {
                    for e in enemies.iter_mut() {
                        e.tick();
                    }
                    enemies.retain(|e| {
                        if e.needs_removal() {
                            //<- Check if they have to die because of the void.
                            score.add(-10); //<- We loose points if they get past our players defenses.
                            false
                        } else {
                            true
                        }
                    });
                    *enemy_tick = 0;
                } else {
                    *enemy_tick += 1;
                }

                // Update all those beautiful explosions when the tick says so.
                // ------------------------------------------------------------
                if *explosion_tick == 5 {
                    for x in explosions.iter_mut() {
                        x.tick();
                    }
                    explosions.retain(|x| !x.needs_removal()); //<- Eliminate the ones with enough progress.
                    *explosion_tick = 0;
                } else {
                    *explosion_tick += 1;
                }

                // Every enemy spawn tick, spawn new enemies (currently only one per spawn tick).
                // They are spawned along the horizontal axis on the top of the canvas.
                // ------------------------------------------------------------------------------
                if *enemy_spawn_tick == 200 {
                    enemies.push(entites::Enemy::new_random());
                    *enemy_spawn_tick = 0;
                } else {
                    *enemy_spawn_tick += 1;
                }

                // Collison check and removal for every projectile by retaining iterator.
                // ----------------------------------------------------------------------
                projectiles.retain(|p| {
                    if let Some(e) = enemies
                        .iter()
                        .enumerate()
                        // Find collisiony between current projectile and all enemies.
                        // -----------------------------------------------------------
                        .find(|(_, e)| e.intersects_with(p.pos_x, p.pos_y))
                        // Get only the index of the enemy.
                        // --------------------------------
                        .map(|(i, _)| i)
                    {
                        // Collision found. Remove enemy by index, create explosion on this position, and
                        // then mark the projectile for removal. Also add some points to the score.
                        // ------------------------------------------------------------------------------
                        enemies.remove(e);
                        explosions.push(entites::Explosion::new(
                            utils::cap(p.pos_x as i32 - 1, 0, 79) as u32,
                            utils::cap(p.pos_y as i32 + 1, 0, 59) as u32,
                        ));
                        score.add(5);
                        false
                    } else {
                        true
                    }
                });
            }
        });
    }
/// Update the game.
///
/// This processes all input, and calculates the next state of the game depending on
/// previous state, current input, and the current timestamp.
Update the game.
This processes all input, and calculates the next state of the game depending on
previous state, current input, and the current timestamp.
Update the game . This processes all input and calculates the next state of the game depending on previous state current input and the current timestamp .
pub fn update(&mut self, ts: u32) {
        // Update the FPS counter.
        // -----------------------
        self.fps_counter.update(ts);
        // Process input.
        // --------------
        self.input.update(ts);
        // Update the player depending on input. This needs
        // a mutable reference to projectiles, so it can spawn new ones on shoot.
        // ----------------------------------------------------------------------
        self.player.update(ts, &self.input, &mut self.projectiles);
        // Get all the mutable references for fields from **Game** into lifetimes scope.
        // This has to be done to prevent confusing the closures lifetime below with the lifetime
        // of the fields. I think it is related to the fact, that the closure does not get any gurantee
        // from `game_tick.check()` regarding outliving any of the mutable resources in **Game**.
        //
        // TODO: Maybe it is possible to annotate this update function, the Game type, or the closure
        // with lifetimes.
        let game_tick = &mut self.game_tick;
        let projectiles = &mut self.projectiles;
        let enemies = &mut self.enemies;
        let enemy_tick = &mut self.enemy_tick;
        let enemy_spawn_tick = &mut self.enemy_spawn_tick;
        let explosions = &mut self.explosions;
        let explosion_tick = &mut self.explosion_tick;
        let score = &mut self.score;
        // This will check if the gametick is fired. When yes, it executes the given closure.
        // The *off* parameter for the closure tells, how many ms the timer may have missed.
        // ----------------------------------------------------------------------------------
        game_tick.check(ts, |off| {
            // Calculate how many ticks we missed (should be 1 for no misses almost always),
            // and perform all of them right here in the loop body.
            // -----------------------------------------------------------------------------
            for _ in 0..(off + TICK) / TICK {
                // Check if projectile would move into the void. The *retain()* iterator is used,
                // to signal which projectiles survive, or die in this game tick.
                // ------------------------------------------------------------------------------
                projectiles.retain(|e| {
                    if e.needs_removal() {
                        score.add(-1); //<- We lose one point when the projectile missed all enemies.
                        false //<- Also please die.
                    } else {
                        true //<- Allowed to live another day.
                    }
                });
                // Now actually update the projectile.
                // -----------------------------------
                for p in projectiles.iter_mut() {
                    p.tick();
                }
                // When the enemy tick is here, update them all.
                // ---------------------------------------------
                if *enemy_tick == 10 {
                    for e in enemies.iter_mut() {
                        e.tick();
                    }
                    enemies.retain(|e| {
                        if e.needs_removal() {
                            //<- Check if they have to die because of the void.
                            score.add(-10); //<- We loose points if they get past our players defenses.
                            false
                        } else {
                            true
                        }
                    });
                    *enemy_tick = 0;
                } else {
                    *enemy_tick += 1;
                }
                // Update all those beautiful explosions when the tick says so.
                // ------------------------------------------------------------
                if *explosion_tick == 5 {
                    for x in explosions.iter_mut() {
                        x.tick();
                    }
                    explosions.retain(|x| !x.needs_removal()); //<- Eliminate the ones with enough progress.
                    *explosion_tick = 0;
                } else {
                    *explosion_tick += 1;
                }
                // Every enemy spawn tick, spawn new enemies (currently only one per spawn tick).
                // They are spawned along the horizontal axis on the top of the canvas.
                // ------------------------------------------------------------------------------
                if *enemy_spawn_tick == 200 {
                    enemies.push(entites::Enemy::new_random());
                    *enemy_spawn_tick = 0;
                } else {
                    *enemy_spawn_tick += 1;
                }
                // Collison check and removal for every projectile by retaining iterator.
                // ----------------------------------------------------------------------
                projectiles.retain(|p| {
                    if let Some(e) = enemies
                        .iter()
                        .enumerate()
                        // Find collisiony between current projectile and all enemies.
                        // -----------------------------------------------------------
                        .find(|(_, e)| e.intersects_with(p.pos_x, p.pos_y))
                        // Get only the index of the enemy.
                        // --------------------------------
                        .map(|(i, _)| i)
                    {
                        // Collision found. Remove enemy by index, create explosion on this position, and
                        // then mark the projectile for removal. Also add some points to the score.
                        // ------------------------------------------------------------------------------
                        enemies.remove(e);
                        explosions.push(entites::Explosion::new(
                            utils::cap(p.pos_x as i32 - 1, 0, 79) as u32,
                            utils::cap(p.pos_y as i32 + 1, 0, 59) as u32,
                        ));
                        score.add(5);
                        false
                    } else {
                        true
                    }
                });
            }
        });
    }
pub fn update ( & mut self , ts : u32 ) { // Update the FPS counter. // ----------------------- self . fps_counter . update ( ts ) ; // Process input. // -------------- self . input . update ( ts ) ; // Update the player depending on input. This needs // a mutable reference to projectiles, so it can spawn new ones on shoot. // ---------------------------------------------------------------------- self . player . update ( ts , & self . input , & mut self . projectiles ) ; // Get all the mutable references for fields from **Game** into lifetimes scope. // This has to be done to prevent confusing the closures lifetime below with the lifetime // of the fields. I think it is related to the fact, that the closure does not get any gurantee // from `game_tick.check()` regarding outliving any of the mutable resources in **Game**. // // TODO: Maybe it is possible to annotate this update function, the Game type, or the closure // with lifetimes. let game_tick = & mut self . game_tick ; let projectiles = & mut self . projectiles ; let enemies = & mut self . enemies ; let enemy_tick = & mut self . enemy_tick ; let enemy_spawn_tick = & mut self . enemy_spawn_tick ; let explosions = & mut self . explosions ; let explosion_tick = & mut self . explosion_tick ; let score = & mut self . score ; // This will check if the gametick is fired. When yes, it executes the given closure. // The *off* parameter for the closure tells, how many ms the timer may have missed. // ---------------------------------------------------------------------------------- game_tick . check ( ts , | off | { // Calculate how many ticks we missed (should be 1 for no misses almost always), // and perform all of them right here in the loop body. // ----------------------------------------------------------------------------- for _ in 0 .. ( off + TICK ) / TICK { // Check if projectile would move into the void. The *retain()* iterator is used, // to signal which projectiles survive, or die in this game tick. // ------------------------------------------------------------------------------ projectiles . retain ( | e | { if e . needs_removal ( ) { score . add ( - 1 ) ; //<- We lose one point when the projectile missed all enemies. false //<- Also please die. } else { true //<- Allowed to live another day. } } ) ; // Now actually update the projectile. // ----------------------------------- for p in projectiles . iter_mut ( ) { p . tick ( ) ; } // When the enemy tick is here, update them all. // --------------------------------------------- if * enemy_tick == 10 { for e in enemies . iter_mut ( ) { e . tick ( ) ; } enemies . retain ( | e | { if e . needs_removal ( ) { //<- Check if they have to die because of the void. score . add ( - 10 ) ; //<- We loose points if they get past our players defenses. false } else { true } } ) ; * enemy_tick = 0 ; } else { * enemy_tick += 1 ; } // Update all those beautiful explosions when the tick says so. // ------------------------------------------------------------ if * explosion_tick == 5 { for x in explosions . iter_mut ( ) { x . tick ( ) ; } explosions . retain ( | x | ! x . needs_removal ( ) ) ; //<- Eliminate the ones with enough progress. * explosion_tick = 0 ; } else { * explosion_tick += 1 ; } // Every enemy spawn tick, spawn new enemies (currently only one per spawn tick). // They are spawned along the horizontal axis on the top of the canvas. // ------------------------------------------------------------------------------ if * enemy_spawn_tick == 200 { enemies . push ( entites :: Enemy :: new_random ( ) ) ; * enemy_spawn_tick = 0 ; } else { * enemy_spawn_tick += 1 ; } // Collison check and removal for every projectile by retaining iterator. // ---------------------------------------------------------------------- projectiles . retain ( | p | { if let Some ( e ) = enemies . iter ( ) . enumerate ( ) // Find collisiony between current projectile and all enemies. // ----------------------------------------------------------- . find ( | ( _ , e ) | e . intersects_with ( p . pos_x , p . pos_y ) ) // Get only the index of the enemy. // -------------------------------- . map ( | ( i , _ ) | i ) { // Collision found. Remove enemy by index, create explosion on this position, and // then mark the projectile for removal. Also add some points to the score. // ------------------------------------------------------------------------------ enemies . remove ( e ) ; explosions . push ( entites :: Explosion :: new ( utils :: cap ( p . pos_x as i32 - 1 , 0 , 79 ) as u32 , utils :: cap ( p . pos_y as i32 + 1 , 0 , 59 ) as u32 , ) ) ; score . add ( 5 ) ; false } else { true } } ) ; } } ) ; }
Update the game.
Update the game .
&mut self
ts
u32
&mut self
ts
u32