1- use bevy:: { input:: common_conditions:: input_just_pressed, prelude:: * , window:: PrimaryWindow } ;
1+ use bevy:: {
2+ input:: common_conditions:: { input_just_pressed, input_just_released} ,
3+ prelude:: * ,
4+ window:: PrimaryWindow ,
5+ } ;
6+ use solitaire_solver:: Board ;
27
38use crate :: {
4- PegMoved , Selected ,
9+ Selected ,
510 board:: { BoardPosition , Peg } ,
611 viewport_to_world,
712} ;
@@ -13,10 +18,13 @@ impl Plugin for Input {
1318 fn build ( & self , app : & mut App ) {
1419 app. add_systems (
1520 PreUpdate ,
16- peg_selection_cursor. run_if ( input_just_pressed ( MouseButton :: Left ) ) ,
21+ grab_peg. run_if ( input_just_pressed ( MouseButton :: Left ) ) ,
22+ ) ;
23+ app. add_systems (
24+ PreUpdate ,
25+ release_peg. run_if ( input_just_released ( MouseButton :: Left ) ) ,
1726 ) ;
1827 app. add_systems ( PreUpdate , peg_selection_touch) ;
19- app. add_observer ( on_board_clicked) ;
2028 }
2129}
2230
@@ -26,83 +34,74 @@ pub struct RequestPegMove {
2634 pub dst : BoardPosition ,
2735}
2836
29- #[ derive( Resource ) ]
30- struct SelectedPos ( BoardPosition ) ;
31-
32- #[ derive( Event ) ]
33- struct PosClicked ( BoardPosition ) ;
34-
35- fn on_board_clicked (
36- clicked_pos : On < PosClicked > ,
37+ fn grab_peg (
3738 mut commands : Commands ,
38- selected_pos : Option < ResMut < SelectedPos > > ,
39+ window : Single < & Window , With < PrimaryWindow > > ,
40+ camera_query : Single < ( & Camera , & GlobalTransform ) > ,
3941 pegs : Query < ( Entity , & BoardPosition ) , With < Peg > > ,
4042) {
41- let clicked = pegs. iter ( ) . find ( |( _, p) | * * p == clicked_pos. 0 ) ;
42- let selected =
43- selected_pos. map ( |selected_pos| pegs. iter ( ) . find ( |( _, p) | * * p == selected_pos. 0 ) . unwrap ( ) ) ;
44-
45- match ( selected, clicked) {
46- ( None , Some ( ( clicked, clicked_pos) ) ) => {
47- commands. insert_resource ( SelectedPos ( * clicked_pos) ) ;
48- commands. entity ( clicked) . insert ( Selected ) ;
49- }
50- ( Some ( ( selected, selected_pos) ) , clicked) => {
51- commands. entity ( selected) . remove :: < Selected > ( ) ;
52- commands. remove_resource :: < SelectedPos > ( ) ;
53- commands. trigger ( PegMoved { peg : selected } ) ; // snap back
54- if let Some ( ( clicked, clicked_pos) ) = clicked {
55- if selected != clicked {
56- commands. insert_resource ( SelectedPos ( * clicked_pos) ) ;
57- commands. entity ( clicked) . insert ( Selected ) ;
43+ let ( camera, camera_transform) = * camera_query;
44+ if let Some ( cursor_pos) = window. cursor_position ( ) {
45+ if let Some ( world_pos_cursor) = viewport_to_world ( cursor_pos, camera, camera_transform) {
46+ let board_pos = BoardPosition :: from_world_space ( world_pos_cursor. xy ( ) ) ;
47+ if Board :: inbounds ( board_pos. into ( ) ) {
48+ if let Some ( peg) = pegs. iter ( ) . find ( |( _, p) | * * p == board_pos) . map ( |( p, _) | p) {
49+ commands. entity ( peg) . insert ( Selected ) ;
5850 }
59- } else {
60- commands. trigger ( RequestPegMove {
61- src : * selected_pos,
62- dst : clicked_pos. 0 ,
63- } ) ;
6451 }
65- }
66- _ => { }
52+ } ;
6753 }
6854}
6955
70- fn peg_selection_cursor (
56+ fn release_peg (
7157 mut commands : Commands ,
7258 window : Single < & Window , With < PrimaryWindow > > ,
7359 camera_query : Single < ( & Camera , & GlobalTransform ) > ,
60+ selected_pegs : Query < ( Entity , & BoardPosition ) , ( With < Peg > , With < Selected > ) > ,
7461) {
62+ let ( camera, camera_transform) = * camera_query;
7563 if let Some ( cursor_pos) = window. cursor_position ( ) {
76- let ( camera, camera_transform) = * camera_query;
77- let Some ( world_pos_cursor) = viewport_to_world ( cursor_pos, camera, camera_transform) else {
78- return ;
64+ if let Some ( world_pos_cursor) = viewport_to_world ( cursor_pos, camera, camera_transform) {
65+ let board_pos = BoardPosition :: from_world_space ( world_pos_cursor. xy ( ) ) ;
66+ for ( selected_peg, & current_pos) in selected_pegs {
67+ commands. entity ( selected_peg) . remove :: < Selected > ( ) ;
68+ commands. trigger ( RequestPegMove {
69+ src : current_pos,
70+ dst : board_pos,
71+ } ) ;
72+ }
7973 } ;
80- let board_pos = BoardPosition :: from_world_space ( world_pos_cursor. xy ( ) ) ;
81- commands. trigger ( PosClicked ( board_pos) ) ;
8274 }
8375}
8476
85- #[ derive( Resource , PartialEq , Eq ) ]
86- struct CurrentTouchId ( u64 ) ;
87-
8877fn peg_selection_touch (
8978 mut commands : Commands ,
9079 touches : Res < Touches > ,
9180 camera_query : Single < ( & Camera , & GlobalTransform ) > ,
92- current_touch_id : Option < Res < CurrentTouchId > > ,
81+ pegs : Query < ( Entity , & BoardPosition ) , With < Peg > > ,
82+ selected_pegs : Query < ( Entity , & BoardPosition ) , ( With < Peg > , With < Selected > ) > ,
9383) {
94- for touch in touches. iter ( ) {
95- if touches. just_pressed ( touch. id ( ) )
96- || Some ( touch. id ( ) ) != current_touch_id. as_ref ( ) . map ( |id| id. 0 )
97- {
98- let ( camera, camera_transform) = * camera_query;
99- let Some ( world_pos) = viewport_to_world ( touch. position ( ) , camera, camera_transform)
100- else {
101- return ;
102- } ;
84+ let ( camera, camera_transform) = * camera_query;
85+ for touch in touches. iter_just_pressed ( ) {
86+ if let Some ( world_pos) = viewport_to_world ( touch. position ( ) , camera, camera_transform) {
87+ let board_pos = BoardPosition :: from_world_space ( world_pos. xy ( ) ) ;
88+ if Board :: inbounds ( board_pos. into ( ) ) {
89+ if let Some ( peg) = pegs. iter ( ) . find ( |( _, p) | * * p == board_pos) . map ( |( p, _) | p) {
90+ commands. entity ( peg) . insert ( Selected ) ;
91+ }
92+ }
93+ }
94+ }
95+ for touch in touches. iter_just_released ( ) {
96+ if let Some ( world_pos) = viewport_to_world ( touch. position ( ) , camera, camera_transform) {
10397 let board_pos = BoardPosition :: from_world_space ( world_pos. xy ( ) ) ;
104- commands. trigger ( PosClicked ( board_pos) ) ;
98+ for ( selected_peg, & current_pos) in selected_pegs {
99+ commands. entity ( selected_peg) . remove :: < Selected > ( ) ;
100+ commands. trigger ( RequestPegMove {
101+ src : current_pos,
102+ dst : board_pos,
103+ } ) ;
104+ }
105105 }
106- commands. insert_resource ( CurrentTouchId ( touch. id ( ) ) ) ;
107106 }
108107}
0 commit comments