The drawOn:
method is modified to draw two distinct,
unconnected lines:
LineExampleMorph>>drawOn: aCanvas aCanvas strokeWidth: 20 color: Color green do: [ aCanvas moveTo: 0 @ 0; lineTo: 200 @ 200; moveTo: 200 @ 0; lineTo: 0 @ 200 ]
Learn how the #moveTo:
message moves the pencil to a given
position with the pen up, then the #lineTo:
asks the pencil to
draw from that previous position to this new position.
We create a RectangleExampleMorph
, subclass of
PlacedMorph
:
PlacedMorph subclass: #RectangleExampleMorph instanceVariableNames: 'fillColor' classVariableNames: '' poolDictionaries: '' category: 'Morphic-Learning'
Then its necessary methods to initialize and to draw the morph:
initialize super initialize . fillColor := Color random alpha: 0.5 drawOn: aCanvas aCanvas strokeWidth: 1 color: Color blue fillColor: fillColor do: [ aCanvas moveTo: 0 @ 0; lineTo: 200 @ 0; lineTo: 200 @ 100; lineTo: 0 @ 100; lineTo: 0 @ 0]
Among the clock parts (submorphs) we only need to modify the drawing
of the ClockSecondHandMorph
class. The disc is surrounded with a
thin red line and filled in yellow.
ClockSecondHandMorph>>drawOn: aCanvas aCanvas strokeWidth: 1.5 color: Color red do: [ aCanvas moveTo: 0 @ 0; lineTo: 85 @ 0 ]. aCanvas ellipseCenter: 0 @ -70 radius: 3 @ 3 borderWidth: 1 borderColor: Color red fillColor: Color yellow
On top of the drawOn:
method, we also want the acceleration
variable to take a range of values between 0 and 50.
SpaceShip>>push "Init an accelaration boost" fuel isZero ifTrue: [^ self]. fuel := fuel - 1. acceleration := (acceleration + 10) min: 50
SpaceShip>>unpush "Stop the accelaration boost" acceleration := acceleration - 5 max: 0
drawOn: canvas ../.. "Draw gas exhaust" acceleration ifNotZero: [ canvas line: c to: 0 acceleration width: 1 + acceleration / 8 color: Color orange].
The width of the torpedo is 4 pixels and its height 8 pixels:
Torpedo>>morphExtent ^ `4 @ 8`
The Torpedo
’s drawOn:
method is very similar to the
one in SpaceShip
class:
Torpedo>>drawOn: canvas | a b c | a := 0 @ -4. b := -2 @ 4. c := 2 @ 4. canvas line: a to: b width: 2 color: color. canvas line: c to: b width: 2 color: color. canvas line: a to: c width: 2 color: color.
We use a local variable because we use two times the vertices, one to draw the ship and a second time to draw the gas exhaust.
SpaceShip>>drawOn: canvas | vertices | vertices := self class vertices. canvas line: vertices first to: vertices second width: 2 color: color. canvas line: vertices second to: vertices third width: 2 color: color. canvas line: vertices third to: vertices fourth width: 2 color: color. canvas line: vertices fourth to: vertices first width: 2 color: color. "Draw gas exhaust" acceleration ifNotZero: [ canvas line: vertices third to: 0@35 width: 1 color: Color gray]
You need both to iterate each vertex of the vertices
array
and access the subsequent vertex by index. The arithmetic reminder
operation #\\
is needed to keep the index in the boundary of the
collection.
When size
is 4 (Space ship diagram), the argument
(i \\ size + 1)
takes alternatively the following values:
Mobile>>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]
Just replace each morph position distance approach with the intersection detection between the morphs’ display bounds:
SpaceWar>>collisionsShips (ships first collides: ships second) ../.. SpaceWar>>collisionsShipsTorpedoes ships do: [:aShip | torpedoes do: [:aTorpedo | (aShip collides: aTorpedo) ../.. SpaceWar>>collisionsTorpedoesStar torpedoes do: [:each | (each collides: centralStar) ../..