Piston tutorial problems


#1

Hi All,

I’m trying to do the Piston tutorials at http://piston-tutorial.logdown.com/pages/table-of-contents, the first one worked fine but the following tut’s are giving me grief.

I’ve downloaded the source from github but they wont compile, my suspicion is it could be because of my version of Rust (1.18.0) with the older cargo dep’s etc??

Anyway, I’m doing these tut’s to get familiar with Rust, I have done some work with C and OpenGL in the past so those parts are fine. I’d like to get a better understanding of how to piece together the parts of Piston I need rather than using PistonWindow as well, it seems as though there’s a hundred ways to do this from what samples I have looked at briefly.

At this stage, I’d be happy to just get the tut’s running so if any one has any advice that would be great.

Thanks,
Mick


#2

It’s hard to tell without seeing the exact errors that you got.


#3

I just downloaded a clean source bundle from github, ran cargo build and here is the error output below.
I’ve tried updating the cargo toml with later versions then I get an iteration error for the events loop. I have come close by changing it to a while loop then I’m having other problems that are more to do with my understanding of Rust which I will ask about later :slight_smile:

error[E0592]: duplicate definitions with name `item`
    --> C:\Users\7\.cargo\registry\src\github.com-1ecc6299db9ec823\winapi-0.2.4\src\macros.rs:134:13
     |
134  |                pub unsafe fn $variant(&self) -> &$fieldtype {
     |   _____________-
     |  |_____________|
     | ||
135  | ||                 ::std::mem::transmute(&self.$field)
136  | ||             }
     | ||             -
     | ||_____________|
     | |______________duplicate definitions for `item`
     |                other definition for `item`
     |
    ::: C:\Users\7\.cargo\registry\src\github.com-1ecc6299db9ec823\winapi-0.2.4\src\commctrl.rs
     |
2889 |    UNION!(TVINSERTSTRUCTA, itemex, item, item_mut, TV_ITEMA);
     |    ---------------------------------------------------------- in this macro invocation

error[E0592]: duplicate definitions with name `item_mut`
    --> C:\Users\7\.cargo\registry\src\github.com-1ecc6299db9ec823\winapi-0.2.4\src\macros.rs:138:13
     |
138  |                pub unsafe fn $variantmut(&mut self) -> &mut $fieldtype {
     |   _____________-
     |  |_____________|
     | ||
139  | ||                 ::std::mem::transmute(&mut self.$field)
140  | ||             }
     | ||             -
     | ||_____________|
     | |______________duplicate definitions for `item_mut`
     |                other definition for `item_mut`
     |
    ::: C:\Users\7\.cargo\registry\src\github.com-1ecc6299db9ec823\winapi-0.2.4\src\commctrl.rs
     |
2889 |    UNION!(TVINSERTSTRUCTA, itemex, item, item_mut, TV_ITEMA);
     |    ---------------------------------------------------------- in this macro invocation

error: aborting due to 2 previous errors

error: Could not compile `winapi`.
Build failed, waiting for other jobs to finish...
error: build failed

#4

I have the following code working but the Release event doesn’t seem to be getting triggered. The logic looks sound but the square will move with first arrow click but not stop moving on release. The opposite arrow does nothing after this.

It is based on this tutorial http://piston-tutorial.logdown.com/posts/306682 with changes to fix the compile errors when using the latest crate for piston_window.

Any help or suggestions would be great, thanks.

EDIT: I think I found the problem, I need to handle the Release event in the main loop, doh!

using the piston_window = “0.67.0” crate in Cargo.toml

extern crate piston_window;

use piston_window::*;

struct Game {
    rotation: f64,
    x: f64,
    y: f64,
    up_d: bool, down_d: bool, left_d: bool, right_d: bool
}

impl Game {  
    fn new() -> Game {
        Game { rotation : 0.0, x : 0.0, y : 0.0, up_d: false, down_d: false, left_d: false, right_d: false }
    }
    fn on_update(&mut self, upd: UpdateArgs) {
        //self.rotation += 3.0 * upd.dt;
        if self.up_d {
            self.y += (-50.0) * upd.dt;
        }
        if self.down_d {
            self.y += (50.0) * upd.dt;
        }
        if self.left_d {
            self.x += (-50.0) * upd.dt;
        }
        if self.right_d {
            self.x += (50.0) * upd.dt;
        }
    }
    fn on_draw(&mut self, e: Input, ren: RenderArgs, w: &mut PistonWindow) {
        w.draw_2d(&e, |c, g| {
            clear([0.0, 0.0, 0.0, 1.0], g);
            let center = c.transform.trans((ren.width / 2) as f64, (ren.height / 2) as f64);
            let square = rectangle::square(0.0, 0.0, 100.0);
            let red = [1.0, 0.0, 0.0, 1.0];
            rectangle(red, square, center.trans(self.x, self.y).rot_rad(self.rotation).trans(-50.0, -50.0), g); 
        });
    }
    fn on_input(&mut self, inp: Input) {
        match inp {
            Input::Press(but) => {
                match but {
                    Button::Keyboard(Key::Up) => {
                        self.up_d = true;
                    }
                    Button::Keyboard(Key::Down) => {
                        self.down_d = true;
                    }
                    Button::Keyboard(Key::Left) => {
                        self.left_d = true;
                    }
                    Button::Keyboard(Key::Right) => {
                        self.right_d = true;
                    }
                    _ => {}
                }
            }
            Input::Release(but) => {
                match but {
                    Button::Keyboard(Key::Up) => {
                        self.up_d = false;
                    }
                    Button::Keyboard(Key::Down) => {
                        self.down_d = false;
                    }
                    Button::Keyboard(Key::Left) => {
                        self.left_d = false;
                    }
                    Button::Keyboard(Key::Right) => {
                        self.right_d = false;
                    }
                    _ => {}
                }
            }
            _ => {}
        }
    }
}

