martes, 16 de octubre de 2012

UCBLogo: videojuego captura la bola



Este videojuego es muy sencillo, pero nos sirve para analizar la posibilidad de interaccionar con el ratón. El juego en sí es bastante simple: tenemos que pinchar sobre una pelota que rebota de manera indefinida en un campo. Si con el ratón pinchamos sobre la pelota acertamos y así lo anotará el contador de aciertos. Si no acertamos, aumentará el contador de fallos. En cualquier caso la velocidad de la pelota aumentará cada vez más.

Una captura de la pantalla del juego es la siguiente:



Consideraciones nuevas de este videojuego:

1.- Conseguir que la bola no aparezca siempre en el mismo sitio: si ejecutamos varias veces el juego, la posición inicial de la pelota no siempre será la misma. Para ello usaremos la sencilla instrucción random para generar números aleatorios. Así en el procedimiento comienzo encontramos:

make "x random 100
make "y random 100

siendo x, y las coordenadas cartesianas de la bola. De esta forma toman un valor aleatorio entre 0 y 99.

2.- Dibujar líneas gruesas: el campo en esta ocasión lo hemos dibujado grueso. Para ello en el procedimiento campo encontramos:

setpensize 8

pues la instrucción setpensize nos permite cambiar el grosor de las líneas. Por ello cuando volvamos a dibujar la bola deberemos volver a poner setpensize 1, que el tamaño de línea por defecto.

3.- Usando el color para borrar objetos: en los ejemplos anteriores usábamos penpaint (para poner en modo de dibujar a la tortuga) y penerase (para poner en modo de borrar a la tortuga). En este caso vamos a usar otro procedimiento que consiste en pintar de color blanco cuando queremos que algo se vea, y pintarlo de color negro (para que quede confundido con el fondo) cuando queremos que algo no se vea. Esta es la forma de trabajo de los procedimientos bola (que pintará la bola) y borrarbola (que borra la bola porque lo que hace es pintar una bola del color del fondo, es decir, negra).

4.- Cómo saber si pinchamos sobre la bola: en primer lugar debemos conocer cuáles son las coordenadas del ratón. Para ello tendremos en cuenta lo siguiente: mousepos es un comando que nos da la posición del ratón dentro de la ventana como un par ordenado de números siendo el primero la coordenada cartesiana “x” y el segundo la coordenada cartesiana “y”. Pues bien, como no deja de ser una lista ordenada (o vector), podemos combinarlo con los comandos first (que nos da el primer miembro de una lista) y last (que nos da el último miembro de una lista) de esta manera:

make "rx first mousepos
make "ry last mousepos

de tal forma que la variable rx contendrá la coordenada “x” del ratón y la variable ry contendrá la coordenada “y” del ratón.

Para saber si pinchamos sobre la bola no tenemos más que calcular la distancia entre el centro de la bola (variables x, y) y el punto del pinchazo del ratón (variables rx, ry). Para ello usamos el siguiente código:

make "distancia sqrt (((x-rx)*(x-rx))+((y-ry)*(y-ry)))

sqrt es la raíz cuadrada, por lo que la ecuación es directamente la ecuación de distancia entre dos puntos en coordenadas cartesianas.

Si la distancia es menor que el radio hemos acertado (y llamamos al procedimiento bien), y si no, hemos fallado (y llamamos al procedimiento mal):

if distancia < 8 [bien]
if distancia > 8 [mal]

5.- Leyendo los botones del ratón: UCBLogo implementa comandos para la lectura del ratón. Hay uno que usaremos que es button. Button devuelve el valor 0 si no hay ningún botón pulsado, 1 si está pulsado el botón izquierdo, 2 si está pulsado el botón derecho y 3 si está pulsado el botón central. Así, la instrucción:

if button = 1 [raton]

lo que hace es ejecutar el procedimiento raton si está pulsado el botón izquierdo el ratón. Algo bastante fácil que, sin embargo, no haremos exactamente así por una cuestión: la variable button sigue siendo 1 mientras no se suelta el ratón, por lo que estaría leyendo de continuo y, en vez de calcular aciertos y fallos con un solo clic del ratón, lo haría varias veces, algo que no queremos. Para evitar esta situación nos inventamos una variable que la llamaremos puedopulsar y que podrá tomar los valores 0 y 1. Así:

