From 89ef496eab23a798fcd771bb50bbde7392ca360e Mon Sep 17 00:00:00 2001 From: Marco Thomas Date: Mon, 24 Aug 2020 23:37:09 +0200 Subject: [PATCH] Add Basic Movement, Add Food generation --- src/main.rs | 128 ++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 115 insertions(+), 13 deletions(-) diff --git a/src/main.rs b/src/main.rs index 0d3acaf..fb13e8e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -9,14 +9,26 @@ use piston::event_loop::*; use glutin_window::GlutinWindow; use opengl_graphics::{GlGraphics, OpenGL}; +const PIXEL_SIZE: i32 = 20; +const FIELD_SIZE_X: i32 = 30; +const FIELD_SIZE_Y: i32 = 30; + +#[derive(Clone, PartialEq)] +enum Direction { + Up, + Down, + Left, + Right, +} + struct Game { gl: GlGraphics, snake: Snake, + food: Food, } impl Game { fn render(&mut self, args: &RenderArgs) { - use graphics; const BLACK: [f32; 4] = [0.0, 0.0, 0.0, 1.0]; @@ -25,24 +37,34 @@ impl Game { }); self.snake.render(&mut self.gl, args); + + self.food.render(&mut self.gl, args); + } + + fn update(&mut self) { + self.snake.update(); + } + + fn button_press(&mut self, button: &Button) { + self.snake.change_direction(&button); } } struct Snake { - x_pos: i32, - y_pos: i32, + pos_x: i32, + pos_y: i32, + direction: Direction, } impl Snake { fn render(&self, gl: &mut GlGraphics, args: &RenderArgs) { - use graphics; const GREEN: [f32; 4] = [0.0, 1.0, 0.0, 1.0]; let square = graphics::rectangle::square( - self.x_pos as f64, - self.y_pos as f64, - 20.0); + (self.pos_x * PIXEL_SIZE) as f64, + (self.pos_y * PIXEL_SIZE) as f64, + PIXEL_SIZE as f64); gl.draw(args.viewport(), |c, gl| { let transform = c.transform; @@ -50,6 +72,70 @@ impl Snake { graphics::rectangle(GREEN, square, transform, gl); }); } + + fn update(&mut self) { + match self.direction { + Direction::Up => self.pos_y -=1, + Direction::Down => self.pos_y +=1, + Direction::Left => self.pos_x -=1, + Direction::Right => self.pos_x +=1, + } + + if self.pos_x > FIELD_SIZE_X { + self.pos_x = 0; + } else if self.pos_x < 0 { + self.pos_x = FIELD_SIZE_X; + } + + if self.pos_y > FIELD_SIZE_Y { + self.pos_y = 0; + } else if self.pos_y < 0 { + self.pos_y = FIELD_SIZE_Y; + } + + } + + fn change_direction(&mut self, button: &Button) { + let last_direction = self.direction.clone(); + + self.direction = match button { + Button::Keyboard(Key::W) => Direction::Up, + Button::Keyboard(Key::S) => Direction::Down, + Button::Keyboard(Key::A) => Direction::Left, + Button::Keyboard(Key::D) => Direction::Right, + _ => last_direction, + } + } +} + +struct Food { + pos_x: i32, + pos_y: i32, +} + +impl Food { + fn new() -> Food { + let random_x: i32 = 3; + let random_y: i32 = 3; + + Food { pos_x: random_x, pos_y: random_y } + } + + fn render(&self, gl: &mut GlGraphics, args: &RenderArgs) { + + const RED: [f32; 4] = [1.0, 0.0, 0.0, 1.0]; + + let square = graphics::rectangle::square( + (self.pos_x * PIXEL_SIZE) as f64, + (self.pos_y * PIXEL_SIZE) as f64, + PIXEL_SIZE as f64); + + gl.draw(args.viewport(), |c, gl| { + let transform = c.transform; + + graphics::rectangle(RED, square, transform, gl); + }); + } } fn main() { @@ -57,7 +143,8 @@ fn main() { let mut window: GlutinWindow = WindowSettings::new( "snake-rs", - [200, 200]) + [(FIELD_SIZE_X * PIXEL_SIZE) as f64, + (FIELD_SIZE_Y * PIXEL_SIZE) as f64]) .graphics_api(opengl) .exit_on_esc(true) .build() @@ -66,16 +153,31 @@ fn main() { let mut game = Game { gl: GlGraphics::new(opengl), snake: Snake { - x_pos: 50, - y_pos: 50 + pos_x: 0, + pos_y: 0, + direction: Direction::Right, }, + food: Food::new(), }; - let mut events = Events::new(EventSettings::new()); + let mut events = Events::new(EventSettings::new()) + .max_fps(60) + .ups(10); while let Some(e) = events.next(&mut window) { - if let Some(args) = e.render_args() { - game.render(&args); + + if let Some(r) = e.render_args() { + game.render(&r); + } + + if let Some(_u) = e.update_args() { + game.update(); + } + + if let Some(b) = e.button_args() { + if b.state == ButtonState::Press { + game.button_press(&b.button); + } } } }