Obviamente, nuestro juego Spacewar! gestiona eventos. En primer lugar, queremos controlar las naves con el teclado. En segundo lugar, queremos que el juego se pause cuando el cursor del ratón salga del juego y se reanude cuando vuelva a entrar.
En nuestro diseño, un morph único, la instancia SpaceWar,
modela el juego. Por lo tanto, queremos que esta instancia gestione los
eventos descritos anteriormente.
Queremos capturar los eventos cuando el cursor del ratón se mueve sobre
nuestro morph SpaceWar.
¿Qué método debería devolver verdadero para que el juego reciba una notificación con mensajes específicos cuando el cursor del ratón entra o sale? ¿En qué clase deberíamos implementar este método?
Ejercicio 8.1: Recibir notificaciones del evento de desplazamiento del ratón
Una vez que dejamos claro que queremos que el juego reciba eventos de desplazamiento del ratón, debemos configurar el comportamiento en consecuencia con métodos específicos.
Cada vez que el cursor del ratón entra en el juego, queremos:
HandMorph, un objeto de evento (véase la jerarquía de clases
de eventos al principio de este capítulo). Se pregunta a un objeto de
evento por su manejo con el mensaje #hand. En definitiva,
queremos que el foco del teclado se dirija hacia nuestro juego cuando
entra el ratón:
event hand newKeyboardFocus: self
self startStepping
¿Qué mensaje se envía al juego para notificar que el cursor del ratón entra en el área de juego? ¿Cómo se debe escribir el método correspondiente?
Ejercicio 8.2: Gestionar el evento de entrada del ratón
También queremos que se nos informe cuando el cursor del ratón abandone
nuestro morph SpaceWar. Gracias al trabajo realizado en
Ejercicio 8.1, ya hemos informado a Cuis-Smalltalk de que queremos que
se nos notifique el movimiento del ratón sobre el juego. Sin embargo,
necesitamos programar el comportamiento cuando el cursor del ratón
abandona el juego:
event hand releaseKeyboardFocus: self
self stopStepping
¿Qué mensaje se envía al juego para notificar que el cursor del ratón ha salido del área de juego? ¿Cómo debemos sobrescribir el método?
Ejercicio 8.3: Manejar el evento de salida del ratón
En la interfaz gráfica de usuario, a menudo se utiliza un efecto visual para informar al usuario de que el foco del teclado ha cambiado. En Spacewar! cambiamos el fondo del juego en función del estado del foco del teclado.
En la Figura 8.1, a la izquierda el foco del teclado está en el juego; a la derecha el foco del teclado no está en el juego, está en pausa y podemos ver a través.
Figura 8.1: Efecto Spacewar! dependiendo del foco del teclado
En el marco Morph, el mensaje #keyboardFocusChange: se envía al
morph que pierde o gana el foco del teclado, su parámetro es un
booleano. Por lo tanto, implementamos el comportamiento Figura 8.1
en el método correspondiente keyboardFocusChange de
SpaceWar:
SpaceWar>>keyboardFocusChange: gotFocus
gotFocus
ifTrue: [color := self defaultColor]
ifFalse: [color := self defaultColor alpha: 0.5].
self redrawNeeded
Ejemplo 8.1: Efecto del foco del teclado en Spacewar!
Para controlar las naves espaciales, utilizamos el teclado. Por lo tanto, queremos que el juego sea notificado de los eventos del teclado.
Averigua qué método debería devolver verdadero para que el juego reciba la notificación del evento del teclado.
Ejercicio 8.4: Recibir notificaciones de eventos del teclado
Podemos decidir que se nos notifique el evento de pulsación o liberación
de tecla, así como el evento de pulsación y liberación de tecla
(pulso de tecla). Siempre que nuestro morph SpaceWar
responda verdadero al mensaje #handlesKeyboard, recibirá los
mensajes #keyUp:, #keyDown: y #keyStroke:. Por defecto,
los métodos coincidentes de la clase Morph no hacen nada.
El argumento de estos mensajes es un objeto KeyboardEvent al
que, entre otras cosas, se le puede preguntar el #keyCharacter
de la tecla pulsada o comprobar algunas teclas especiales, como las
flechas del teclado. La nave del primer jugador, –la verde–, se controla
con las flechas del teclado cuando se pulsan:
SpaceWar>>keyStroke: event event isArrowUp ifTrue: [^ ships first push]. event isArrowRight ifTrue: [^ ships first right]. event isArrowLeft ifTrue: [^ ships first left]. event isArrowDown ifTrue: [^ ships first fireTorpedo]. ...
Ejemplo 8.2: Teclas para controlar la nave del primer jugador
Para controlar la nave del segundo jugador, utilizamos otra disposición clásica en los juegos controlados con teclado QWERTY: WASD.27.
Añade el código adicional al Ejemplo 8.2 para controlar la nave del segundo jugador con las teclas WASD. Como recordatorio, en Smalltalk el código de carácter para q se puede escribir como
$q.
Ejercicio 8.5: Teclas para controlar la nave del segundo jugador