dentro del procedimiento juego (el principal):
if button = 0 [make "puedopulsar 1]
if puedopulsar = 1 [if button = 1 [raton]]

dentro del procedimiento raton:
make "puedopulsar 0

es decir, la variable puedopulsar valdrá por defecto 1 (no hay botón del ratón pulsado). En el momento en el que se pulsa un botón valdrá 0, pues el procedimiento raton fuerza a que una vez se entra valga cero, pero como vale 0, ya no se puede ejecutar otra vez este procedimiento raton hasta que la variable puedopulsar valga otra vez 1 (que será en el momento en el que la variable button sea 0, es decir, no haya ningún botón del ratón pulsado).

Con todo esto ya tenemos todas las claves para entender el código del videojuego. Sólo un par de apuntes: se empieza por el procedimiento inicio y el procedimiento principal es juego.


Código del juego

;
; Videojuego de captura de la bola
; raultecnologia
; para empezar el juego teclea el procedimiento inicio
;
; Con este sencillo videojuego aprendemos las posibilidades de interaccion
; con el raton
;

;
; el procedimiento inicio establece la pantalla de presentacion
;
to inicio
clearscreen
hideturtle
setpencolor 7
penup
setxy -200 140
label "Videojuego_captura_la_bola
setxy -200 110
label "Usa_el_boton_izquierdo_del_raton_para_capturar_la_bola
setxy -200 80
label "En_cada_intento_la_bola_aumenta_su_velocidad
setxy -200 0
setpencolor 3
label "Pulsa_cualquier_tecla_para_empezar
make "tecla rc
comienzo
end

;
; el procedimiento comienzo establece las condiciones iniciales
;
to comienzo
clearscreen
campo
hideturtle
make "x random 100
make "y random 100
make "aciertos 0
make "fallos 0
make "puedopulsar 1
;  puedopulsar es una variable que nos impide volver a pinchar con el raton hasta que no
;  soltemos el boton
setxy -200 180
label "Aciertos
setxy -100 180
label aciertos
setxy 50 180
label "Fallos
setxy 130 180
label fallos
make "xvel 1
make "yvel 1
make "velocidad 50
;       velocidad es una variable hecha para perder tiempo
bola
juego
end

;
; el procedimiento campo sencillamente dibuja el campo de juego
;
to campo
setpencolor 7
penup
setxy -250 -140
setpensize 8
pendown
fd 300
rt 90
fd 500
rt 90
fd 300
rt 90
fd 500
rt 90
penup
end

;
; el procedimiento bola dibuja la bola
;
to bola
penup
setxy x y
pendown
setpensize 1
setpencolor 7
arc 360 8
end

;
; el procedimiento borrabola borra la bola anterior
;
to borrabola
penup
setxy x y
setpencolor 0
setpensize 1
pendown
arc 360 8
end

;
; el procedimiento juego controla las condiciones del juego
;
to juego
if button = 0 [make "puedopulsar 1]
pierdetiempo
make "rx first mousepos
make "ry last mousepos
if puedopulsar = 1 [if button = 1 [raton]]
borrabola
if x = 236 [make "xvel -xvel]
if x = -236 [make "xvel -xvel]
if y = 146 [make "yvel -yvel]
if y = -125 [make "yvel -yvel]
make "x x+xvel
make "y y+yvel
bola
juego
end

;
; el procedimiento pierdetiempo es el encargado de variar la velocidad del tiempo
; dibujando el campo un monton de veces
;
to pierdetiempo
for [i 1 velocidad 1] [campo]
end

;
; el procedimiento raton establece que ocurre cuando se pulsa el boton izquierdo
;
to raton
make "puedopulsar 0
make "distancia sqrt (((x-rx)*(x-rx))+((y-ry)*(y-ry)))
if distancia < 8 [bien]
if distancia > 8 [mal]
end

;
; el procedimiento bien establece que ocurre cuando capturamos la bola
;
to bien
make "aciertos aciertos+1
make "velocidad velocidad/1.25
penup
setpencolor 7
setxy -100 180
label aciertos
end

;
; el procedimiento mal establece que ocurre cuando fallamos en la captura de la bola
;
to mal
make "fallos fallos+1
make "velocidad velocidad/1.25
penup
setpencolor 7
setxy 130 180
label fallos
end