Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update dependencies along with needed code refactoring #109

Open
wants to merge 15 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 13 additions & 14 deletions books/en_US/src/SUMMARY.md
Original file line number Diff line number Diff line change
@@ -1,19 +1,18 @@
# Summary

- [Base game](./c01-00-intro.md)
- [Project setup](./c01-01-setup.md)
- [Entity Component System](./c01-02-ecs.md)
- [Components and entities](./c01-03-entities-components.md)
- [Rendering system](./c01-04-rendering.md)
- [Project setup](./c01-01-setup.md)
- [Entity Component System](./c01-02-ecs.md)
- [Components and entities](./c01-03-entities-components.md)
- [Rendering system](./c01-04-rendering.md)
- [Gameplay](./c02-00-intro.md)
- [Map loading](./c02-01-map-loading.md)
- [Moving the player](./c02-02-move-player.md)
- [Pushing boxes](./c02-03-push-box.md)
- [Modules](./c02-04-modules.md)
- [Gameplay](./c02-05-gameplay.md)
- [Map loading](./c02-01-map-loading.md)
- [Moving the player](./c02-02-move-player.md)
- [Pushing boxes](./c02-03-push-box.md)
- [Modules](./c02-04-modules.md)
- [Gameplay](./c02-05-gameplay.md)
- [Advanced gameplay](./c03-00-intro.md)
- [Coloured boxes](./c03-01-colours.md)
- [Animations](./c03-02-animations.md)
- [Sounds and events](./c03-03-sounds-events.md)
- [Batch rendering](./c03-04-batch-rendering.md)

- [Colored boxes](./c03-01-colors.md)
- [Animations](./c03-02-animations.md)
- [Sounds and events](./c03-03-sounds-events.md)
- [Batch rendering](./c03-04-batch-rendering.md)
4 changes: 2 additions & 2 deletions books/en_US/src/c01-01-setup.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ Let's install [rustup](https://www.rust-lang.org/tools/install), this will insta

```
$ rustc --version
rustc 1.40.0
rustc 1.65.0
$ cargo --version
cargo 1.40.0
cargo 1.65.0
```

## Creating a project
Expand Down
6 changes: 3 additions & 3 deletions books/en_US/src/c01-03-entities-components.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ This should hopefully be straight-forward, the position components stores the x,


```rust
{{#include ../../../code/rust-sokoban-c01-03/src/main.rs:13:42}}
{{#include ../../../code/rust-sokoban-c01-03/src/main.rs:16:36}}
```

Among the familiar Rust code we've got some new syntax, we're using a powerful Rust feature called `Procedural Macros` which is used in `#[storage(VecStorage)]`. These type of macros are essentially functions that at compile time consume some syntax and produce some new syntax.
Expand All @@ -19,7 +19,7 @@ Among the familiar Rust code we've got some new syntax, we're using a powerful R
In order for specs to be happy we have to tell it ahead of time what components we will be using. Let's create a function to register components into specs.

```rust
{{#include ../../../code/rust-sokoban-c01-03/src/main.rs:61:69}}
{{#include ../../../code/rust-sokoban-c01-03/src/main.rs:56:63}}
```

## Creating entities
Expand All @@ -28,7 +28,7 @@ An entity is simply a numeric identifier tied to a set of components. So the way
This is how entity creation looks now.

```rust
{{#include ../../../code/rust-sokoban-c01-03/src/main.rs:71:124}}
{{#include ../../../code/rust-sokoban-c01-03/src/main.rs:65:117}}
```

## Assets
Expand Down
14 changes: 7 additions & 7 deletions books/en_US/src/c01-04-rendering.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ It's time for our first system, the rendering system. This system will be respon
First we'll define the `RenderingSystem` struct, it will need access to the ggez context in order to actually render.

```rust
{{#include ../../../code/rust-sokoban-c01-04/src/main.rs:47:49}}
{{#include ../../../code/rust-sokoban-c01-04/src/main.rs:48:50}}
```

We've got some new syntax here; `'a` is called a lifetime annotation. It's needed because the compiler can't see how long the reference in `RenderingSystem` is valid, meaning that we have to specify the lifetime annotation.
Expand All @@ -16,15 +16,15 @@ We've got some new syntax here; `'a` is called a lifetime annotation. It's neede
Now let's implement the System trait for our Rendering system. This doesn't do anything yet, we're just setting up the scaffolding. The definition of SystemData means that we will have access to the storage of position and renderable components, and the fact that it's read storage means we only get immutable access, which is exactly what we need.

```rust
{{#include ../../../code/rust-sokoban-c01-04/src/main.rs:51:57}}
{{#include ../../../code/rust-sokoban-c01-04/src/main.rs:52:58}}
// implementation here
{{#include ../../../code/rust-sokoban-c01-04/src/main.rs:83:84}}
{{#include ../../../code/rust-sokoban-c01-04/src/main.rs:86:87}}
```

