use ggez::event::EventHandler; use ggez::graphics::{self, Color, DrawMode, Mesh, MeshBuilder}; use ggez::input::mouse::{self, MouseButton}; use ggez::{Context, GameResult}; use crate::actor; use crate::behaviour; use crate::board; pub struct Apr { board: board::Board, grid: Mesh, should_update_grid: bool, dragging: bool, actors: Vec, #[allow(dead_code)] behaviours: Vec, } pub fn make_grid( ctx: &mut Context, xlen: u8, ylen: u8, board: &[Vec<(u8, u8)>], ) -> GameResult { let mut builder = MeshBuilder::new(); for x in 0..xlen { for y in 0..ylen { builder.rectangle( DrawMode::fill(), graphics::Rect { x: board::START_X + (board::BOARD_SQUARE_SIZE * f32::from(x)), y: board::START_Y + (board::BOARD_SQUARE_SIZE * f32::from(y)), w: board::BOARD_SQUARE_SIZE, h: board::BOARD_SQUARE_SIZE, }, match board[x as usize][y as usize].0 % 2 { 0 => Color::WHITE, 1 => Color::BLACK, _ => Color::BLACK, //impossible }, )?; } } builder.build(ctx) } impl Apr { pub fn new(_ctx: &mut Context, xlen: u8, ylen: u8) -> GameResult { // Load/create resources such as images here. let mut board = board::make_board(xlen, ylen); let mut actors: Vec = Vec::new(); let mut behaviours: Vec = vec![behaviour::Behaviour { moves: vec![ behaviour::MovePattern { movement: (1, 0), amount: 255, negx: true, negy: false, }, behaviour::MovePattern { movement: (0, 1), amount: 255, negx: false, negy: true, }, behaviour::MovePattern { movement: (1, 1), amount: 255, negx: true, negy: true, }, ], }]; //pawn can move ONE forward, ONCE. not really the best test for i in 0..xlen { // white side pawns <<<<<<< HEAD actors.push(actor::Actor::new( _ctx, "/pawn.png", i, 1, behaviours.len() as u8, )); behaviours.push(behaviour::Behaviour::new( vec![(1, 1)], vec![(1, -1), (-1, -1)], )); } for i in 0..=1 { // white side knights actors.push(actor::Actor::new( _ctx, "/pawn.png", i, 0, behaviours.len() as u8, )); behaviours.push(behaviour::Behaviour::new( vec![(1, 2)], vec![(1, -1), (-1, -1)], )); } for i in 0..r { // black side pawns actors.push(actor::Actor::new( _ctx, "/pawn2.png", i, c - 2, behaviours.len() as u8, )); behaviours.push(behaviour::Behaviour::new( vec![(1, 1)], vec![(1, 1), (-1, 1)], )); } for i in 0..=1 { // black side knights actors.push(actor::Actor::new( _ctx, "/pawn2.png", i, c - 1, behaviours.len() as u8, )); behaviours.push(behaviour::Behaviour::new( vec![(1, 2)], vec![(1, 1), (-1, 1)], )); ======= actors.push(actor::Actor::new(_ctx, "/pawn.png", i, 6, 0)); <<<<<<< HEAD >>>>>>> 4b6cfb4cbffca15aad2526287cb1ba8d58909c60 ======= board.board[usize::from(i)][6].1 = i; >>>>>>> badc482d63df8eb117f259445c08bd36596d836b } actors.push(actor::Actor::new(_ctx, "/pawn.png", 4, 4, 0)); //blocking pawn for testing board.board[4][4].1 = xlen; Ok(Apr { grid: make_grid(_ctx, xlen, ylen, board.board.as_slice())?, board, should_update_grid: false, actors, dragging: false, behaviours, }) } #[allow(dead_code)] pub fn set_colour(&mut self, x: usize, y: usize, clr: u8) { //You should only modify self.board through this method. self.board.board[x][y].0 = clr; //Making a getter for self.board would sadly break borrowing in the same way that closest_square_coords does. self.should_update_grid = true; //Similar solutions apply. } } impl EventHandler for Apr { fn update(&mut self, ctx: &mut Context) -> GameResult<()> { let posn = mouse::position(ctx); for (index, actor) in self.actors.iter_mut().enumerate() { match actor.posn { actor::ActorPosn::FloatingPosn { x: _, y: _, held_x, held_y, prev_x, prev_y, } => { if !mouse::button_pressed(ctx, MouseButton::Left) { // no long clicking and dragging let (x, y) = self.board.closest_square_coords(posn.x, posn.y); if self.dragging { // released, so now we check destination if !self.behaviours[usize::from(actor.behaviour)].validate_dest( (prev_x, prev_y), (x, y), &self.board, ) { actor.posn = actor::ActorPosn::BoardPosn { x: prev_x, y: prev_y, }; } else { self.board.board[usize::from(prev_x)][usize::from(prev_y)].1 = 255; self.board.board[usize::from(x)][usize::from(y)].1 = index as u8; //only 255 actors allowed? should be fine (laughing) (we look back at this in 10 years and die) //[x][y] or [y][x]?? i think its [y][x] since row-column //update, eveyrthing is fucked actor.posn = actor::ActorPosn::BoardPosn { x, y }; } } self.dragging = false; } else { actor.posn = actor::ActorPosn::FloatingPosn { x: posn.x + held_x, y: posn.y + held_y, held_x, held_y, prev_x, prev_y, }; } } actor::ActorPosn::BoardPosn { x, y } => { if mouse::button_pressed(ctx, MouseButton::Left) && !self.dragging { let (posx, posy) = self.board.closest_square_coords(posn.x, posn.y); if posx == x && posy == y { let x = board::START_X + board::BOARD_SQUARE_SIZE * f32::from(x); let y = board::START_Y + board::BOARD_SQUARE_SIZE * f32::from(y); self.dragging = true; actor.posn = actor::ActorPosn::FloatingPosn { x, y, held_x: x - posn.x, held_y: y - posn.y, prev_x: posx, prev_y: posy, }; } } } } } Ok(()) } fn draw(&mut self, ctx: &mut Context) -> GameResult<()> { graphics::clear(ctx, Color::new(0.5, 0.5, 0.5, 1.0)); let drawparams = graphics::DrawParam::new(); if self.should_update_grid { self.grid = make_grid( ctx, self.board.xlen, self.board.ylen, self.board.board.as_slice(), )?; self.should_update_grid = false; } graphics::draw(ctx, &self.grid, drawparams)?; for actor in &self.actors { match actor.posn { actor::ActorPosn::FloatingPosn { x, y, .. } => { graphics::draw(ctx, &actor.image, drawparams.dest([x, y]))? } actor::ActorPosn::BoardPosn { x, y } => graphics::draw( ctx, &actor.image, drawparams.dest([ board::START_X + board::BOARD_SQUARE_SIZE * f32::from(x), //i might have to kill myself board::START_Y + board::BOARD_SQUARE_SIZE * f32::from(y), ]), )?, } } // Draw code here... graphics::present(ctx) } }