123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193 |
- use bevy::{
- app::AppExit,
- prelude::*,
- };
- use bevy_mod_picking::*;
- use crate::pieces::*;
- pub struct Square {
- pub x: u8,
- pub y: u8,
- }
- impl Square {
- fn is_white(&self) -> bool {
- (self.x + self.y + 1) % 2 == 0
- }
- }
- struct PlayerTurn(PieceColor);
- impl Default for PlayerTurn {
- fn default() -> Self {
- Self(PieceColor::White)
- }
- }
- #[derive(Default)]
- struct SelectedSquare {
- entity: Option<Entity>,
- }
- #[derive(Default)]
- struct SelectedPiece {
- entity: Option<Entity>,
- }
- pub struct BoardPlugin;
- impl Plugin for BoardPlugin {
- fn build(&self, app: &mut AppBuilder) {
- app.init_resource::<SelectedSquare>()
- .init_resource::<SelectedPiece>()
- .init_resource::<PlayerTurn>()
- .add_startup_system(create_board.system())
- .add_system(select_square.system());
- }
- }
- fn create_board(
- mut commands: Commands,
- mut meshes: ResMut<Assets<Mesh>>,
- mut materials: ResMut<Assets<StandardMaterial>>,
- mut highlight_colors: ResMut<MeshButtonMaterials>,
- ) {
- // add meshes and materials
- let mesh = meshes.add(Mesh::from(shape::Plane {size: 1.0}));
- for i in 0..8 {
- for j in 0..8 {
- commands
- .spawn_bundle(PbrBundle {
- mesh: mesh.clone(),
- material: if (i + j + 1) % 2 == 0 {
- materials.add(Color::rgb(1.0, 0.9, 0.9).into())
- } else {
- materials.add(Color::rgb(0.0, 0.1, 0.1).into())
- },
- transform: Transform::from_translation(Vec3::new(i as f32, 0.0, j as f32)),
- ..Default::default()
- })
- .insert_bundle(PickableBundle::default())
- .insert(Square {
- x: i,
- y: j,
- });
- }
- }
- highlight_colors.hovered = materials.add(Color::rgb(0.8, 0.3, 0.3).into());
- highlight_colors.pressed = materials.add(Color::rgb(0.9, 0.5, 0.5).into());
- highlight_colors.selected = materials.add(Color::rgb(0.9, 0.1, 0.1).into());
- }
- fn select_square(
- mut commands: Commands,
- mouse_button_inputs: Res<Input<MouseButton>>,
- mut selected_square: ResMut<SelectedSquare>,
- mut selected_piece: ResMut<SelectedPiece>,
- mut turn: ResMut<PlayerTurn>,
- mut app_exit_events: EventWriter<AppExit>,
- camera_query: Query<&PickingCamera>,
- squares_query: Query<&Square>,
- mut pieces_query: Query<(Entity, &mut Piece, &Children)>,
- ) {
- if !mouse_button_inputs.just_pressed(MouseButton::Left) {
- return;
- }
- for camera in camera_query.iter() {
- if let Some((square_entity, _intersection)) = camera.intersect_top() {
- let pieces_entity_vec: Vec<(Entity, Piece, Vec<Entity>)> = pieces_query
- .iter_mut()
- .map(|(entity, piece, children)| {
- (
- entity,
- *piece,
- children.iter().map(|entity| *entity).collect()
- )
- })
- .collect();
- let pieces_vec = pieces_query
- .iter_mut()
- .map(|(_, piece, _)| *piece)
- .collect();
- if let Ok(square) = squares_query.get(square_entity) {
- selected_square.entity = Some(square_entity);
- // if a piece is already selected, set it to move
- if let Some(selected_piece_entity) = selected_piece.entity {
- if let Ok((_piece_entity, mut piece, _)) = pieces_query.get_mut(selected_piece_entity) {
- if piece.is_move_valid((square.x, square.y), &pieces_vec) {
- // check to see if we're capturing
- for (other_entity, other_piece, other_children) in pieces_entity_vec {
- if other_piece.x == square.x
- && other_piece.y == square.y
- && other_piece.color != piece.color
- {
- // if the king is taken, exit
- if other_piece.piece_type == PieceType::King {
- println!(
- "{} won! Thanks for playing!",
- match turn.0 {
- PieceColor::White => "White",
- PieceColor::Black => "Black",
- }
- );
- app_exit_events.send(AppExit);
- }
- // despawn the piece and its children
- commands.entity(other_entity).despawn();
- for child in other_children {
- commands.entity(child).despawn();
- }
- }
- }
- // and set it to move
- piece.x = square.x;
- piece.y = square.y;
- turn.0 = match turn.0 {
- PieceColor::White => PieceColor::Black,
- PieceColor::Black => PieceColor::White,
- }
- }
- }
- selected_square.entity = None;
- selected_piece.entity = None;
- } else {
- // otherwise, select the piece (if one) in the selected square
- for (piece_entity, piece, _) in pieces_query.iter_mut() {
- if piece.x == square.x
- && piece.y == square.y
- && piece.color == turn.0
- {
- selected_piece.entity = Some(piece_entity);
- break;
- }
- }
- }
- }
- } else {
- // clicked on nothing, deselect
- selected_square.entity = None;
- selected_piece.entity = None;
- }
- }
- }
|