-
Notifications
You must be signed in to change notification settings - Fork 0
/
Snake-Game.st
213 lines (184 loc) · 6.55 KB
/
Snake-Game.st
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
AlignmentMorph subclass: #SnakeGameMorph
instanceVariableNames: 'board scoreMorph highMorph'
classVariableNames: 'High'
poolDictionaries: ''
category: 'Snake-Game'!
!SnakeGameMorph commentStamp: 'JS 5/21/2022 12:30' prior: 0!
Jaime Silvela (jaime.silvela@gmail.com)
This is the toplevel class for the snake game. All it does is package the SnakeMorph board, which does the real stuff, in an alignment morph with a score & controls panel.
Game controls:
* Left arrow -- Turn counterclockwise
* Right arrow -- Turn clockwise!
!SnakeGameMorph methodsFor: 'as yet unclassified' stamp: 'JSM 9/9/2001 16:01'!
initialize
super initialize.
High = nil
ifTrue: [ High _ 0].
self color: Color darkGray;
borderWidth: 0;
hResizing: #shrinkWrap;
vResizing: #shrinkWrap;
listDirection: #topToBottom;
addMorphBack: (board _ SnakeMorph new);
addMorphBack: self makeControlPanel.
self startStepping! !
!SnakeGameMorph methodsFor: 'as yet unclassified' stamp: 'JSM 9/9/2001 16:12'!
makeControlPanel
^ AlignmentMorph newRow color: Color lightGray;
borderWidth: 0;
layoutInset: 3;
vResizing: #shrinkWrap;
wrapCentering: #center;
addMorphBack: AlignmentMorph newVariableTransparentSpacer;
addMorphBack: (SimpleButtonMorph new label: 'New game';
color: Color lightGray;
borderColor: #raised;
borderWidth: 2;
actionSelector: #newGame;
target: board);
addMorphBack: AlignmentMorph newVariableTransparentSpacer;
addMorphBack: (SimpleButtonMorph new label: 'Quit';
color: Color lightGray;
borderColor: #raised;
borderWidth: 2;
actionSelector: #delete;
target: self);
addMorphBack: AlignmentMorph newVariableTransparentSpacer;
addMorphBack: (StringMorph contents: 'Score ');
addMorphBack: (scoreMorph _ LedMorph new digits: 4;
extent: 40 @ 15);
addMorphBack: AlignmentMorph newVariableTransparentSpacer;
addMorphBack: (StringMorph contents: 'High ');
addMorphBack: (highMorph _ LedMorph new digits: 4;
extent: 40 @ 15);
addMorphBack: AlignmentMorph newVariableTransparentSpacer! !
!SnakeGameMorph methodsFor: 'as yet unclassified' stamp: 'JSM 9/9/2001 15:59'!
step
scoreMorph value: board length.
board length > High
ifTrue: [High _ board length].
highMorph value: High! !
Morph subclass: #SnakeMorph
instanceVariableNames: 'speed cells grow'
classVariableNames: ''
poolDictionaries: ''
category: 'Snake-Game'!
!SnakeMorph commentStamp: 'JS 5/21/2022 12:32' prior: 0!
Jaime Silvela (jaime.silvela@gmail.com)
21 September 2001
This class contains the game proper.
The lion's share of this class is in the step method.
The class contains three instance variables:
* speed: a vector that keeps track of orientation
* cells: an ordered collection of square Morphs.
* grow: the number of cells to be added to the snake.
`step` will move the first cell in the "cells" variable according to speed,
then it will move through "cells", making each one take the position of
the previous one. It also checks for collision of the snake with the walls
or with itself.
Finally, if the snake eats one of the numbers that pop up on the screen,
it updates "grow" accordingly.!
!SnakeMorph methodsFor: 'as yet unclassified' stamp: 'JSM 8/25/2001 23:42'!
growCells: aNumber
grow _ aNumber! !
!SnakeMorph methodsFor: 'as yet unclassified' stamp: 'JSM 8/25/2001 22:36'!
handlesKeyboard: evt
^ true! !
!SnakeMorph methodsFor: 'as yet unclassified' stamp: 'JSM 8/25/2001 22:37'!
handlesMouseOver: evt
^ true! !
!SnakeMorph methodsFor: 'as yet unclassified' stamp: 'JSM 9/1/2001 14:51'!
initialize
super initialize.
self extent: 300 @ 300.
self newGame! !
!SnakeMorph methodsFor: 'as yet unclassified' stamp: 'JSM 8/25/2001 23:26'!
keyStroke: evt
| keyValue |
keyValue _ evt keyCharacter asciiValue.
keyValue = 28 ifTrue: [ self turnRight ].
keyValue = 29 ifTrue: [ self turnLeft]! !
!SnakeMorph methodsFor: 'as yet unclassified' stamp: 'JSM 9/1/2001 15:34'!
length
^ cells size + grow! !
!SnakeMorph methodsFor: 'as yet unclassified' stamp: 'JSM 8/25/2001 22:38'!
mouseEnter: evt
evt hand newKeyboardFocus: self! !
!SnakeMorph methodsFor: 'as yet unclassified' stamp: 'JSM 9/1/2001 15:41'!
newGame
| cell |
self
submorphsDo: [:m | m delete].
cell _ Morph new extent: 10 @ 10;
color: Color yellow.
cell position: self position." + self extent / 2."
self addMorph: cell.
cells _ OrderedCollection new.
cells addLast: cell.
speed _ 1 @ 0.
self growCells: 6.
self numberAtRandom.
self startStepping! !
!SnakeMorph methodsFor: 'as yet unclassified' stamp: 'JSM 9/1/2001 14:40'!
numberAtRandom
| value x y string stringMorph temp |
value _ 9 atRandom.
string _ String fromString: value printString.
stringMorph _ StringMorph contents: string.
stringMorph extent: 10 @ 10;
color: Color yellow.
temp _ self extent - stringMorph extent.
x _ temp x atRandom - 1.
y _ temp y atRandom - 1.
stringMorph position: self position + (x @ y).
self
submorphsDo: [:m | (m bounds intersects: stringMorph bounds)
ifTrue: [self numberAtRandom.
^ self]].
self addMorph: stringMorph! !
!SnakeMorph methodsFor: 'as yet unclassified' stamp: 'JSM 9/21/2001 20:48'!
step
| head lastPosition tmp cell |
head _ cells first.
lastPosition _ head position.
(self bounds
containsRect: (head bounds translateBy: speed * head width))
ifFalse: [self stopStepping.
^ self].
"Move the first cell according to the speed vector, then have the second cell take the place of the first one, the third one take the place of the second one etc."
head position: head position + (speed * head width).
2
to: cells size
do: [:index |
tmp _ (cells at: index) position.
(cells at: index)
position: lastPosition.
lastPosition _ tmp].
"If the snake needs to grow, make a new cell and append to the snake"
grow > 0
ifTrue: [cell _ Morph new.
cell extent: 10 @ 10.
cell color: Color yellow.
cell position: lastPosition.
cells addLast: cell.
self addMorph: cell.
grow _ grow - 1].
2
to: cells size
do: [:index | (cells at: index) position = head position
ifTrue: [self stopStepping]].
self
submorphsDo: [:m | ((m isMemberOf: StringMorph)
and: [head bounds intersects: m bounds])
ifTrue: [self growCells: m contents asInteger.
m delete.
self numberAtRandom]]! !
!SnakeMorph methodsFor: 'as yet unclassified' stamp: 'JSM 8/25/2001 23:48'!
stepTime
^ 100! !
!SnakeMorph methodsFor: 'as yet unclassified' stamp: 'JSM 8/25/2001 22:40'!
turnLeft
speed _ speed y negated @ speed x! !
!SnakeMorph methodsFor: 'as yet unclassified' stamp: 'JSM 8/25/2001 22:40'!
turnRight
speed _ speed y @ speed x negated! !