|  |  | @ -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; | 
			
		
	
	
		
			
				
					|  |  | @ -18,28 +18,35 @@ struct Apr { | 
			
		
	
		
			
				
					|  |  |  |     should_update_grid: bool, | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     actors: Vec<Actor>, | 
			
		
	
		
			
				
					|  |  |  |     behaviours: Vec<Behaviour> | 
			
		
	
		
			
				
					|  |  |  |     behaviours: Vec<Behaviour>, | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | struct Behaviour { | 
			
		
	
		
			
				
					|  |  |  |     moves: Vec<(u8, u8)> //this is a placeholder
 | 
			
		
	
		
			
				
					|  |  |  |     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} | 
			
		
	
		
			
				
					|  |  |  |     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
 | 
			
		
	
		
			
				
					|  |  |  |     behaviour: u8, //index into the behaviours array
 | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | fn make_grid(ctx: &mut Context, r: i32, c: i32, board: &[Vec<u8>]) -> GameResult<Mesh> { | 
			
		
	
		
			
				
					|  |  |  |     let mut builder = MeshBuilder::new(); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
	
		
			
				
					|  |  | @ -53,7 +60,7 @@ fn make_grid(ctx: &mut Context, r: i32, c: i32, board: &[Vec<u8>]) -> GameResult | 
			
		
	
		
			
				
					|  |  |  |                     w: BOARD_SQUARE_SIZE, | 
			
		
	
		
			
				
					|  |  |  |                     h: BOARD_SQUARE_SIZE, | 
			
		
	
		
			
				
					|  |  |  |                 }, | 
			
		
	
		
			
				
					|  |  |  |                 match board[row as usize][col as usize]  { | 
			
		
	
		
			
				
					|  |  |  |                 match board[row as usize][col as usize] { | 
			
		
	
		
			
				
					|  |  |  |                     0 => Color::WHITE, | 
			
		
	
		
			
				
					|  |  |  |                     1 => Color::BLACK, | 
			
		
	
		
			
				
					|  |  |  |                     2 => Color::RED, | 
			
		
	
	
		
			
				
					|  |  | @ -63,7 +70,7 @@ fn make_grid(ctx: &mut Context, r: i32, c: i32, board: &[Vec<u8>]) -> GameResult | 
			
		
	
		
			
				
					|  |  |  |                     6 => Color::BLUE, | 
			
		
	
		
			
				
					|  |  |  |                     7 => Color::MAGENTA, | 
			
		
	
		
			
				
					|  |  |  |                     _ => Color::BLACK, | 
			
		
	
		
			
				
					|  |  |  |                 } | 
			
		
	
		
			
				
					|  |  |  |                 }, | 
			
		
	
		
			
				
					|  |  |  |             )?; | 
			
		
	
		
			
				
					|  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |     } | 
			
		
	
	
		
			
				
					|  |  | @ -81,27 +88,26 @@ 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); | 
			
		
	
		
			
				
					|  |  |  |     //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); | 
			
		
	
		
			
				
					|  |  |  |     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; | 
			
		
	
		
			
				
					|  |  |  |     //Then, snap to board coords.
 | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     let x = (x / BOARD_SQUARE_SIZE) as u8; | 
			
		
	
		
			
				
					|  |  |  |     let y = (y / BOARD_SQUARE_SIZE) as u8; | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |         (x, y) | 
			
		
	
		
			
				
					|  |  |  |     (x, y) | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | impl Apr { | 
			
		
	
		
			
				
					|  |  |  |     pub fn new(_ctx: &mut Context, r: i32, c: i32) -> GameResult<Apr> { | 
			
		
	
	
		
			
				
					|  |  | @ -114,8 +120,14 @@ impl Apr { | 
			
		
	
		
			
				
					|  |  |  |             board, | 
			
		
	
		
			
				
					|  |  |  |             should_update_grid: false, | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |             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
 | 
			
		
	
		
			
				
					|  |  |  |             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
 | 
			
		
	
		
			
				
					|  |  |  |         }) | 
			
		
	
		
			
				
					|  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
	
		
			
				
					|  |  | @ -124,30 +136,47 @@ impl Apr { | 
			
		
	
		
			
				
					|  |  |  |         self.should_update_grid = true; | 
			
		
	
		
			
				
					|  |  |  |         Ok(()) | 
			
		
	
		
			
				
					|  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | impl EventHandler for Apr { | 
			
		
	
		
			
				
					|  |  |  |     fn update(&mut self, ctx: &mut Context) -> GameResult<()> { | 
			
		
	
		
			
				
					|  |  |  |         let posn = mouse::position(ctx); | 
			
		
	
		
			
				
					|  |  |  |         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
 | 
			
		
	
		
			
				
					|  |  |  |                 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}; | 
			
		
	
		
			
				
					|  |  |  |                         actor.posn = Board { x, y }; | 
			
		
	
		
			
				
					|  |  |  |                     } else { | 
			
		
	
		
			
				
					|  |  |  |                         actor.posn = Floating { x: posn.x + held_x, y: posn.y + held_y, held_x, held_y }; | 
			
		
	
		
			
				
					|  |  |  |                     }, | 
			
		
	
		
			
				
					|  |  |  |                 Board { x, 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); | 
			
		
	
		
			
				
					|  |  |  |                         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}; | 
			
		
	
		
			
				
					|  |  |  |                             actor.posn = Floating { | 
			
		
	
		
			
				
					|  |  |  |                                 x, | 
			
		
	
		
			
				
					|  |  |  |                                 y, | 
			
		
	
		
			
				
					|  |  |  |                                 held_x: x - posn.x, | 
			
		
	
		
			
				
					|  |  |  |                                 held_y: y - posn.y, | 
			
		
	
		
			
				
					|  |  |  |                             }; | 
			
		
	
		
			
				
					|  |  |  |                         } | 
			
		
	
		
			
				
					|  |  |  |                     } 
 | 
			
		
	
		
			
				
					|  |  |  |                 
 | 
			
		
	
		
			
				
					|  |  |  |                     } | 
			
		
	
		
			
				
					|  |  |  |                 } | 
			
		
	
		
			
				
					|  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |         Ok(()) | 
			
		
	
	
		
			
				
					|  |  | @ -163,11 +192,21 @@ impl EventHandler for Apr { | 
			
		
	
		
			
				
					|  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |         graphics::draw(ctx, &self.grid, drawparams)?; | 
			
		
	
		
			
				
					|  |  |  |         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)]))? | 
			
		
	
		
			
				
					|  |  |  |             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...
 | 
			
		
	
	
		
			
				
					|  |  | @ -186,9 +225,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
 | 
			
		
	
	
		
			
				
					|  |  | 
 |