1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
extern crate graphics; extern crate opengl_graphics; extern crate piston; extern crate piston_window; extern crate rand; use opengl_graphics::GlGraphics; use piston::input::*; use self::{ food::Food, snake::{Direction, Snake}, }; pub mod food; pub mod snake; pub struct Game { pub gl: GlGraphics, pub rows: u32, pub cols: u32, pub snake: Snake, pub just_eaten: bool, pub square_width: u32, pub food: Food, pub score: u32, } impl Game { pub fn render(&mut self, args: &RenderArgs) { const BLACK: [f32; 4] = [0.0, 0.0, 0.0, 1.0]; self.gl.draw(args.viewport(), |_, gl| { graphics::clear(BLACK, gl); }); self.snake.render(args); self.food.render(&mut self.gl, args, self.square_width); } pub fn update(&mut self, _: &UpdateArgs) -> bool { if !self.snake.update(self.just_eaten, self.cols, self.rows) { return false; } if self.just_eaten { self.score += 1; self.just_eaten = false; } self.just_eaten = self.food.update(&self.snake); if self.just_eaten { use rand::{thread_rng, Rng}; let mut r = thread_rng(); loop { let new_x: u32 = r.gen_range(0..self.cols); let new_y: u32 = r.gen_range(0..self.rows); if !self.snake.is_collide(new_x, new_y) { self.food = Food { x: new_x, y: new_y }; break; } } } true } pub fn pressed(&mut self, btn: &Button) { let last_direction = self.snake.d.clone(); self.snake.d = match btn { &Button::Keyboard(Key::Up) if last_direction != Direction::DOWN => Direction::UP, &Button::Keyboard(Key::Down) if last_direction != Direction::UP => Direction::DOWN, &Button::Keyboard(Key::Left) if last_direction != Direction::RIGHT => Direction::LEFT, &Button::Keyboard(Key::Right) if last_direction != Direction::LEFT => Direction::RIGHT, _ => last_direction, }; } }