jueves, 18 de octubre de 2012

UCBLogo: videojuego del muro



El videojuego del muro (o Arkanoid) es un videojuego clásico en el que aparece un muro hecho con ladrillos que debemos derribar usando una bola a la que golpeamos con una raqueta (o una nave).



Consideraciones sobre el juego:

1.- vamos a manejar la raqueta con el ratón. Para ello la raqueta se moverá de izquierda a derecha siguiendo el ratón y hacemos que no pueda sobrepasar las paredes del terreno de juego:

make "rx first mousepos   ;variable rx vale la posicion en x del raton
if [rx < -176] [make "rx -176]
if [rx > 275] [make "rx 275]
penup
setxy rx ry  ;ry es una constante
nave ;el procedimiento nave dibuja la raqueta

2.- para saber qué ladrillos quedan usaremos de nuevo una tabla (10 columnas y 4 filas) en la que guardaremos con el valor de 1 si hay ladrillo y con el valor de 0 si no lo hay. Además, de vez en cuando habrá que repintar los ladrillos.  Para ello:

to dibujaladrillos
for [i 1 10 1] [for [j 1 4 1] [make "dentro mditem (list :i :j) :tabla ~
 if [dentro = 1] [penup setxy i*41-200 j*21+50 ladrillo]]]
end

3.- Programando si hay o no hay colisión: de nuevo (como en casos anteriores en que manejamos tablas para los cálculos del programa) vamos a manejar dos sistemas de coordenadas (bolax y bolay para las coordenadas de la bola en la parte gráfica y varx y vary para las coordenadas en la tabla):

make "varx int((bolax+200)/41)  ;int devuelve la parte entera
make "vary int((bolay-50)/21)

definiremos también una variable llamada posible, que conceptualmente vale para mirar si hay posibilidad (posible valdrá 1) o no (vale 0) de que haya colisión con los ladrillos (está claro que si la bola está alejada del muro no puede chocar con los ladrillos, sólo miraremos si está cerca o no del muro).

if [varx <= 10][if [varx>=1][if [vary<=4][if [vary>=1][make "posible 1]]]]

Si está en una posición en la que hay muro, la bola chocará si hay ladrillo, si no, no lo hace.

if [posible=1] [make "dentro mditem (list :varx :vary) :tabla ~
 if [dentro = 1] [make "vely -vely penup setxy varx*41-200 vary*21+50 borraladrillo ~
mdsetitem (list :varx :vary) :tabla 0 dibujaladrillos make "aciertos aciertos+1]]


Código del juego

;
; Videojuego Arkanoid
; Raultecnologia
; el programa esta en LOGO para usar directamente en el UCBLogo
; para empezar el juego teclea el procedimiento inicio
;



clearscreen
hideturtle

to campo
penup
setxy -200 -120
pendown
setpencolor 7
setpensize 8
fd 300
rt 90
fd 500
rt 90
fd 300
rt 90
fd 500
rt 90
setpensize 1
end


to ladrillo
setpencolor 4
pendown
fd 20
rt 90
fd 40
rt 90
fd 20
rt 90
fd 40
rt 90
end

to borraladrillo
setpencolor 0
pendown
fd 20
rt 90
fd 40
rt 90
fd 20
rt 90
fd 40
rt 90
end

to nave
setpencolor 5
penup
lt 90
fd 20
rt 90
pendown
fd 10
rt 90
fd 40
rt 90
fd 10
rt 90
fd 40
rt 90
penup
rt 90
fd 20
lt 90
end

to borranave
setpencolor 0
penup
lt 90
fd 20
rt 90
pendown
fd 10
rt 90
fd 40
rt 90
fd 10
rt 90
fd 40
rt 90
penup
rt 90
fd 20
lt 90
end

to bola
pendown
setpencolor 7
arc 360 8
end

to borrabola
pendown
setpencolor 0
arc 360 8
end


to tele


make "posible 0
if [bolay <= -80][colision]
if [bolay >= 170][make "vely -vely]
if [bolax <= -190][make "velx -velx]
if [bolax >= 290][make "velx -velx]

make "varx int((bolax+200)/41)
make "vary int((bolay-50)/21)
if [varx <= 10][if [varx>=1][if [vary<=4][if [vary>=1][make "posible 1]]]]

if [posible=1] [make "dentro mditem (list :varx :vary) :tabla ~
 if [dentro = 1] [make "vely -vely penup setxy varx*41-200 vary*21+50 borraladrillo ~
mdsetitem (list :varx :vary) :tabla 0 dibujaladrillos make "aciertos aciertos+1]]
if [aciertos=40][fin]
penup
setxy bolax bolay
borrabola
penup
setxy rx ry
borranave
make "bolax bolax+velx
make "bolay bolay+vely
make "rx first mousepos
if [rx < -176] [make "rx -176]
if [rx > 275] [make "rx 275]
penup
setxy rx ry
nave
penup
setxy bolax bolay
bola
for [i 0 perdertiempo] [penup setxy 0 0 campo]
tele
end


to inicio
clearscreen
setpensize 1
penup
setxy -200 140
setpencolor 4
label "|Videojuego Arkanoid|
setxy -200 110
setpencolor 7
label "|Maneja la nave con el ratón|
setxy -200 80
setpencolor 6
label "|Acierta a los ladrillos|
setxy -200 -20
label "|Pulsa cualquier tecla para empezar|
wait 120
make "tecla rc
clearscreen
setpencolor 7

make "size_x 11
make "size_y 5
make "tabla (mdarray (list :size_x :size_y) 1)

for [i 1 10 1] [for [j 1 4 1] [mdsetitem (list :i :j) :tabla 1]]

dibujaladrillos

make "perdertiempo 30

make "puntos 0

make "ry -100
make "rx 0
make "bolax 0
make "bolay 0
make "velx 1
make "vely -1
make "aciertos 0


window
tele
end

to dibujaladrillos
for [i 1 10 1] [for [j 1 4 1] [make "dentro mditem (list :i :j) :tabla ~
 if [dentro = 1] [penup setxy i*41-200 j*21+50 ladrillo]]]
end






to fin
penup


setpencolor 4
penup
setxy -40 -5
label "!!!fin!!!
setxy -100 -100
label "|pulsa cualquier tecla para empezar|
wait 120
make "tecla rc
inicio
end


to colision
make "distancia ((rx-bolax))
if [distancia<0][make "distancia -distancia]
if [velx>0][make "signovelx 1]
if [velx<0][make "signovelx -1]

if [distancia<25][make "vely -vely make "velx signovelx+distancia/10]
if [distancia >=25][destruyenave]
end

to destruyenave
penup
setxy rx ry
borranave
pendown
setpencolor 2
lt 45
arc 90 20
arc 90 40
rt 180
arc 90 20
arc 90 40
rt 180
rt 45
penup
setxy -40 -5
label "!!!Perdiste!!!
setxy -100 -100
label "|pulsa cualquier tecla para empezar|
wait 120
make "tecla rc
inicio
end