Skip to content

Commit

Permalink
006-executing-systems-on-specific-intervals
Browse files Browse the repository at this point in the history
In snake the snake only moves one square every so often. In Bevy we can emulate this with fixed time steps using [`Time`](https://docs.rs/bevy/0.12.0/bevy/prelude/struct.Time.html); specifically a variant of `Time` called [`Fixed`](https://docs.rs/bevy/0.12.0/bevy/time/struct.Fixed.html).

In `src/main.rs`, we start off by inserting a new `Resource` using [`Time<Fixed>`](https://docs.rs/bevy/0.12.0/bevy/time/struct.Time.html#impl-Time%3CFixed%3E) to handle counting our time steps. In this case I've chosen to make the step run every 0.1 seconds.

```rust
.insert_resource(Time::<Fixed>::from_seconds(0.1))
```

<details><summary>more about `Time` and `Fixed`</summary>

There are a lot of different ways to deal with time. In Bevy, there's ways of accessing [wall-clock time](https://docs.rs/bevy/0.12.0/bevy/time/struct.Real.html), [virtual time](https://docs.rs/bevy/0.12.0/bevy/time/struct.Virtual.html), and [fixed time](https://docs.rs/bevy/0.12.0/bevy/time/struct.Fixed.html).

Each of these ways of accessing time share a large set of functions for dealing with time, so it makes sense that we'd have a way to represent all of that shared functionality. Here is the [Pull Request](bevyengine/bevy#8964) that implemented this unified interface.

[`Time`](https://docs.rs/bevy/0.12.0/bevy/prelude/struct.Time.html) then, is a type that accepts a generic type argument (in this case we're using [`Fixed`](https://docs.rs/bevy/0.12.0/bevy/time/struct.Fixed.html)).

There are additional functions implemented on [`Time<Fixed>`](https://docs.rs/bevy/0.12.0/bevy/time/struct.Time.html#impl-Time%3CFixed%3E) that don't exist on other specializations of `Time`. One such function is `from_seconds` which is used to instantiate a new `Time<Fixed>` value that we can insert as a `Resource`.

The syntax for accessing the `from_seconds` function associated with the `Time<Fixed>` type is not written as `Time<Fixed>::from_seconds` but rather is `Time::<Fixed>::from_seconds`. This is mostly because if we didn't use the turbofish syntax then it could be ambiguous as to whether the programmer meant to write "greater than" and "less than" or "a generic type".

</details>

After creating our `Time<Fixed>` `Resource`, we need to add a system that gets executed on the interval we defined. We'll use the [`FixedUpdate`](https://docs.rs/bevy/0.12.0/bevy/app/struct.FixedUpdate.html) schedule and a new system we haven't created yet called `tick`.

```rust
.add_systems(FixedUpdate, tick)
```

The `tick` system will be defined in `src/lib.rs`, so we can write the use item now to bring it into scope.

```rust
use snake::{
    board::{spawn_board, Board},
    snake::{spawn_snake, Snake},
    tick,
};
```

In `src/lib.rs` , we can drop in a new function that logs out the word `"tick!"`. This system will run once every 0.1 seconds, as we specified in our `src/main.rs`.

```rust
pub mod board;
pub mod colors;
pub mod snake;

use bevy::prelude::*;

pub fn tick() {
    info!("tick!");
}
```

`info!` comes from the [tracing](https://docs.rs/tracing/0.1.40/tracing/index.html) crate, which Bevy includes and sets up for us.

> [!NOTE] tracing in Bevy
> Bevy handles setting up logging in different ways depending on the environment we're running in using the [`LogPlugin`](https://docs.rs/bevy/0.12.0/bevy/log/struct.LogPlugin.html), which is part of the [`DefaultPlugins`](https://docs.rs/bevy/0.12.0/bevy/struct.DefaultPlugins.html)

After running `cargo run`, we can see our new system logging out `"tick"` on the interval we specified. The output will include the timestamp of the log, the log level (`INFO` in this case), any span information, and finally the message we logged out.

```
2023-11-13T17:54:07.073260Z  INFO snake: tick!
2023-11-13T17:54:07.174248Z  INFO snake: tick!
2023-11-13T17:54:07.273097Z  INFO snake: tick!
2023-11-13T17:54:07.373646Z  INFO snake: tick!
2023-11-13T17:54:07.473044Z  INFO snake: tick!
```

In the next lesson we'll combine this system with our VecDeque to handle our snake's movement.
  • Loading branch information
ChristopherBiscardi committed Nov 19, 2023
1 parent 6cc7a3b commit 3269a78
Show file tree
Hide file tree
Showing 2 changed files with 9 additions and 0 deletions.
6 changes: 6 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
pub mod board;
pub mod colors;
pub mod snake;

use bevy::prelude::*;

pub fn tick() {
info!("tick!");
}
3 changes: 3 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use bevy::prelude::*;
use snake::{
board::{spawn_board, Board},
snake::{spawn_snake, Snake},
tick,
};

fn main() {
Expand All @@ -18,10 +19,12 @@ fn main() {
}))
.insert_resource(Board::new(20))
.init_resource::<Snake>()
.insert_resource(Time::<Fixed>::from_seconds(0.1))
.add_systems(
Startup,
(setup, spawn_board, spawn_snake),
)
.add_systems(FixedUpdate, tick)
.run();
}

Expand Down

0 comments on commit 3269a78

Please sign in to comment.