Approved.
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.

267 lines
9.4 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,
xlen: u8,
ylen: u8,
board: &[Vec<(u8, u8)>],
) -> GameResult<Mesh> {
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<Apr> {
// Load/create resources such as images here.
let mut board = board::make_board(xlen, ylen);
let mut actors: Vec<actor::Actor> = Vec::new();
let mut behaviours: Vec<behaviour::Behaviour> = 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)
}
}