In the raw source code below, understand the “_” character as “:=”.
'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!