Finally let's run the rendering system in our draw loop. This means that every time the game updates we will render the latest state of all our entities.

```rust
{{#include ../../../code/rust-sokoban-c01-04/src/main.rs:97:111}}
{{#include ../../../code/rust-sokoban-c01-04/src/main.rs:100:114}}
```

Running the game now should compile, but it will probably not do anything yet, since we haven't filled in any of the implementation of the rendering system and also we haven't created any entities.
Expand All @@ -34,7 +34,7 @@ Running the game now should compile, but it will probably not do anything yet, s
**Note:** We're going to add [glam](https://lib.rs/crates/glam) as a dependency here that is a simple and fast 3D library that offers some performance improvements.

```
{{#include ../../../code/rust-sokoban-c01-03/Cargo.toml:9:11}}
{{#include ../../../code/rust-sokoban-c01-04/Cargo.toml:9:12}}
```

Here is the implementation of the rendering system. It does a few things:
Expand All @@ -44,15 +44,15 @@ Here is the implementation of the rendering system. It does a few things:
* finally, present to the screen

```rust
{{#include ../../../code/rust-sokoban-c01-04/src/main.rs:56:83}}
{{#include ../../../code/rust-sokoban-c01-04/src/main.rs:57:86}}
```

## Add some test entities

Let's create some test entities to make sure things are working correctly.

```rust
{{#include ../../../code/rust-sokoban-c01-04/src/main.rs:179:204}}
{{#include ../../../code/rust-sokoban-c01-04/src/main.rs:182:207}}
```

Finally, let's put everything together and run. You should see something like this! This is super exciting, now we have a proper rendering system and we can actually see something on the screen for the first time. Next up, we're going to work on the gameplay so it can actually feel like a game!
Expand Down
11 changes: 6 additions & 5 deletions books/en_US/src/c02-01-map-loading.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@
Last chapter we left off at creating some entities to test our rendering system, but now it's time to render a proper map. In this section we will create a text based map configuration which we will load.

## Map config

First step, let's try to load a level based on a 2d map that looks like this.

