@ -12,7 +12,7 @@ use bevy::{
/// TODO: Handle Cursor!
/// TODO: Handle Cursor!
///
///
use crate ::{
use crate ::{
game ::{ ActiveTile , Board , BoardIndex , Piece },
game ::{ ActiveTile , Board , BoardIndex , Piece , Tile },
prelude ::* ,
prelude ::* ,
} ;
} ;
@ -42,15 +42,17 @@ impl Plugin for Display2dPlugin {
. run_if ( any_with_component ::< game ::Selected > ( ) ) ,
. run_if ( any_with_component ::< game ::Selected > ( ) ) ,
cancel_place
cancel_place
. run_if ( in_state ( GameState ::Display2d ) )
. run_if ( in_state ( GameState ::Display2d ) )
. run_if ( any_with_component ::< game ::Selected > ( ) ) ,
. run_if ( on_event ::< MouseButtonInput > ( ) ) ,
snap_back_cancel
. run_if ( in_state ( GameState ::Display2d ) )
. run_if ( any_component_removed ::< game ::Selected > ( ) ) ,
update_background . run_if ( on_event ::< WindowResized > ( ) ) ,
update_background . run_if ( on_event ::< WindowResized > ( ) ) ,
draw_board
// PERF: Only need to run when piece2d or tile2d added
. run_if ( resource_exists ::< SpriteSheet > ( ) )
set_sprite ,
. run_if ( any_component_removed ::< game ::Selected > ( ) ) // trigger if item was de-selected
set_transform ,
. run_if ( any_with_component ::< BoardIndex > ( ) ) ,
) ,
) ,
)
)
. add_systems ( OnEnter ( GameState ::Display2d ) , ( activate , draw_board ) )
. add_systems ( OnEnter ( GameState ::Display2d ) , activate )
. add_systems ( OnExit ( GameState ::Display2d ) , deactivate ) ;
. add_systems ( OnExit ( GameState ::Display2d ) , deactivate ) ;
}
}
}
}
@ -67,7 +69,10 @@ struct Board2d;
/// Marker for 2d piece entities
/// Marker for 2d piece entities
#[ derive(Debug, Component) ]
#[ derive(Debug, Component) ]
struct Piece2d ;
pub ( crate ) struct Piece2d ;
#[ derive(Debug, Component) ]
struct Tile2d ;
#[ derive(Debug, Component) ]
#[ derive(Debug, Component) ]
struct Display2dCamera ;
struct Display2dCamera ;
@ -151,16 +156,11 @@ fn update_background(
}
}
/// STARTUP: Initialize the board for representation
/// STARTUP: Initialize the board for representation
fn initialize_board ( sprite_sheet: Option < Res < SpriteSheet > > , mut commands : Commands ) {
fn initialize_board ( board: Option < Res < Board > > , mut commands : Commands ) {
if let Some ( sprite_sheet) = sprite_sheet {
if let Some ( board) = board {
commands
commands
. spawn ( (
. spawn ( (
SpatialBundle {
SpatialBundle {
transform : Transform ::from_xyz (
- SCALE * TILE_SIZE * 7.0 / 2.0 , // TODO: WHY???
- SCALE * TILE_SIZE * 3.0 / 2.0 , // Why 7 and 3??
0.0 ,
) ,
visibility : Visibility ::Hidden ,
visibility : Visibility ::Hidden ,
.. default ( )
.. default ( )
} ,
} ,
@ -170,82 +170,78 @@ fn initialize_board(sprite_sheet: Option<Res<SpriteSheet>>, mut commands: Comman
for i in 0 .. 32 {
for i in 0 .. 32 {
let x = i % 8 ;
let x = i % 8 ;
let y = i / 8 ;
let y = i / 8 ;
let s = ( x % 2 ) ^ ( y % 2 ) ;
let transform = Transform ::from_scale ( Vec3 ::splat ( SCALE ) ) . with_translation (
Vec3 ::new ( SCALE * 16.0 * x as f32 , SCALE * 16.0 * y as f32 , 0.0 ) ,
) ;
let sprite = TextureAtlasSprite ::new ( s ) ;
let texture_atlas = sprite_sheet . handle . clone ( ) ;
let index = BoardIndex { x , y } ;
let index = BoardIndex { x , y } ;
// Rectangle
let s = ( x % 2 ) ^ ( y % 2 ) ;
parent . spawn ( (
let tile = if s = = 0 { Tile ::Dark } else { Tile ::Light } ;
SpriteSheetBundle {
texture_atlas ,
parent . spawn ( ( tile , index , Tile2d , SpriteSheetBundle { .. default ( ) } ) ) ;
sprite ,
transform ,
.. default ( )
} ,
index ,
) ) ;
}
}
} ) ;
}
}
/// Update the location of pieces on the board
board . pieces ( ) . iter ( ) . for_each ( | ( piece , index ) | {
fn draw_board (
board : Option < Res < Board > > ,
sprite_sheet : Option < Res < SpriteSheet > > ,
root : Query < Entity , With < Board2d > > ,
tiles : Query < ( & Transform , & BoardIndex ) > ,
pieces : Query < Entity , With < Piece2d > > ,
mut commands : Commands ,
) {
if let ( Some ( board ) , Some ( sprite_sheet ) ) = ( board , sprite_sheet ) {
pieces
. iter ( )
. for_each ( | entity | commands . entity ( entity ) . despawn_recursive ( ) ) ;
commands . entity ( root . single ( ) ) . with_children ( | parent | {
board
. pieces ( )
. iter ( )
. filter_map ( | ( board_index , piece ) | {
tiles . iter ( ) . find_map ( | ( transform , this_index ) | {
( * this_index = = * board_index ) . then ( | | ( piece , transform , this_index ) )
} )
} )
. for_each ( | ( piece , transform , index ) | {
let texture_atlas = sprite_sheet . handle . clone ( ) ;
let s = match piece {
Piece ::Queen = > 2 ,
Piece ::Drone = > 3 ,
Piece ::Pawn = > 4 ,
} ;
let sprite = TextureAtlasSprite ::new ( s ) ;
// TODO: transform is slightly different, set sprite
// TODO: transform is slightly different, set sprite
parent . spawn ( (
parent . spawn ( (
piece . clone ( ) ,
piece . clone ( ) ,
SpriteSheetBundle {
texture_atlas ,
sprite ,
transform : Transform {
.. transform . clone ( )
} ,
.. default ( )
} ,
Piece2d ,
Piece2d ,
index . clone ( ) ,
index . clone ( ) ,
SpriteSheetBundle { .. default ( ) } ,
) ) ;
) ) ;
} ) ;
} ) ;
} ) ;
} ) ;
}
}
}
}
fn set_sprite (
mut events : Query <
(
& mut TextureAtlasSprite ,
& mut Handle < TextureAtlas > ,
Option < & Piece > ,
Option < & Tile > ,
) ,
Or < ( Added < Piece > , Added < Tile2d > ) > ,
> ,
sprite_sheet : Option < Res < SpriteSheet > > ,
) {
if let Some ( sprite_sheet ) = sprite_sheet {
events
. iter_mut ( )
. for_each ( | ( mut sprite , mut texture_atlas , piece , tile ) | {
* texture_atlas = sprite_sheet . handle . clone ( ) ;
let s = match piece {
Some ( Piece ::Queen ) = > 2 ,
Some ( Piece ::Drone ) = > 3 ,
Some ( Piece ::Pawn ) = > 4 ,
None = > match tile {
Some ( Tile ::Dark ) = > 0 ,
Some ( Tile ::Light ) = > 1 ,
None = > 99 ,
} ,
} ;
* sprite = TextureAtlasSprite ::new ( s ) ;
debug ! ( "Setting sprite for {:?} {:?}" , piece , tile ) ;
} ) ;
}
}
/// Sets a piece location given it's board index
fn set_transform (
mut events : Query <
( & mut Transform , & BoardIndex ) ,
(
Or < ( With < Piece2d > , With < Tile2d > ) > ,
Or < ( Changed < BoardIndex > , Added < BoardIndex > ) > ,
) ,
> ,
) {
events . iter_mut ( ) . for_each ( | ( mut t , i ) | {
let x = SCALE * 16.0 * ( ( i . x as f32 ) - 3.5 ) ;
let y = SCALE * 16.0 * ( ( i . y as f32 ) - 1.5 ) ;
* t = Transform ::from_scale ( Vec3 ::splat ( SCALE ) ) . with_translation ( Vec3 ::new ( x , y , 0.0 ) ) ;
info ! ( "setting position of {:?} to {:?}" , i , t ) ;
} ) ;
}
fn activate (
fn activate (
mut cameras : Query < & mut Camera , With < Display2dCamera > > ,
mut cameras : Query < & mut Camera , With < Display2dCamera > > ,
mut boards : Query < & mut Visibility , With < Board2d > > ,
mut boards : Query < & mut Visibility , With < Board2d > > ,
@ -296,7 +292,7 @@ fn active_tile(
let size = {
let size = {
let sprite_size = atlases
let sprite_size = atlases
. get ( handle )
. get ( handle )
. map ( | atlas | atlas . textures . get ( * index ) . expect ( "Get this rect ") )
. map ( | atlas | atlas . textures . get ( * index ) . expect ( "Get this rect texture ") )
. expect ( "get this rect" )
. expect ( "get this rect" )
. size ( ) ;
. size ( ) ;
let ( transform_scale , _ , _ ) = transform . to_scale_rotation_translation ( ) ;
let ( transform_scale , _ , _ ) = transform . to_scale_rotation_translation ( ) ;
@ -372,7 +368,8 @@ fn place_piece(
active : Res < ActiveTile > ,
active : Res < ActiveTile > ,
mut board : ResMut < Board > ,
mut board : ResMut < Board > ,
mut commands : Commands ,
mut commands : Commands ,
mut writer : EventWriter < game ::GameEvent > ,
mut game_events : EventWriter < game ::GameEvent > ,
mut move_events : EventWriter < game ::Move > ,
) {
) {
events
events
. iter ( )
. iter ( )
@ -391,11 +388,14 @@ fn place_piece(
) )
) )
} )
} )
. for_each ( | ( entity , from , to ) | match board . move_piece ( from , to ) {
. for_each ( | ( entity , from , to ) | match board . move_piece ( from , to ) {
Ok ( ( ) ) = > {
Ok ( moves ) = > {
commands . entity ( entity ) . remove ::< game ::Selected > ( ) ;
commands . entity ( entity ) . remove ::< game ::Selected > ( ) ;
writer . send ( game ::GameEvent ::PlacePiece ) ;
moves . iter ( ) . for_each ( | m | {
move_events . send ( m . clone ( ) ) ;
} ) ;
game_events . send ( game ::GameEvent ::PlacePiece ) ;
}
}
Err ( game ::GameError ::NullMove ) = > writer . send ( game ::GameEvent ::PlacePiece ) ,
Err ( game ::GameError ::NullMove ) = > game_events . send ( game ::GameEvent ::PlacePiece ) ,
Err ( game ::GameError ::InvalidMove ) = > warn ! ( "Invalid move!" ) ,
Err ( game ::GameError ::InvalidMove ) = > warn ! ( "Invalid move!" ) ,
} )
} )
}
}
@ -417,3 +417,19 @@ fn cancel_place(
writer . send ( game ::GameEvent ::PlacePiece ) ;
writer . send ( game ::GameEvent ::PlacePiece ) ;
} )
} )
}
}
fn snap_back_cancel (
mut events : RemovedComponents < game ::Selected > ,
query : Query < & game ::BoardIndex , With < Piece2d > > ,
mut move_events : EventWriter < game ::Move > ,
) {
events . iter ( ) . for_each ( | entity | {
if let Ok ( idx ) = query . get ( entity ) {
move_events . send ( game ::Move {
epoch : 0 ,
from : idx . clone ( ) ,
to : Some ( idx . clone ( ) ) ,
} ) ;
}
} )
}