You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
159 lines
5.6 KiB
159 lines
5.6 KiB
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<actor::Actor>,
|
|
|
|
#[allow(dead_code)]
|
|
behaviours: Vec<behaviour::Behaviour>,
|
|
}
|
|
|
|
pub fn make_grid(ctx: &mut Context, r: u8, c: u8, board: &[Vec<u8>]) -> GameResult<Mesh> {
|
|
let mut builder = MeshBuilder::new();
|
|
|
|
for row in 0..r {
|
|
for col in 0..c {
|
|
builder.rectangle(
|
|
DrawMode::fill(),
|
|
graphics::Rect {
|
|
x: board::START_X + (board::BOARD_SQUARE_SIZE * col as f32),
|
|
y: board::START_Y + (board::BOARD_SQUARE_SIZE * row as f32),
|
|
w: board::BOARD_SQUARE_SIZE,
|
|
h: board::BOARD_SQUARE_SIZE,
|
|
},
|
|
match board[row as usize][col as usize] % 2 {
|
|
0 => Color::WHITE,
|
|
1 => Color::BLACK,
|
|
_ => Color::BLACK, //impossible
|
|
},
|
|
)?;
|
|
}
|
|
}
|
|
|
|
builder.build(ctx)
|
|
}
|
|
|
|
impl Apr {
|
|
pub fn new(_ctx: &mut Context, r: u8, c: u8) -> GameResult<Apr> {
|
|
// Load/create resources such as images here.
|
|
let board = board::make_board(r, c);
|
|
let mut actors: Vec<actor::Actor> = Vec::new();
|
|
for i in 0..r {
|
|
// white side
|
|
actors.push(actor::Actor::new(_ctx, "/pawn.png", i, 1, 0));
|
|
}
|
|
for i in 0..r {
|
|
// black side
|
|
actors.push(actor::Actor::new(_ctx, "/pawn2.png", i, c - 2, 0));
|
|
}
|
|
Ok(Apr {
|
|
grid: make_grid(_ctx, r, c, board.board.as_slice())?,
|
|
board,
|
|
should_update_grid: false,
|
|
actors,
|
|
dragging: false,
|
|
behaviours: vec![behaviour::Behaviour { // 4-tile-corner leaper pawn behaviour
|
|
moves: vec![(1, 1)],
|
|
dirs: (1, 0, 0, 0),
|
|
}], //the pawn can go TWO diagonally and to the right and only upwards
|
|
})
|
|
}
|
|
|
|
#[allow(dead_code)]
|
|
pub fn set_colour(&mut self, r: usize, c: usize, clr: u8) {
|
|
//You should only modify self.board through this method.
|
|
self.board.board[r][c] = 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 actor in self.actors.iter_mut() {
|
|
match actor.posn {
|
|
actor::ActorPosn::FloatingPosn {
|
|
x: _,
|
|
y: _,
|
|
held_x,
|
|
held_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);
|
|
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,
|
|
};
|
|
}
|
|
}
|
|
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 * (x as f32);
|
|
let y = board::START_Y + board::BOARD_SQUARE_SIZE * (y as f32);
|
|
self.dragging = true;
|
|
actor.posn = actor::ActorPosn::FloatingPosn {
|
|
x,
|
|
y,
|
|
held_x: x - posn.x,
|
|
held_y: y - posn.y,
|
|
};
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
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.row,
|
|
self.board.col,
|
|
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 * (x as f32),
|
|
board::START_Y + board::BOARD_SQUARE_SIZE * (y as f32),
|
|
]),
|
|
)?,
|
|
}
|
|
}
|
|
// Draw code here...
|
|
graphics::present(ctx)
|
|
}
|
|
}
|
|
|