iolivia / rust-sokoban

Rust Sokoban book and code samples
https://sokoban.iolivia.me
MIT License
149 stars 28 forks source link

`ggez` related code seems outdated #108

Open kwiat1990 opened 1 year ago

kwiat1990 commented 1 year ago

Hi Olivia! First of all thanks for your time and effort put into preparing this tutorial! I pick up Rust recently and I try to follow your explanation of the code step by step but in Chapter 1.4 Rendering Game the implementation of the run method seems outdated due to changes in ggez::graphics crate, so that some methods can't be found anymore, are deprecated or their signatures have changed.

It would be cool and helpful for everyones, who finds and starts to follow your tutorial if the code is up-to-date, so it works and doesn't confuses.

My Cargo.toml:

[package]
name = "sokoban"
version = "0.1.0"
edition = "2021"

[dependencies]
ggez = "0.8.1"
glam = { version = "0.22.0", features = ["mint"]}
specs = { version = "0.18.0", features = ["specs-derive"] }

I'm trying to fix all places, where code is outdated and compile no longer but it's a quite challenging task for someone, who has absolutely no experience in Rust and libraries used in the project 😉. Based on examples from ggezrepository, the code could be refactored as follows:

let (positions, renderables) = data;

// Clearing the screen (this gives us the background colour)
let mut canvas = Canvas::from_frame(self.context, graphics::Color::new(0.95, 0.95, 0.95, 1.0));

// Get all the renderables with their positions and sort by the position z
// This will allow us to have entities layered visually.
let mut rendering_data = (&positions, &renderables).join().collect::<Vec<_>>();
rendering_data.sort_by_key(|&k| k.0.z);

// Iterate through all pairs of positions & renderables, load the image
// and draw it at the specified position.
for (position, renderable) in rendering_data.iter() {
    // Load the image
    let image = Image::from_path(self.context, renderable.path.clone()).expect("expected image");
    let x = position.x as f32 * TILE_WIDTH;
    let y = position.y as f32 * TILE_WIDTH;

    // draw
    let draw_params = DrawParam::new().dest(Vec2::new(x, y));
    canvas.draw(&image, draw_params);
}

// Finally, present the context, this will actually display everything
// on the screen.
canvas.finish(self.context).expect("expected to present");
iolivia commented 1 year ago

hey @kwiat1990, thanks for pointing this out, it's certainly been a while since I've bumped the ggez version!

I'll take a look and see what's changed, if there are big API changes it might be tricky because the book relies on line numbers for the code snippets, so adding more lines will mess up the book text.

kwiat1990 commented 1 year ago

@iolivia I have managed to go through the entire tutorial and adjusted the code, so it uses the latest version of listed dependencies: link to my repo.

If you’re interested I could try to incorporate the changes in following days and create a PR. I think it could be a good learning experience for me as well.

iolivia commented 1 year ago

hey @kwiat1990, great job getting this to work, a PR would be very welcome!

kwiat1990 commented 1 year ago

I gonna create one in the next few days.