El método drawOn: se modifica para dibujar dos líneas
distintas, sin conexión:
LineExampleMorph>>drawOn: aCanvas
aCanvas strokeWidth: 20 color: Color green do: [
aCanvas
moveTo: 0 @ 0;
lineTo: 200 @ 200;
moveTo: 200 @ 0;
lineTo: 0 @ 200 ]
Fíjate cómo el mensaje #moveTo: mueve el lápiz a una posición
determinada con el lápiz levantado y, a continuación, el mensaje
#lineTo: le pide al lápiz que dibuje desde la posición anterior
hasta la nueva posición.
Creamos un RectangleExampleMorph, subclase de
PlacedMorph:
PlacedMorph subclass: #RectangleExampleMorph instanceVariableNames: 'fillColor' classVariableNames: '' poolDictionaries: '' category: 'Morphic-Learning'
A continuación, los métodos necesarios para inicializar y dibujar el 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]
Figura D.2: Varios morphs rectangulares
Entre las piezas del reloj (submorphs), sólo necesitamos modificar el
dibujo de la clase ClockSecondHandMorph. El disco está rodeado
por una fina línea roja y relleno de amarillo.
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
Además del método drawOn:, también queremos que la variable de
aceleración tome un rango de valores entre 0 y 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].
El ancho del torpedo es de 4 píxeles y su altura de 8 píxeles:
Torpedo>>morphExtent ^ `4 @ 8`
El método drawOn: de Torpedo es muy similar al de la
clase SpaceShip:
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.
Utilizamos una variable local porque usamos dos veces los vértices, una para dibujar la nave y otra para dibujar el escape de gas.
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]
Necesitas tanto iterar cada vértice de la matriz vertices
como acceder al vértice siguiente por índice. La operación aritmética de
resto #\\ es necesaria para mantener el índice dentro de los
límites de la colección.
Cuando size es 4 (diagrama de la nave espacial), el
argumento (i \\ size + 1) toma alternativamente los
siguientes valores:
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]
Simplemente sustituye cada aproximación de distancia de posición de morph por la detección de intersección entre los límites de visualización de los morphs:
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)
../..