@@ -15,10 +15,11 @@ import { Animator } from "src/main/rendering/animator";
1515import { Renderer } from "src/main/rendering/renderer" ;
1616import { putCanvas } from "src/main/utils/canvas-pool" ;
1717import { cellFocusMode } from "src/main/utils/constants" ;
18+ import { gamepad } from "src/main/utils/gamepad" ;
1819import { isFeaturePhone } from "src/main/utils/static-display" ;
1920import { bind } from "src/utils/bind" ;
2021import { StateChange } from "src/worker/gamelogic" ;
21- import { Cell } from "src/worker/gamelogic/types" ;
22+ import { Cell , PlayMode } from "src/worker/gamelogic/types" ;
2223import { GameChangeCallback } from "../../index" ;
2324import {
2425 board ,
@@ -45,24 +46,17 @@ export interface Props {
4546 renderer : Renderer ;
4647 animator : Animator ;
4748 dangerMode : boolean ;
49+ interactive : boolean ;
4850 gameChangeSubscribe : ( f : GameChangeCallback ) => void ;
4951 gameChangeUnsubscribe : ( f : GameChangeCallback ) => void ;
5052 onDangerModeChange : ( v : boolean ) => void ;
5153}
5254
53- interface State {
54- keyNavigation : boolean ;
55- }
56-
5755interface SetFocusOptions {
5856 preventScroll ?: boolean ;
5957}
6058
61- export default class Board extends Component < Props , State > {
62- state : State = {
63- keyNavigation : false
64- } ;
65-
59+ export default class Board extends Component < Props , { } > {
6660 private _canvas ?: HTMLCanvasElement ;
6761 private _table ?: HTMLTableElement ;
6862 private _buttons : HTMLButtonElement [ ] = [ ] ;
@@ -74,10 +68,6 @@ export default class Board extends Component<Props, State> {
7468 private _currentFocusableBtn ?: HTMLButtonElement ;
7569 private _tableContainer ?: HTMLDivElement ;
7670
77- private _gamepadState : boolean [ ] [ ] = [ ] ;
78- private _gamepadIsTicking = false ;
79- private _gamepadStopTicking = false ;
80-
8171 componentDidMount ( ) {
8272 document . documentElement . classList . add ( "in-game" ) ;
8373 this . _createTable ( this . props . width , this . props . height ) ;
@@ -105,23 +95,16 @@ export default class Board extends Component<Props, State> {
10595
10696 window . addEventListener ( "resize" , this . _onWindowResize ) ;
10797 window . addEventListener ( "keyup" , this . _onGlobalKeyUp ) ;
108- // @ts -ignore This version of TS does not know about gamepadconnected
109- window . addEventListener ( "gamepadconnected" , this . _onGamepadsUpdate ) ;
110- // @ts -ignore This version of TS does not know about gamepaddisconnected
111- window . addEventListener ( "gamepaddisconnected" , this . _onGamepadsUpdate ) ;
112- this . _gamepadStopTicking = false ;
113- this . _initGamepads ( ) ;
98+ gamepad . addButtonDownCallback ( this . _onGamepadButtonDown ) ;
99+ gamepad . addButtonPressCallback ( this . _onGamepadButtonPress ) ;
114100 }
115101
116102 componentWillUnmount ( ) {
117103 document . documentElement . classList . remove ( "in-game" ) ;
118104 window . removeEventListener ( "resize" , this . _onWindowResize ) ;
119105 window . removeEventListener ( "keyup" , this . _onGlobalKeyUp ) ;
120- // @ts -ignore This version of TS does not know about gamepadconnected
121- window . removeEventListener ( "gamepadconnected" , this . _onGamepadsUpdate ) ;
122- // @ts -ignore This version of TS does not know about gamepaddisconnected
123- window . removeEventListener ( "gamepaddisconnected" , this . _onGamepadsUpdate ) ;
124- this . _gamepadStopTicking = true ;
106+ gamepad . removeButtonDownCallback ( this . _onGamepadButtonDown ) ;
107+ gamepad . removeButtonPressCallback ( this . _onGamepadButtonPress ) ;
125108 this . props . gameChangeUnsubscribe ( this . _doManualDomHandling ) ;
126109 this . props . renderer . stop ( ) ;
127110 this . props . animator . stop ( ) ;
@@ -159,6 +142,9 @@ export default class Board extends Component<Props, State> {
159142
160143 @bind
161144 private _onGlobalKeyUp ( event : KeyboardEvent ) {
145+ if ( ! this . props . interactive ) {
146+ return ;
147+ }
162148 // This returns the focus to the board when one of these keys is pressed (on feature phones
163149 // only). This means the user doesn't have to manually refocus the board.
164150 if (
@@ -177,86 +163,52 @@ export default class Board extends Component<Props, State> {
177163 }
178164
179165 @bind
180- private _onGamepadsUpdate ( ) {
181- this . _initGamepads ( ) ;
182- }
183-
184- private _initGamepads ( ) {
185- this . _gamepadState = [ ] ;
186- if ( ! this . _gamepadIsTicking ) {
187- this . _gamepadIsTicking = true ;
188- requestAnimationFrame ( this . _gamepadTick ) ;
189- }
190- }
191-
192- @bind
193- private _gamepadTick ( ) {
194- const gamepads = navigator . getGamepads ( ) ;
195-
196- const oldState = this . _gamepadState ;
197- this . _gamepadState = [ ] ;
198-
199- let connectedGamepads = 0 ;
200- for ( let i = 0 ; i < gamepads . length ; i ++ ) {
201- const gamepad = gamepads [ i ] ;
202- this . _gamepadState [ i ] = [ ] ;
203- if ( gamepad !== null ) {
204- connectedGamepads ++ ;
205- for ( let j = 0 ; j < gamepad . buttons . length ; j ++ ) {
206- const button = gamepad . buttons [ j ] ;
207- this . _gamepadState [ i ] [ j ] = button . pressed ;
208- }
209- }
166+ private _onGamepadButtonDown ( buttonId : number ) {
167+ if ( ! this . props . interactive ) {
168+ return ;
210169 }
211-
212- for ( let i = 0 ; i < this . _gamepadState . length ; i ++ ) {
213- for ( let j = 0 ; j < this . _gamepadState [ i ] . length ; j ++ ) {
214- const oldValue = oldState [ i ] && oldState [ i ] [ j ] ;
215- if ( this . _gamepadState [ i ] [ j ] && ! oldValue ) {
216- this . _onGamepadPress ( j ) ;
217- }
218- if ( ! this . _gamepadState [ i ] [ j ] && oldValue ) {
219- console . log ( "release" , i , j ) ;
170+ switch ( buttonId ) {
171+ case 0 : // A
172+ case 4 : /* Left Shoulder Button */ {
173+ const button = document . activeElement as HTMLButtonElement ;
174+ if ( ! button ) {
175+ return ;
220176 }
177+ this . simulateClick ( button ) ;
178+ break ;
221179 }
222- }
223-
224- // Continue ticking if there are still gamepads connected, else stop ticking
225- // to avoid unnecessary CPU usage.
226- if ( connectedGamepads > 0 && ! this . _gamepadStopTicking ) {
227- requestAnimationFrame ( this . _gamepadTick ) ;
228- } else {
229- this . _gamepadIsTicking = false ;
230- }
231- }
232-
233- private _onGamepadPress ( id : number ) {
234- switch ( id ) {
235- case 0 : {
236- // A
180+ case 2 : // X
181+ case 5 : /* Right Shoulder Button */ {
237182 const button = document . activeElement as HTMLButtonElement ;
238183 if ( ! button ) {
239184 return ;
240185 }
241- this . simulateClick ( button ) ;
186+ this . simulateClick ( button , true ) ;
242187 break ;
243188 }
244189 case 1 : // B
245190 this . _toggleDangerMode ( ) ;
246191 break ;
192+ }
193+ }
194+
195+ @bind
196+ private _onGamepadButtonPress ( buttonId : number ) {
197+ if ( ! this . props . interactive ) {
198+ return ;
199+ }
200+ switch ( buttonId ) {
247201 case 15 : // Right
248- this . moveFocusByKey ( new KeyboardEvent ( "press ") , 1 , 0 ) ;
202+ this . moveFocusByKey ( new Event ( " ") , 1 , 0 ) ;
249203 break ;
250204 case 14 : // Left
251- this . moveFocusByKey ( new KeyboardEvent ( "press ") , - 1 , 0 ) ;
205+ this . moveFocusByKey ( new Event ( " ") , - 1 , 0 ) ;
252206 break ;
253207 case 12 : // Up
254- this . moveFocusByKey ( new KeyboardEvent ( "press ") , 0 , - 1 ) ;
208+ this . moveFocusByKey ( new Event ( " ") , 0 , - 1 ) ;
255209 break ;
256210 case 13 : // Down
257- this . moveFocusByKey ( new KeyboardEvent ( "press" ) , 0 , 1 ) ;
258- break ;
259- default :
211+ this . moveFocusByKey ( new Event ( "" ) , 0 , 1 ) ;
260212 break ;
261213 }
262214 }
@@ -346,7 +298,7 @@ export default class Board extends Component<Props, State> {
346298 button . classList . contains ( "focus-visible" ) ||
347299 isFeaturePhone ||
348300 cellFocusMode ||
349- this . _gamepadIsTicking ;
301+ gamepad . isGamepadConnected ;
350302
351303 if ( ! showFocusStyle ) {
352304 this . props . renderer . setFocus ( - 1 , - 1 ) ;
@@ -419,7 +371,7 @@ export default class Board extends Component<Props, State> {
419371 }
420372
421373 @bind
422- private moveFocusByKey ( event : KeyboardEvent , h : number , v : number ) {
374+ private moveFocusByKey ( event : Event , h : number , v : number ) {
423375 event . stopPropagation ( ) ;
424376 event . preventDefault ( ) ;
425377
0 commit comments