changeset 2:3bb2fada1594

Do not capture keys when not playing. Esc key now interrupts the game in any state.
author Mikhail Kryshen <mikhail@kryshen.net>
date Thu, 18 Feb 2016 01:08:13 +0300
parents bffc42c9b7c5
children 9ee21f993e05
files src/Serpentron.st
diffstat 1 files changed, 45 insertions(+), 29 deletions(-) [+]
line diff
     1.1 --- a/src/Serpentron.st	Wed Feb 17 23:58:34 2016 +0300
     1.2 +++ b/src/Serpentron.st	Thu Feb 18 01:08:13 2016 +0300
     1.3 @@ -1,7 +1,7 @@
     1.4  Smalltalk createPackage: 'Serpentron'!
     1.5  (Smalltalk packageAt: 'Serpentron') imports: {'silk/Silk'}!
     1.6  Object subclass: #Serpentron
     1.7 -	instanceVariableNames: 'field skin players playerColors controllerPrototypes score pointsToWin'
     1.8 +	instanceVariableNames: 'field skin players playerColors controllerPrototypes score pointsToWin timeoutId startScreenVisible'
     1.9  	package: 'Serpentron'!
    1.10  !Serpentron commentStamp!
    1.11  The game UI.!
    1.12 @@ -11,13 +11,14 @@
    1.13  initialize
    1.14  	super initialize.
    1.15  	playerColors := #('#377eb8' '#e41a1c' '#4daf4a' '#ff7f00' '#984ea3' '#b3ad78').
    1.16 +	startScreenVisible := true.
    1.17  	skin := TronSkin new.
    1.18  	field := TronField new
    1.19  		skin: skin;
    1.20  		onEndGame: [ self handleEndGame ].
    1.21  	self initializePlayers; initializeControllers.
    1.22  	(Silk fromElement: document)
    1.23 -		on: #keydown bind: [ :event | field keyDown: event ].
    1.24 +		on: #keydown bind: [ :event | self keyDown: event ].
    1.25  ! !
    1.26  
    1.27  !Serpentron methodsFor: 'private'!
    1.28 @@ -33,16 +34,13 @@
    1.29  	(score anySatisfy: [ :each | each >= pointsToWin ])
    1.30  		ifFalse: [
    1.31  			self status: (self winnerDOM: color) << ' won the round.'.
    1.32 -			^ self nextRound ].
    1.33 +			timeoutId := window
    1.34 +				setTimeout: [ self nextRound ]
    1.35 +				after: 2000.
    1.36 +			^ self ].
    1.37  	self status: self scoreDOM.
    1.38 -	window
    1.39 -		setTimeout: [ 
    1.40 -			self startScreenVisible: true.
    1.41 -			self hideMessage.
    1.42 -			self status: self scoreDOM << '. ' << (self winnerDOM: color) << ' won!!' ]
    1.43 -		after: 2000.	
    1.44 -	window
    1.45 -		setTimeout: [ self showMessage: (self winnerDOM: color) << ' won!!' ]
    1.46 +	timeoutId := window 
    1.47 +		setTimeout: [ self showGameWinner: color ]
    1.48  		after: 1000.
    1.49  !
    1.50  
    1.51 @@ -108,12 +106,22 @@
    1.52  	}.
    1.53  !
    1.54  
    1.55 +keyDown: event
    1.56 +	startScreenVisible ifTrue: [ ^ self ].
    1.57 +	"Handle Esc key."
    1.58 +	(event keyCode = 27)
    1.59 +		ifTrue: [
    1.60 +			event preventDefault.
    1.61 +			field stopTimer.
    1.62 +			window clearTimeout: timeoutId.
    1.63 +			self hideMessage; startScreenVisible: true.
    1.64 +			^ self ].
    1.65 +	field keyDown: event.
    1.66 +!
    1.67 +
    1.68  nextRound
    1.69 -	window
    1.70 -		setTimeout: [
    1.71 -			self status: self scoreDOM.
    1.72 -			field start: field players ]
    1.73 -		after: 2000.
    1.74 +	self status: self scoreDOM.
    1.75 +	field start: field players.
    1.76  !
    1.77  
    1.78  randomizePlayerColors
    1.79 @@ -236,6 +244,17 @@
    1.80  	^ message.
    1.81  !
    1.82  
    1.83 +showGameWinner: color
    1.84 +	self showMessage: (self winnerDOM: color) << ' won!!'.
    1.85 +	timeoutId := window
    1.86 +		setTimeout: [ 
    1.87 +			self 
    1.88 +				startScreenVisible: true;
    1.89 +				hideMessage;
    1.90 +				status: self scoreDOM << '. ' << (self winnerDOM: color) << ' won!!' ]
    1.91 +		after: 1000.
    1.92 +!
    1.93 +
    1.94  showMessage: anObject
    1.95  	((Silk at: '#message') resetContents << anObject)
    1.96  		element className: 'visible'.
    1.97 @@ -250,8 +269,9 @@
    1.98  !
    1.99  
   1.100  startScreenVisible: aBoolean
   1.101 +	startScreenVisible := aBoolean.
   1.102  	(Silk at: '#start-screen') element 
   1.103 -		className: (aBoolean ifTrue: [ 'visible' ] ifFalse: [ 'hidden' ])
   1.104 +		className: (aBoolean ifTrue: [ 'visible' ] ifFalse: [ 'hidden' ]).
   1.105  !
   1.106  
   1.107  status: anObject
   1.108 @@ -732,12 +752,6 @@
   1.109  !TronField methodsFor: 'event handling'!
   1.110  
   1.111  keyDown: event
   1.112 -	"Handle Esc key."
   1.113 -	livePlayers isEmpty not & (event keyCode = 27)
   1.114 -		ifTrue: [
   1.115 -			event preventDefault.
   1.116 -			self endGame.
   1.117 -			^ self ].
   1.118  	"Check all players rather than livePlayers 
   1.119  	so that preventDefault is called for all used keys."
   1.120  	(players anySatisfy: [ :each | each keyDown: event keyCode ])
   1.121 @@ -809,12 +823,6 @@
   1.122  	timerId := window setInterval: [ self update ] every: 75.
   1.123  !
   1.124  
   1.125 -stopTimer
   1.126 -	timerId ifNotNil: [
   1.127 -		window clearInterval: timerId.
   1.128 -		timerId := nil ]
   1.129 -!
   1.130 -
   1.131  update
   1.132  	| lpCopy |
   1.133  	lpCopy := livePlayers copy.
   1.134 @@ -885,6 +893,14 @@
   1.135  	self startIfAllReady.
   1.136  ! !
   1.137  
   1.138 +!TronField methodsFor: 'stopping'!
   1.139 +
   1.140 +stopTimer
   1.141 +	timerId ifNotNil: [
   1.142 +		window clearInterval: timerId.
   1.143 +		timerId := nil ]
   1.144 +! !
   1.145 +
   1.146  Object subclass: #TronPlayer
   1.147  	instanceVariableNames: 'enabled color name controller segments location moved direction nextDirection onColorChange onEnabledChange onControllerChange'
   1.148  	package: 'Serpentron'!