```
{{#include ../../../code/rust-sokoban-c02-01/src/main.rs:181:189}}
{{#include ../../../code/rust-sokoban-c02-01/src/main.rs:186:194}}

where:
. is an empty spot
Expand All @@ -20,18 +21,18 @@ N is nothing: used for the outer edges of the map
Let's make a string for this, eventually we can load from a file but for simplicity let's go with a constant in the code for now.

```rust
{{#include ../../../code/rust-sokoban-c02-01/src/main.rs:179:193}}
{{#include ../../../code/rust-sokoban-c02-01/src/main.rs:184:198}}
```

And here is the implementation of load map.

```rust
{{#include ../../../code/rust-sokoban-c02-01/src/main.rs:195:234}}
{{#include ../../../code/rust-sokoban-c02-01/src/main.rs:200:239}}
```

The most interesting Rust concept here is probably the `match`. We are using the basic feature of pattern matching here, we are simply matching on the values of each token found in the map config, but we could do a lot of more advanced conditions or types of patterns.

> **_MORE:_** Read more about pattern matching [here](https://doc.rust-lang.org/book/ch06-02-match.html).
> **_MORE:_** Read more about pattern matching [here](https://doc.rust-lang.org/book/ch06-02-match.html).

Now let's run the game and see what our map looks like.

Expand All @@ -43,4 +44,4 @@ Final code below.
{{#include ../../../code/rust-sokoban-c02-01/src/main.rs}}
```

> **_CODELINK:_** You can see the full code in this example [here](https://github.com/iolivia/rust-sokoban/tree/master/code/rust-sokoban-c02-01).
> **_CODELINK:_** You can see the full code in this example [here](https://github.com/iolivia/rust-sokoban/tree/master/code/rust-sokoban-c02-01).
30 changes: 16 additions & 14 deletions books/en_US/src/c02-02-move-player.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
It wouldn't be a game if we couldn't move the player, would it? In this section we will figure out how to grab input events.

## Input events

The first step for making our player move is to start listening to input events. If we take a quick look at the [ggez input example](https://github.com/ggez/ggez/blob/master/examples/input_test.rs#L59) we can see we can subscribe to all sort of mouse and keyboard related events, for now we probably only want `key_down_event`.

Let's start listening to key events. First we'll bring a few more modules into scope:
Expand All @@ -14,16 +15,16 @@ Let's start listening to key events. First we'll bring a few more modules into s
Then, we'll add this code inside the `event::EventHandler` implementation block for our Game:

```rust
{{#include ../../../code/rust-sokoban-c02-02/src/main.rs:134}}
{{#include ../../../code/rust-sokoban-c02-02/src/main.rs:136}}

// ...

{{#include ../../../code/rust-sokoban-c02-02/src/main.rs:155:162}}
{{#include ../../../code/rust-sokoban-c02-02/src/main.rs:166}}
{{#include ../../../code/rust-sokoban-c02-02/src/main.rs:157:158}}
{{#include ../../../code/rust-sokoban-c02-02/src/main.rs:162}}

// ...

{{#include ../../../code/rust-sokoban-c02-02/src/main.rs:167}}
{{#include ../../../code/rust-sokoban-c02-02/src/main.rs:163}}
```

If we run this we should see the print lines in the console.
Expand All @@ -37,51 +38,52 @@ Key pressed: Down
Key pressed: Left
```

If you are not familiar with the `{:?}` notation used when printing, this is just a convenient way that Rust allows us to print objects for debugging. In this case we can print a KeyCode object (which is an enum) because the KeyCode type implements the Debug trait using the Debug macro (remember we discussed macros in [Chapter 1.3](./c01-03-entities-components.html), so head back there if you need a refresher). If KeyCode didn't implement Debug we would not be able to use this syntax and instead we would get a compiler error. This saves us writing some custom code to convert the key codes to strings, so we can rely on the built-in functionalily for that.
If you are not familiar with the `{:?}` notation used when printing, this is just a convenient way that Rust allows us to print objects for debugging. In this case we can print a KeyCode object (which is an enum) because the KeyCode type implements the Debug trait using the Debug macro (remember we discussed macros in [Chapter 1.3](./c01-03-entities-components.html), so head back there if you need a refresher). If KeyCode didn't implement Debug we would not be able to use this syntax and instead we would get a compiler error. This saves us writing some custom code to convert the key codes to strings, so we can rely on the built-in functionalily for that.

## Resources

Next up we'll add a resource, which is the specs way of sharing some state across systems which isn't part of your world. We'll use a resource for modelling the input queue of key presses, since that doesn't really fit into our existing components/entities model.

```rust
{{#include ../../../code/rust-sokoban-c02-02/src/main.rs:48:52}}
{{#include ../../../code/rust-sokoban-c02-02/src/main.rs:51:54}}
```

And then we'll push the new key presses into the queue when `key_down_event` is called.

```rust
{{#include ../../../code/rust-sokoban-c02-02/src/main.rs:134}}
{{#include ../../../code/rust-sokoban-c02-02/src/main.rs:136}}

// ...

{{#include ../../../code/rust-sokoban-c02-02/src/main.rs:155:166}}
{{#include ../../../code/rust-sokoban-c02-02/src/main.rs:157:162}}

// ...

{{#include ../../../code/rust-sokoban-c02-02/src/main.rs:167}}
{{#include ../../../code/rust-sokoban-c02-02/src/main.rs:163}}
```

Finally, we need to register the resources into specs like we did for components.

```rust
// Registering resources
{{#include ../../../code/rust-sokoban-c02-02/src/main.rs:179:181}}
{{#include ../../../code/rust-sokoban-c02-02/src/main.rs:177:179}}

// Registering resources in main
{{#include ../../../code/rust-sokoban-c02-02/src/main.rs:295:312}}
{{#include ../../../code/rust-sokoban-c02-02/src/main.rs:293:311}}
```

## Input system

Using this code we have a resource that is a continuous queue of input key presses. Next up, we'll start processing these inputs in a system.

```rust
{{#include ../../../code/rust-sokoban-c02-02/src/main.rs:94:121}}
{{#include ../../../code/rust-sokoban-c02-02/src/main.rs:99:127}}
```

Finally we need to run the system in our update loop.

```rust
{{#include ../../../code/rust-sokoban-c02-02/src/main.rs:135:143}}
{{#include ../../../code/rust-sokoban-c02-02/src/main.rs:141:149}}
```

The input system is pretty simple, it grabs all the players and positions (we should only have one player but this code doesn't need to care about that, it could in theory work if we have multiple players that we want to control with the same input). And then for every player and position combination, it will grab the first key pressed and remove it from the input queue. It will then figure out what is the required transformation - for example if we press up we want to move one tile up and so on, and then applies this position update.
Expand All @@ -90,4 +92,4 @@ Pretty cool! Here's how it should look like. Notice we can go through walls and

![Moving player](./images/input.gif)

> **_CODELINK:_** You can see the full code in this example [here](https://github.com/iolivia/rust-sokoban/tree/master/code/rust-sokoban-c02-02).
> **_CODELINK:_** You can see the full code in this example [here](https://github.com/iolivia/rust-sokoban/tree/master/code/rust-sokoban-c02-02).
Loading