Los fundamentos de Morph

Ejercicio 7.1

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.

Ejercicio 7.2

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]
E-exeRectMorph

Figura D.2: Varios morphs rectangulares

Ejercicio 7.3

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

Ejercicio 7.4

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].

Ejercicio 7.5

El ancho del torpedo es de 4 píxeles y su altura de 8 píxeles:

Torpedo>>morphExtent
   ^ `4 @ 8`

Ejercicio 7.6

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.

Ejercicio 7.7

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]

Ejercicio 7.8

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]

Ejercicio 7.9

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)
   ../..