diff --git a/src/board.rs b/src/board.rs index 3fbb3f8..fc790ea 100644 --- a/src/board.rs +++ b/src/board.rs @@ -1,6 +1,7 @@ -use crate::pieces::*; use bevy::prelude::*; -use bevy_mod_picking::*; +use bevy_mod_picking::{PickableBundle, PickingCamera}; + +use crate::pieces::{is_check_mate_on, is_check_on, Piece, PieceColor, PieceType}; pub struct Square { pub pos: IVec2, @@ -81,11 +82,16 @@ impl FromWorld for SquareMaterials { let mut materials = world .get_resource_mut::>() .unwrap(); + let make_material = |r, g, b| StandardMaterial { + roughness: 0.5, + base_color: Color::rgb(r, g, b), + ..Default::default() + }; SquareMaterials { - highlight_color: materials.add(Color::rgb(0.8, 0.3, 0.3).into()), - selected_color: materials.add(Color::rgb(0.9, 0.1, 0.1).into()), - black_color: materials.add(Color::rgb(0., 0.1, 0.1).into()), - white_color: materials.add(Color::rgb(1., 0.9, 0.9).into()), + highlight_color: materials.add(make_material(0.8, 0.3, 0.3)), + selected_color: materials.add(make_material(0.9, 0.1, 0.1)), + black_color: materials.add(make_material(0., 0.1, 0.1)), + white_color: materials.add(make_material(1., 0.9, 0.9)), } } } @@ -98,15 +104,30 @@ struct SelectedSquare { struct SelectedPiece { entity: Option, } -pub struct PlayerTurn(pub PieceColor); -impl Default for PlayerTurn { + +pub enum StatusType { + Move, + Win, +} + +pub struct GameStatus { + pub color: PieceColor, + pub status_type: StatusType, +} +impl Default for GameStatus { fn default() -> Self { - Self(PieceColor::White) + Self { + color: PieceColor::White, + status_type: StatusType::Move, + } } } -impl PlayerTurn { - fn change(&mut self) { - self.0 = self.0.other(); +impl GameStatus { + fn change(&mut self, pieces: &[Piece]) { + match is_check_mate_on(pieces, self.color.other()) { + false => self.color = self.color.other(), + true => self.status_type = StatusType::Win, + } } } @@ -140,7 +161,7 @@ fn select_square( fn select_piece( selected_square: Res, mut selected_piece: ResMut, - turn: Res, + game_status: Res, squares_query: Query<&Square>, pieces_query: Query<(Entity, &Piece)>, ) { @@ -161,7 +182,7 @@ fn select_piece( if selected_piece.entity.is_none() { // Select the piece in the currently selected square for (piece_entity, piece) in pieces_query.iter() { - if piece.pos == square.pos && piece.color == turn.0 { + if piece.pos == square.pos && piece.color == game_status.color { // piece_entity is now the entity in the same square selected_piece.entity = Some(piece_entity); break; @@ -174,7 +195,7 @@ fn move_piece( mut commands: Commands, selected_square: Res, selected_piece: Res, - mut turn: ResMut, + mut turn: ResMut, squares_query: Query<&Square>, mut pieces_query: Query<(Entity, &mut Piece)>, mut reset_selected_event: EventWriter, @@ -219,7 +240,7 @@ fn move_piece( // Move piece piece.pos = square.pos; piece.has_moved = true; - turn.change(); + turn.change(&pieces_after_move); // Check if a piece of the opposite color exists in this square and despawn it if let Some((entity, _)) = pieces_query @@ -263,7 +284,7 @@ impl Plugin for BoardPlugin { app.init_resource::() .init_resource::() .init_resource::() - .init_resource::() + .init_resource::() .add_event::() .add_startup_system(create_board.system()) .add_system(color_squares.system()) diff --git a/src/camera.rs b/src/camera.rs new file mode 100644 index 0000000..058ef47 --- /dev/null +++ b/src/camera.rs @@ -0,0 +1,91 @@ +use std::f32::consts::PI; + +use bevy::{prelude::*, render::camera::PerspectiveProjection}; +use bevy_mod_picking::PickingCameraBundle; + +use crate::{board::GameStatus, pieces::PieceColor}; + +const ACCELERATION: f32 = PI * 2.; +const INITIAL_SPEED: f32 = 0.5; +struct CameraPosition { + yaw: f32, +} + +impl Default for CameraPosition { + fn default() -> Self { + CameraPosition { yaw: -PI / 2. } + } +} + +impl CameraPosition { + fn get_rotation(&self) -> Quat { + Quat::from_rotation_ypr(self.yaw, -1.3, 0.) + } + + fn get_translation(&self) -> Vec3 { + Vec3::new( + 3.5 * (self.yaw.sin() + 1.), + 13., + 3.5 * (self.yaw.cos() + 1.), + ) + } + + fn get_speed(&self) -> f32 { + let theta = PI / 2. - self.yaw.abs(); + f32::sqrt(2. * ACCELERATION * theta) + INITIAL_SPEED + } +} + +fn setup(mut commands: Commands, camera_yaw: Res) { + commands + // Camera + .spawn_bundle(PerspectiveCameraBundle { + transform: Transform::from_matrix(Mat4::from_rotation_translation( + camera_yaw.get_rotation(), + camera_yaw.get_translation(), + )), + ..Default::default() + }) + .insert_bundle(PickingCameraBundle::default()) + // Light + .commands() + .spawn_bundle(LightBundle { + transform: Transform::from_translation(Vec3::new(3.5, 10., 3.5)), + ..Default::default() + }); +} + +fn reposition_camera( + time: Res