fn main() {
    let mut window: PistonWindow = WindowSettings::new(
        "piston-tutorial",
        [600, 600]
    )
    .exit_on_esc(true)
    .build()
    .unwrap();
    let mut game = Game::new();
    while let Some(e) = window.next() {
        match e {
            Input::Render(r) => {
                game.on_draw(e, r, &mut window);
            }
            Input::Update(u) => {
                game.on_update(u);
            }
            Input::Press(_) => {
                game.on_input(e);           
            }
            _ => {}
        }
    }
}

#5

I have been trying to reproduce but my interent is very spotty and there are many dependencies and so I haven’t been able to yet.


#6

no worries, thanks stevelabnik!

Working code below:

extern crate piston_window;

use piston_window::*;

struct Game {
    rotation: f64,
    x: f64,
    y: f64,
    up_d: bool, down_d: bool, left_d: bool, right_d: bool
}

impl Game {  
    fn new() -> Game {
        Game { rotation : 0.0, x : 0.0, y : 0.0, up_d: false, down_d: false, left_d: false, right_d: false }
    }

    fn on_update(&mut self, upd: UpdateArgs) {
        self.rotation += 3.0 * upd.dt;
        if self.up_d {
            self.y += (-50.0) * upd.dt;
        }
        if self.down_d {
            self.y += (50.0) * upd.dt;
        }
        if self.left_d {
            self.x += (-50.0) * upd.dt;
        }
        if self.right_d {
            self.x += (50.0) * upd.dt;
        }
    }

    fn on_draw(&mut self, e: Input, ren: RenderArgs, w: &mut PistonWindow) {
        w.draw_2d(&e, |c, g| {
            clear([0.0, 0.0, 0.0, 1.0], g);
            let center = c.transform.trans((ren.width / 2) as f64, (ren.height / 2) as f64);
            let square = rectangle::square(0.0, 0.0, 100.0);
            let red = [1.0, 0.0, 0.0, 1.0];
            rectangle(red, square, center.trans(self.x, self.y).rot_rad(self.rotation).trans(-50.0, -50.0), g); 
        });
    }

    fn on_press(&mut self, inp: Input) {
        match inp {
            Input::Press(but) => {
                match but {
                    Button::Keyboard(Key::Up) => {
                        self.up_d = true;
                    }
                    Button::Keyboard(Key::Down) => {
                        self.down_d = true;
                    }
                    Button::Keyboard(Key::Left) => {
                        self.left_d = true;
                    }
                    Button::Keyboard(Key::Right) => {
                        self.right_d = true;
                    }
                    _ => {}
                }
            }
           _ => {}
        }
    }

    fn on_release(&mut self, inp: Input) {
        match inp {
            Input::Release(but) => {
                match but {
                    Button::Keyboard(Key::Up) => {
                        self.up_d = false;
                    }
                    Button::Keyboard(Key::Down) => {
                        self.down_d = false;
                    }
                    Button::Keyboard(Key::Left) => {
                        self.left_d = false;
                    }
                    Button::Keyboard(Key::Right) => {
                        self.right_d = false;
                    }
                    _ => {}
                }
            }
            _ => {}
        }
    }
 }

fn main() {
    let mut window: PistonWindow = WindowSettings::new(
        "piston-tutorial",
        [600, 600]
    )
    .exit_on_esc(true)
    .build()
    .unwrap();

    let mut game = Game::new();
    while let Some(e) = window.next() {
        match e {
            Input::Render(r) => {
                game.on_draw(e, r, &mut window);
            }
            Input::Update(u) => {
                game.on_update(u);
            }
            Input::Press(_) => {
                game.on_press(e);           
            }
            Input::Release(_) => {
                game.on_release(e);
            }
            _ => {} 
        }
    }
}