-
Notifications
You must be signed in to change notification settings - Fork 9
/
Spacewar!.pck.st
452 lines (377 loc) · 13.4 KB
/
Spacewar!.pck.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
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
'From Cuis6.0 [latest update: #6154] on 27 January 2024 at 5:42:28 pm'!
'Description SpaceWar!! game code'!
!provides: 'Spacewar!!' 1 97!
SystemOrganization addCategory: #'Spacewar!!'!
!classDefinition: #Mobile category: #'Spacewar!!'!
PlacedMorph subclass: #Mobile
instanceVariableNames: 'acceleration color velocity'
classVariableNames: ''
poolDictionaries: ''
category: 'Spacewar!!'!
!classDefinition: 'Mobile class' category: #'Spacewar!!'!
Mobile class
instanceVariableNames: 'vertices'!
!classDefinition: #SpaceShip category: #'Spacewar!!'!
Mobile subclass: #SpaceShip
instanceVariableNames: 'name fuel torpedoes'
classVariableNames: ''
poolDictionaries: ''
category: 'Spacewar!!'!
!classDefinition: 'SpaceShip class' category: #'Spacewar!!'!
SpaceShip class
instanceVariableNames: ''!
!classDefinition: #Torpedo category: #'Spacewar!!'!
Mobile subclass: #Torpedo
instanceVariableNames: 'lifeSpan'
classVariableNames: ''
poolDictionaries: ''
category: 'Spacewar!!'!
!classDefinition: 'Torpedo class' category: #'Spacewar!!'!
Torpedo class
instanceVariableNames: ''!
!classDefinition: #SpaceWar category: #'Spacewar!!'!
PlacedMorph subclass: #SpaceWar
instanceVariableNames: 'color ships torpedoes centralStar'
classVariableNames: ''
poolDictionaries: ''
category: 'Spacewar!!'!
!classDefinition: 'SpaceWar class' category: #'Spacewar!!'!
SpaceWar class
instanceVariableNames: ''!
!classDefinition: #CentralStar category: #'Spacewar!!'!
Morph subclass: #CentralStar
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'Spacewar!!'!
!classDefinition: 'CentralStar class' category: #'Spacewar!!'!
CentralStar class
instanceVariableNames: ''!
!Mobile commentStamp: 'hlsf 10/25/2020 09:16:19' prior: 0!
An abstract mobile with a mass and inner acceleration, subject to a gravity pull.!
!SpaceShip commentStamp: 'hlsf 10/25/2020 09:19:28' prior: 0!
A ship comes with a torpedo inventory and a fuel tank.
Player controls its heading and acceleration, and he can fire torpedo.!
!Torpedo commentStamp: 'hlsf 10/25/2020 09:18:37' prior: 0!
A torpedo comes with a lifespan and an automatic acceleration handling!
!SpaceWar commentStamp: 'hlsf 11/1/2020 10:06:46' prior: 0!
I am the view and controler of the game.
My submorphs are the elements of the game.
To start the game execute: "SpaceWar new openInWorld"
Ship Controls
Green: left, right, up down arrows
Red: a, d, w, s keys!
!CentralStar commentStamp: '<historical>' prior: 0!
I am the central start of the game generating a gravity field.!
!Mobile methodsFor: 'accessing' stamp: 'hlsf 10/1/2020 08:34:04'!
color: aColor
"Set the receiver's color. "
color = aColor ifFalse: [
color _ aColor.
self redrawNeeded ]! !
!Mobile methodsFor: 'accessing' stamp: 'hlsf 2/14/2022 13:48:54'!
direction
"I am an unit vector representing the noze direction of the mobile"
^Point rho: 1 theta: self heading! !
!Mobile methodsFor: 'accessing' stamp: 'hlsf 2/14/2022 13:48:44'!
heading
^ location radians - Float halfPi! !
!Mobile methodsFor: 'accessing' stamp: 'hlsf 2/14/2022 13:53:10'!
heading: aHeading
self rotation: aHeading + Float halfPi! !
!Mobile methodsFor: 'accessing' stamp: 'hlsf 10/1/2020 08:34:23'!
mass
^ 1! !
!Mobile methodsFor: 'accessing' stamp: 'hlsf 1/27/2024 15:47:36'!
starMass
^ owner starMass! !
!Mobile methodsFor: 'accessing' stamp: 'hlsf 8/23/2021 11:55:02'!
velocity: aVector
velocity _ aVector ! !
!Mobile methodsFor: 'computing' stamp: 'hlsf 1/27/2024 15:47:23'!
gravity
"Compute the gravity acceleration vector"
| position |
position := self morphPosition.
^ [-10 * self mass * self starMass / (position r raisedTo: 3) * position]
on: Error do: [0 @ 0]! !
!Mobile methodsFor: 'computing' stamp: 'hlsf 8/23/2021 11:52:21'!
update: t
"Update the mobile position and velocity "
| ai ag newVelocity |
"acceleration vectors"
ai _ acceleration * self direction.
ag _ self gravity.
newVelocity _ (ai + ag) * t + velocity.
self morphPosition: (0.5 * (ai + ag) * t squared)
+ (velocity * t)
+ self morphPosition.
velocity _ newVelocity.
"Are we out of screen?
If so we move the mobile to the other corner and slow it down by a factor of 2"
(self isInOuterSpace and: [self isGoingOuterSpace]) ifTrue: [
velocity _ velocity / 2.
self morphPosition: self morphPosition negated]! !
!Mobile methodsFor: 'initialization' stamp: 'hlsf 10/1/2020 08:37:29'!
initialize
super initialize.
color _ Color gray.
velocity _ 0 @ 0.
acceleration _ 0.! !
!Mobile methodsFor: 'testing' stamp: 'hlsf 10/8/2020 22:21:33'!
isGoingOuterSpace
"is the mobile going crazy in direction of the outer space?"
^ (self morphPosition dotProduct: velocity) > 0 ! !
!Mobile methodsFor: 'testing' stamp: 'jmv 10/28/2021 15:04:22'!
isInOuterSpace
"Is the mobile located in the outer space? (outside of the game play area)"
^(owner localBounds containsPoint: self morphPosition) not! !
!Mobile methodsFor: 'drawing' stamp: 'hlsf 8/23/2021 11:50:43'!
drawOn: canvas polygon: vertices
| size |
size _ vertices size.
vertices withIndexDo: [: aPoint :i |
canvas
line: aPoint
to: ( vertices at: (i \\ size + 1) )
width: 2
color: color] ! !
!Mobile methodsFor: 'geometry' stamp: 'jmv 10/28/2021 14:53:01'!
localBounds
^Rectangle encompassing: self class vertices! !
!Mobile class methodsFor: 'as yet unclassified' stamp: 'hlsf 12/19/2020 23:21:09'!
vertices
^ vertices ! !
!SpaceShip methodsFor: 'control' stamp: 'hlsf 2/14/2022 13:53:33'!
fireTorpedo
"Fire a torpedo in the direction of the ship heading with a combined velocity"
| torpedo |
torpedoes isZero ifTrue: [ ^ self].
torpedoes _ torpedoes - 1.
torpedo _ Torpedo new.
torpedo
morphPosition: self morphPosition + self nose;
heading: self heading;
velocity: velocity;
color: color muchLighter .
owner addTorpedo: torpedo.! !
!SpaceShip methodsFor: 'control' stamp: 'hlsf 2/14/2022 14:09:51'!
left
"Rotate the ship to its left"
self heading: self heading - 0.1! !
!SpaceShip methodsFor: 'control' stamp: 'hlsf 1/27/2024 15:39:46'!
push
"Init an accelaration boost"
fuel isZero ifTrue: [^ self].
fuel := fuel - 1.
acceleration := (acceleration + 10) min: 50! !
!SpaceShip methodsFor: 'control' stamp: 'hlsf 2/14/2022 14:10:08'!
right
"Rotate the ship to its right"
self heading: self heading + 0.1! !
!SpaceShip methodsFor: 'control' stamp: 'hlsf 1/27/2024 15:39:56'!
unpush
"Stop the accelaration boost"
acceleration := acceleration - 5 max: 0! !
!SpaceShip methodsFor: 'drawing' stamp: 'hlsf 1/27/2024 17:42:24'!
drawOn: canvas
| vertices |
vertices := self class vertices.
super drawOn: canvas polygon: vertices.
"Draw gas exhaust"
acceleration ifNotZero: [
canvas line: vertices third to: 0@acceleration width: 1 + acceleration / 8 color: Color orange].! !
!SpaceShip methodsFor: 'drawing' stamp: 'hlsf 12/15/2020 21:16:09'!
nose
^ self direction * 40! !
!SpaceShip methodsFor: 'initialization' stamp: 'hlsf 2/14/2022 13:50:54'!
initialize
super initialize.
self resupply! !
!SpaceShip methodsFor: 'initialization' stamp: 'hlsf 2/16/2023 11:54:41'!
resupply
fuel _ 500.
torpedoes _ 10! !
!SpaceShip class methodsFor: 'as yet unclassified' stamp: 'hlsf 12/19/2020 23:21:16'!
initialize
"SpaceShip initialize"
vertices _ {0@-15 . -10@15. 0@10. 10@15}! !
!Torpedo methodsFor: 'computing' stamp: 'hlsf 2/16/2023 11:56:14'!
update: t
"Update the torpedo position"
super update: t.
"orientate the torpedo in its velocity direction, nicer effect while inaccurate"
self heading: (velocity y arcTan: velocity x).
lifeSpan _ lifeSpan - 1.
lifeSpan isZero ifTrue: [owner destroyTorpedo: self].
acceleration > 0 ifTrue: [acceleration _ acceleration - 500].! !
!Torpedo methodsFor: 'drawing' stamp: 'hlsf 12/20/2020 13:19:16'!
drawOn: canvas
self drawOn: canvas polygon: self class vertices! !
!Torpedo methodsFor: 'initialization' stamp: 'hlsf 12/15/2020 21:12:29'!
initialize
super initialize.
lifeSpan _ 500.
acceleration _ 3000! !
!Torpedo class methodsFor: 'as yet unclassified' stamp: 'hlsf 12/19/2020 23:21:22'!
initialize
"Torpedo initialize"
vertices _ {0@-4 . -2@4 . 2@4}! !
!SpaceWar methodsFor: 'accessing' stamp: 'hlsf 9/16/2020 16:41:40'!
starMass
^ centralStar mass! !
!SpaceWar methodsFor: 'actions' stamp: 'hlsf 9/21/2020 20:56:33'!
addTorpedo: aTorpedo
torpedoes add: aTorpedo.
self addMorph: aTorpedo ! !
!SpaceWar methodsFor: 'actions' stamp: 'hlsf 9/21/2020 21:10:33'!
destroyTorpedo: aTorpedo
aTorpedo delete.
torpedoes remove: aTorpedo ! !
!SpaceWar methodsFor: 'actions' stamp: 'hlsf 10/1/2020 17:29:37'!
teleport: aShip
"Teleport a ship at a random location"
| area randomCoordinate |
aShip resupply.
area _ self localBounds insetBy: 20.
randomCoordinate _ [(area left to: area right) atRandom].
aShip
velocity: 0@0;
morphPosition: randomCoordinate value @ randomCoordinate value! !
!SpaceWar methodsFor: 'collisions' stamp: 'hlsf 10/1/2020 15:04:27'!
collisions
self collisionsShipsStar.
self collisionsTorpedoesStar.
self collisionsShipsTorpedoes.
self collisionsShips ! !
!SpaceWar methodsFor: 'collisions' stamp: 'hlsf 2/16/2023 12:53:43'!
collisionsShips
(ships first collides: ships second) ifTrue: [
ships do: [:each |
each flashWith: Color red.
self teleport: each] ]! !
!SpaceWar methodsFor: 'collisions' stamp: 'hlsf 2/16/2023 12:28:09'!
collisionsShipsStar
ships do: [ :aShip |
(aShip collides: centralStar) ifTrue: [
aShip flashWith: Color red.
self teleport: aShip ]]! !
!SpaceWar methodsFor: 'collisions' stamp: 'hlsf 2/16/2023 12:30:08'!
collisionsShipsTorpedoes
ships do: [:aShip |
torpedoes do: [:aTorpedo |
(aShip collides: aTorpedo) ifTrue: [
aShip flashWith: Color red.
aTorpedo flashWith: Color orange.
self destroyTorpedo: aTorpedo.
self teleport: aShip]]
]! !
!SpaceWar methodsFor: 'collisions' stamp: 'hlsf 2/16/2023 12:30:19'!
collisionsTorpedoesStar
torpedoes do: [:each |
(each collides: centralStar) ifTrue: [
each flashWith: Color orange.
self destroyTorpedo: each]]! !
!SpaceWar methodsFor: 'drawing' stamp: 'hlsf 10/1/2020 15:45:54'!
drawOn: aCanvas
aCanvas
fillRectangle: self localBounds
color: color! !
!SpaceWar methodsFor: 'event handling testing' stamp: 'hlsf 11/1/2020 10:03:57'!
handlesKeyboard
^ true! !
!SpaceWar methodsFor: 'event handling testing' stamp: 'hlsf 11/1/2020 10:04:18'!
handlesMouseOver: event
^ true! !
!SpaceWar methodsFor: 'events' stamp: 'hlsf 2/22/2023 21:31:48'!
keyStroke: event
| key |
event isArrowUp ifTrue: [^ ships first push].
event isArrowRight ifTrue: [^ ships first right].
event isArrowLeft ifTrue: [^ ships first left].
event isArrowDown ifTrue: [^ ships first fireTorpedo].
key _ event keyCharacter.
key = $w ifTrue: [^ ships second push].
key =$d ifTrue: [^ ships second right].
key = $a ifTrue: [^ ships second left].
key = $s ifTrue: [^ ships second fireTorpedo]! !
!SpaceWar methodsFor: 'events' stamp: 'hlsf 9/11/2020 10:07:17'!
mouseEnter: evt
evt hand newKeyboardFocus: self.
self startStepping! !
!SpaceWar methodsFor: 'events' stamp: 'hlsf 9/11/2020 10:07:22'!
mouseLeave: evt
evt hand releaseKeyboardFocus: self.
self stopStepping! !
!SpaceWar methodsFor: 'focus handling' stamp: 'hlsf 9/10/2020 16:04:35'!
keyboardFocusChange: gotFocus
gotFocus
ifTrue: [color _ self defaultColor ]
ifFalse: [color _ self defaultColor alpha: 0.5].
self redrawNeeded.! !
!SpaceWar methodsFor: 'geometry testing' stamp: 'hlsf 12/11/2020 13:00:49'!
clipsSubmorphs
^ true! !
!SpaceWar methodsFor: 'initialization' stamp: 'hlsf 9/10/2020 15:21:22'!
defaultColor
^ `Color black`! !
!SpaceWar methodsFor: 'initialization' stamp: 'hlsf 11/1/2020 10:04:39'!
initialize
"We want to capture keyboard and mouse events,
start the game loop(step) and initialize the actors."
super initialize.
color _ self defaultColor.
self startSteppingStepTime: self stepTime.
self initializeActors.! !
!SpaceWar methodsFor: 'initialization' stamp: 'hlsf 8/23/2021 11:53:32'!
initializeActors
centralStar _ CentralStar new.
self addMorph: centralStar.
centralStar morphPosition: 0@0.
torpedoes _ OrderedCollection new.
ships _ Array with: SpaceShip new with: SpaceShip new.
self addAllMorphs: ships.
ships first
morphPosition: 200 @ -200;
color: Color green darker.
ships second
morphPosition: -200 @ 200;
color: Color red darker.! !
!SpaceWar methodsFor: 'stepping' stamp: 'hlsf 12/16/2020 19:45:30'!
stepAt: millisecondSinceLast
ships do: [:each | each update: millisecondSinceLast / 1000 ].
ships do: [:each | each unpush ].
torpedoes do: [:each | each update: millisecondSinceLast / 1000 ].
self collisions.
self redrawNeeded
! !
!SpaceWar methodsFor: 'stepping' stamp: 'hlsf 9/11/2020 13:19:07'!
stepTime
"millisecond"
^ 20! !
!SpaceWar methodsFor: 'stepping' stamp: 'hlsf 9/10/2020 18:03:59'!
wantsSteps
^ true! !
!SpaceWar methodsFor: 'geometry' stamp: 'hlsf 2/16/2023 11:38:27'!
localBounds
^ -300 @ -300 extent: 600@600! !
!CentralStar methodsFor: 'accessing' stamp: 'hlsf 10/8/2020 22:20:17'!
mass
^ 8000! !
!CentralStar methodsFor: 'accessing' stamp: 'hlsf 12/15/2020 21:04:13'!
morphExtent
^ `30 @ 30`! !
!CentralStar methodsFor: 'drawing' stamp: 'KenD 2/15/2023 15:40:04'!
drawOn: canvas
| radius |
radius _ self morphExtent // 2.
canvas ellipseCenter: 0 @ 0
radius: (radius x + (2 atRandom - 1)) @ (radius y + (2 atRandom - 1))
borderWidth: 3
borderColor: Color orange
fillColor: Color yellow ! !
!CentralStar methodsFor: 'geometry' stamp: 'jmv 10/28/2021 14:55:55'!
localBounds
^Rectangle center: 0@0 extent: self morphExtent! !
SpaceShip initialize!
Torpedo initialize!