|  |  | @ -1,6 +1,6 @@ | 
			
		
	
		
			
				
					|  |  |  | use ggez::input::mouse::{self, MouseButton}; | 
			
		
	
		
			
				
					|  |  |  | use ggez::event::{self, EventHandler}; | 
			
		
	
		
			
				
					|  |  |  | use ggez::graphics::{self, Color, DrawMode, Mesh, MeshBuilder}; | 
			
		
	
		
			
				
					|  |  |  | use ggez::input::mouse::{self, MouseButton}; | 
			
		
	
		
			
				
					|  |  |  | use ggez::{Context, ContextBuilder, GameResult}; | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | use std::env; | 
			
		
	
	
		
			
				
					|  |  | @ -16,16 +16,35 @@ struct Apr { | 
			
		
	
		
			
				
					|  |  |  |     board: Vec<Vec<u8>>, | 
			
		
	
		
			
				
					|  |  |  |     grid: Mesh, | 
			
		
	
		
			
				
					|  |  |  |     should_update_grid: bool, | 
			
		
	
		
			
				
					|  |  |  |     // Your state here...
 | 
			
		
	
		
			
				
					|  |  |  |     __test_state: usize, | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     //These would go in a dedicated Actor struct in the real game.
 | 
			
		
	
		
			
				
					|  |  |  |     __test_pawn_image: graphics::Image, | 
			
		
	
		
			
				
					|  |  |  |     __test_pawn_x: f32, | 
			
		
	
		
			
				
					|  |  |  |     __test_pawn_y: f32, | 
			
		
	
		
			
				
					|  |  |  |     __test_pawn_held: bool, | 
			
		
	
		
			
				
					|  |  |  |     __test_pawn_h_x: f32, | 
			
		
	
		
			
				
					|  |  |  |     __test_pawn_h_y: f32, | 
			
		
	
		
			
				
					|  |  |  |     actors: Vec<Actor>, | 
			
		
	
		
			
				
					|  |  |  |     behaviours: Vec<Behaviour>, | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | struct Behaviour { | 
			
		
	
		
			
				
					|  |  |  |     moves: Vec<(u8, u8)>, //this is a placeholder
 | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | enum ActorPosn { | 
			
		
	
		
			
				
					|  |  |  |     Board { | 
			
		
	
		
			
				
					|  |  |  |         x: u8, | 
			
		
	
		
			
				
					|  |  |  |         y: u8, | 
			
		
	
		
			
				
					|  |  |  |     }, | 
			
		
	
		
			
				
					|  |  |  |     Floating { | 
			
		
	
		
			
				
					|  |  |  |         x: f32, | 
			
		
	
		
			
				
					|  |  |  |         y: f32, | 
			
		
	
		
			
				
					|  |  |  |         held_x: f32, | 
			
		
	
		
			
				
					|  |  |  |         held_y: f32, | 
			
		
	
		
			
				
					|  |  |  |     }, | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | use crate::ActorPosn::{Board, Floating}; | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | struct Actor { | 
			
		
	
		
			
				
					|  |  |  |     image: graphics::Image, | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     posn: ActorPosn, | 
			
		
	
		
			
				
					|  |  |  |     behaviour: u8, //index into the behaviours array
 | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | struct Piece { | 
			
		
	
	
		
			
				
					|  |  | @ -63,7 +82,7 @@ fn make_grid(ctx: &mut Context, r: i32, c: i32, board: &[Vec<u8>]) -> GameResult | 
			
		
	
		
			
				
					|  |  |  |                     6 => Color::BLUE, | 
			
		
	
		
			
				
					|  |  |  |                     7 => Color::MAGENTA, | 
			
		
	
		
			
				
					|  |  |  |                     _ => Color::BLACK, | 
			
		
	
		
			
				
					|  |  |  |                 } | 
			
		
	
		
			
				
					|  |  |  |                 }, | 
			
		
	
		
			
				
					|  |  |  |             )?; | 
			
		
	
		
			
				
					|  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |     } | 
			
		
	
	
		
			
				
					|  |  | @ -81,6 +100,27 @@ fn make_board(r: i32, c: i32) -> Vec<Vec<u8>> { | 
			
		
	
		
			
				
					|  |  |  |     init | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | fn closest_square_coords(x: f32, y: f32, col: i32, row: i32) -> (u8, u8) { | 
			
		
	
		
			
				
					|  |  |  |     //First, normalise to within the grid.
 | 
			
		
	
		
			
				
					|  |  |  |     let mut x = x; | 
			
		
	
		
			
				
					|  |  |  |     x = x.max(START_X); | 
			
		
	
		
			
				
					|  |  |  |     x = x.min(START_X + (BOARD_SQUARE_SIZE * col as f32) - 1.0); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     let mut y = y; | 
			
		
	
		
			
				
					|  |  |  |     y = y.max(START_Y); | 
			
		
	
		
			
				
					|  |  |  |     y = y.min(START_Y + (BOARD_SQUARE_SIZE * row as f32) - 1.0); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     //Then, remove the start x and y
 | 
			
		
	
		
			
				
					|  |  |  |     x -= START_X; | 
			
		
	
		
			
				
					|  |  |  |     y -= START_Y; | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     //Then, snap to board coords.
 | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     let x = (x / BOARD_SQUARE_SIZE) as u8; | 
			
		
	
		
			
				
					|  |  |  |     let y = (y / BOARD_SQUARE_SIZE) as u8; | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     (x, y) | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | impl Apr { | 
			
		
	
		
			
				
					|  |  |  |     pub fn new(_ctx: &mut Context, r: i32, c: i32) -> GameResult<Apr> { | 
			
		
	
		
			
				
					|  |  |  |         // Load/create resources such as images here.
 | 
			
		
	
	
		
			
				
					|  |  | @ -91,14 +131,15 @@ impl Apr { | 
			
		
	
		
			
				
					|  |  |  |             grid: make_grid(_ctx, r, c, board.as_slice())?, | 
			
		
	
		
			
				
					|  |  |  |             board, | 
			
		
	
		
			
				
					|  |  |  |             should_update_grid: false, | 
			
		
	
		
			
				
					|  |  |  |             __test_state: 0, | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |             __test_pawn_image: graphics::Image::new(_ctx, "/pawn.png")?, | 
			
		
	
		
			
				
					|  |  |  |             __test_pawn_x: 20.0, | 
			
		
	
		
			
				
					|  |  |  |             __test_pawn_y: 20.0, | 
			
		
	
		
			
				
					|  |  |  |             __test_pawn_held: false, | 
			
		
	
		
			
				
					|  |  |  |             __test_pawn_h_x: 0.0, | 
			
		
	
		
			
				
					|  |  |  |             __test_pawn_h_y: 0.0 | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |             actors: vec![Actor { | 
			
		
	
		
			
				
					|  |  |  |                 image: graphics::Image::new(_ctx, "/pawn.png")?, | 
			
		
	
		
			
				
					|  |  |  |                 posn: Board { x: 0, y: 0 }, | 
			
		
	
		
			
				
					|  |  |  |                 behaviour: 0, | 
			
		
	
		
			
				
					|  |  |  |             }], | 
			
		
	
		
			
				
					|  |  |  |             behaviours: vec![Behaviour { | 
			
		
	
		
			
				
					|  |  |  |                 moves: vec![(0, 1)], | 
			
		
	
		
			
				
					|  |  |  |             }], //the pawn can go ONE forwards
 | 
			
		
	
		
			
				
					|  |  |  |         }) | 
			
		
	
		
			
				
					|  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
	
		
			
				
					|  |  | @ -107,58 +148,49 @@ impl Apr { | 
			
		
	
		
			
				
					|  |  |  |         self.should_update_grid = true; | 
			
		
	
		
			
				
					|  |  |  |         Ok(()) | 
			
		
	
		
			
				
					|  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     fn closest_square_coords(&self, x: f32, y: f32) -> (f32, f32) { | 
			
		
	
		
			
				
					|  |  |  |         //First, normalise to within the grid.
 | 
			
		
	
		
			
				
					|  |  |  |         let mut x = x; | 
			
		
	
		
			
				
					|  |  |  |         x = x.max(START_X); | 
			
		
	
		
			
				
					|  |  |  |         x = x.min(START_X + (BOARD_SQUARE_SIZE * self.col as f32) - 1.0); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |         let mut y = y; | 
			
		
	
		
			
				
					|  |  |  |         y = y.max(START_Y); | 
			
		
	
		
			
				
					|  |  |  |         y = y.min(START_Y + (BOARD_SQUARE_SIZE * self.row as f32) - 1.0); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |         //Then, snap to top left.
 | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |         x = (x / BOARD_SQUARE_SIZE).trunc() * BOARD_SQUARE_SIZE; | 
			
		
	
		
			
				
					|  |  |  |         y = (y / BOARD_SQUARE_SIZE).trunc() * BOARD_SQUARE_SIZE; | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |         (x, y) | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | impl EventHandler for Apr { | 
			
		
	
		
			
				
					|  |  |  |     fn update(&mut self, ctx: &mut Context) -> GameResult<()> { | 
			
		
	
		
			
				
					|  |  |  |         for _x in 0..self.col { | 
			
		
	
		
			
				
					|  |  |  |             let c = self.__test_state % self.col as usize; | 
			
		
	
		
			
				
					|  |  |  |             let r = (self.__test_state / self.row as usize) % self.row as usize; | 
			
		
	
		
			
				
					|  |  |  |             self.set_colour(r, c, (self.board[r][c] + 1) % 8)?; | 
			
		
	
		
			
				
					|  |  |  |             self.__test_state += 1; | 
			
		
	
		
			
				
					|  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |         
 | 
			
		
	
		
			
				
					|  |  |  |         let posn = mouse::position(ctx); | 
			
		
	
		
			
				
					|  |  |  |         if self.__test_pawn_held { | 
			
		
	
		
			
				
					|  |  |  |             if !mouse::button_pressed(ctx, MouseButton::Left) { // no long clicking and dragging
 | 
			
		
	
		
			
				
					|  |  |  |                 let (x, y) = self.closest_square_coords(posn.x, posn.y); | 
			
		
	
		
			
				
					|  |  |  |                 self.__test_pawn_x = x; | 
			
		
	
		
			
				
					|  |  |  |                 self.__test_pawn_y = y; | 
			
		
	
		
			
				
					|  |  |  |                 self.__test_pawn_held = false; | 
			
		
	
		
			
				
					|  |  |  |         for actor in self.actors.iter_mut() { | 
			
		
	
		
			
				
					|  |  |  |             match actor.posn { | 
			
		
	
		
			
				
					|  |  |  |                 Floating { | 
			
		
	
		
			
				
					|  |  |  |                     x: _, | 
			
		
	
		
			
				
					|  |  |  |                     y: _, | 
			
		
	
		
			
				
					|  |  |  |                     held_x, | 
			
		
	
		
			
				
					|  |  |  |                     held_y, | 
			
		
	
		
			
				
					|  |  |  |                 } => { | 
			
		
	
		
			
				
					|  |  |  |                     if !mouse::button_pressed(ctx, MouseButton::Left) { | 
			
		
	
		
			
				
					|  |  |  |                         // no long clicking and dragging
 | 
			
		
	
		
			
				
					|  |  |  |                         let (x, y) = closest_square_coords(posn.x, posn.y, self.col, self.row); | 
			
		
	
		
			
				
					|  |  |  |                         actor.posn = Board { x, y }; | 
			
		
	
		
			
				
					|  |  |  |                     } else { | 
			
		
	
		
			
				
					|  |  |  |                 self.__test_pawn_x = posn.x + self.__test_pawn_h_x; | 
			
		
	
		
			
				
					|  |  |  |                 self.__test_pawn_y = posn.y + self.__test_pawn_h_y; | 
			
		
	
		
			
				
					|  |  |  |                         actor.posn = Floating { | 
			
		
	
		
			
				
					|  |  |  |                             x: posn.x + held_x, | 
			
		
	
		
			
				
					|  |  |  |                             y: posn.y + held_y, | 
			
		
	
		
			
				
					|  |  |  |                             held_x, | 
			
		
	
		
			
				
					|  |  |  |                             held_y, | 
			
		
	
		
			
				
					|  |  |  |                         }; | 
			
		
	
		
			
				
					|  |  |  |                     } | 
			
		
	
		
			
				
					|  |  |  |                 } | 
			
		
	
		
			
				
					|  |  |  |                 Board { x, y } => { | 
			
		
	
		
			
				
					|  |  |  |                     if mouse::button_pressed(ctx, MouseButton::Left) { | 
			
		
	
		
			
				
					|  |  |  |                         let (posx, posy) = | 
			
		
	
		
			
				
					|  |  |  |                             closest_square_coords(posn.x, posn.y, self.col, self.row); | 
			
		
	
		
			
				
					|  |  |  |                         if posx == x && posy == y { | 
			
		
	
		
			
				
					|  |  |  |                             let x = START_X + BOARD_SQUARE_SIZE * (x as f32); | 
			
		
	
		
			
				
					|  |  |  |                             let y = START_Y + BOARD_SQUARE_SIZE * (y as f32); | 
			
		
	
		
			
				
					|  |  |  |                             actor.posn = Floating { | 
			
		
	
		
			
				
					|  |  |  |                                 x, | 
			
		
	
		
			
				
					|  |  |  |                                 y, | 
			
		
	
		
			
				
					|  |  |  |                                 held_x: x - posn.x, | 
			
		
	
		
			
				
					|  |  |  |                                 held_y: y - posn.y, | 
			
		
	
		
			
				
					|  |  |  |                             }; | 
			
		
	
		
			
				
					|  |  |  |                         } | 
			
		
	
		
			
				
					|  |  |  |                     } | 
			
		
	
		
			
				
					|  |  |  |                 } | 
			
		
	
		
			
				
					|  |  |  |         } else if mouse::button_pressed(ctx, MouseButton::Left) { | 
			
		
	
		
			
				
					|  |  |  |             let posx = posn.x; | 
			
		
	
		
			
				
					|  |  |  |             let posy = posn.y; | 
			
		
	
		
			
				
					|  |  |  |             if posx >= self.__test_pawn_x && posx <= self.__test_pawn_x + BOARD_SQUARE_SIZE && posy >= self.__test_pawn_y && posy <= self.__test_pawn_y + BOARD_SQUARE_SIZE { | 
			
		
	
		
			
				
					|  |  |  |                 self.__test_pawn_h_x = self.__test_pawn_x - posx; | 
			
		
	
		
			
				
					|  |  |  |                 self.__test_pawn_h_y = self.__test_pawn_y - posy; | 
			
		
	
		
			
				
					|  |  |  |                     self.__test_pawn_held = true; | 
			
		
	
		
			
				
					|  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  |         } else { | 
			
		
	
		
			
				
					|  |  |  |             self.set_colour(((self.__test_pawn_y - START_Y) / BOARD_SQUARE_SIZE) as usize, ((self.__test_pawn_x - START_X) / BOARD_SQUARE_SIZE) as usize, 3)?; | 
			
		
	
		
			
				
					|  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |         
 | 
			
		
	
		
			
				
					|  |  |  |         Ok(()) | 
			
		
	
		
			
				
					|  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
	
		
			
				
					|  |  | @ -171,7 +203,24 @@ impl EventHandler for Apr { | 
			
		
	
		
			
				
					|  |  |  |             self.should_update_grid = false; | 
			
		
	
		
			
				
					|  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |         graphics::draw(ctx, &self.grid, drawparams)?; | 
			
		
	
		
			
				
					|  |  |  |         graphics::draw(ctx, &self.__test_pawn_image, drawparams.dest([self.__test_pawn_x, self.__test_pawn_y]))?; | 
			
		
	
		
			
				
					|  |  |  |         for actor in &self.actors { | 
			
		
	
		
			
				
					|  |  |  |             match actor.posn { | 
			
		
	
		
			
				
					|  |  |  |                 Floating { | 
			
		
	
		
			
				
					|  |  |  |                     x, | 
			
		
	
		
			
				
					|  |  |  |                     y, | 
			
		
	
		
			
				
					|  |  |  |                     held_x: _, | 
			
		
	
		
			
				
					|  |  |  |                     held_y: _, | 
			
		
	
		
			
				
					|  |  |  |                 } => graphics::draw(ctx, &actor.image, drawparams.dest([x, y]))?, | 
			
		
	
		
			
				
					|  |  |  |                 Board { x, y } => graphics::draw( | 
			
		
	
		
			
				
					|  |  |  |                     ctx, | 
			
		
	
		
			
				
					|  |  |  |                     &actor.image, | 
			
		
	
		
			
				
					|  |  |  |                     drawparams.dest([ | 
			
		
	
		
			
				
					|  |  |  |                         START_X + BOARD_SQUARE_SIZE * (x as f32), | 
			
		
	
		
			
				
					|  |  |  |                         START_Y + BOARD_SQUARE_SIZE * (y as f32), | 
			
		
	
		
			
				
					|  |  |  |                     ]), | 
			
		
	
		
			
				
					|  |  |  |                 )?, | 
			
		
	
		
			
				
					|  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |         // Draw code here...
 | 
			
		
	
		
			
				
					|  |  |  |         graphics::present(ctx) | 
			
		
	
		
			
				
					|  |  |  |     } | 
			
		
	
	
		
			
				
					|  |  | @ -188,9 +237,7 @@ fn main() -> GameResult<()> { | 
			
		
	
		
			
				
					|  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     // Make a Context.
 | 
			
		
	
		
			
				
					|  |  |  |     let (mut ctx, event_loop) = cb | 
			
		
	
		
			
				
					|  |  |  |         .build() | 
			
		
	
		
			
				
					|  |  |  |         .expect("aieee, could not create ggez context!"); | 
			
		
	
		
			
				
					|  |  |  |     let (mut ctx, event_loop) = cb.build().expect("aieee, could not create ggez context!"); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     // Create an instance of your event handler.
 | 
			
		
	
		
			
				
					|  |  |  |     // Usually, you should provide it with the Context object to
 | 
			
		
	
	
		
			
				
					|  |  | 
 |