Ejercicio resuelto del tema 2
Dibujar un rectángulo en el borde de la pantalla (por ejemplo, con el rectángulo relleno, carácter 143, o con el rectángulo de trama gruesa, carácter 206) y algún obstáculo en puntos intermedios de la pantalla (por ejemplo, con el rectángulo tramado fino, carácter 207). En el centro de la pantalla habrá un personaje (carácter 248). Cada vez que se pulse una flecha en el teclado, el personaje deberá moverse en la dirección indicada. Cuando el personaje se mueva cambiará de forma (por ejemplo, al carácter 250). Terminará cuando el personaje choque con un obstáculo o con el borde, o si se pulsa la tecla ESC.
La apariencia podría ser como ésta:
Y cuando el personaje choque, se podría imitar una explosión con el carácter 238, por ejemplo:
Esta es mi propuesta de solución. En ella he buscado sobre todo legibilidad, y por eso he declarado al principio del programa las variables que representarán a los distintos caracteres que aparecen en el juego. Como no sabemos todavía generar números al azar, los obstáculos están en posiciones prefijadas:
10 ' Ejemplo del tema 2
20 ' Preparo los caracteres
30 borde$=CHR$(206)
40 obstac$=CHR$(207)
50 izqda$=CHR$(242)
60 dcha$=CHR$(243)
70 arriba$=CHR$(240)
80 abajo$=CHR$(241)
90 perso1$=CHR$(248)
100 perso2$=CHR$(250)
110 explo$=CHR$(238)
120 ' Preparo los colores
130 INK 0, 0: ' Color 0: Negro
140 INK 1, 2: ' Color 1: Azul claro
150 INK 2, 11: ' Color 2: Azul cielo
160 INK 3, 20: ' Color 3: Cyan claro
170 PAPER 0: PEN 1: 'Azul cl sobre negro
180 BORDER 0
190 MODE 1
200 ' Dibujo linea superior e inf.
210 FOR i = 1 TO 40
220 LOCATE i,1: PRINT borde$;
230 LOCATE i,24: PRINT borde$;
240 NEXT i
250 ' Dibujo linea dcha e izqda
260 FOR i = 2 TO 23
270 LOCATE 1,i: PRINT borde$;
280 LOCATE 40,i: PRINT borde$;
290 NEXT i
300 ' Pongo unos cuantos obstaculos
310 PEN 2
320 LOCATE 10,10: PRINT obstac$
330 LOCATE 30,18: PRINT obstac$
340 PEN 3: PAPER 1
350 LOCATE 2,6: PRINT obstac$
360 LOCATE 10,8: PRINT obstac$
370 PEN 3: PAPER 2
380 LOCATE 15,12: PRINT obstac$
390 LOCATE 22,20: PRINT obstac$
400 PEN 3: PAPER 0
410 ' Parte repetitiva: personaje
420 ' Primero: valores iniciales
430 x = 10: y= 12
440 persona$=perso1$
450 LOCATE x,y: PRINT persona$
460 ' Ahora espero tecla
470 tecla$ = INKEY$: IF tecla$="" THEN GOTO 470
480 ' Borro personaje
490 LOCATE x,y: PRINT " "
500 ' Calculo nueva posicion
510 IF tecla$=izqda$ THEN x = x - 1
520 IF tecla$=dcha$ THEN x = x + 1
530 IF tecla$=arriba$ THEN y = y - 1
540 IF tecla$=abajo$ THEN y = y + 1
550 ' Compruebo si choca
560 LOCATE x,y
570 IF (COPYCHR$(#0) = obstac$) OR (COPYCHR$(#0) = borde$) THEN GOTO 630
580 ' Si no choca, alterno personaje
590 IF persona$=perso1$ THEN persona$=perso2$ ELSE persona$=perso1$
600 ' Y repito
610 GOTO 450
620 ' Si ha chocado, se acabo
630 PRINT explo$
640 END
Por supuesto, no es la única solución posible. Esta es la alternativa que propone DadMaN, que utiliza variables enteras (no necesitamos decimales en ninguno de los cálculos) y que sí coloca los obstáculos al azar. Son dos posibilidades que aún no hemos tratado en el curso, y que se verán en los temas 6 y 3, respectivamente. Las órdenes ON BREAK y FRAME tampoco las hemos tratado aún. En cuanto a los detalles de funcionamiento de su versión, él emplea obstáculos de distintos tipos, por lo que para detectar colisiones compara si la posición a la que se va a mover no es un espacio (<> 32):
10 ON BREAK GOSUB 360
20 MODE 1:BORDER 0:INK 0,0:INK 1,2:INK 2,20
30 'DIBUJADO MARCO Y OBSTACULOS
40 PEN 1
50 FOR x%=1 TO 40
60 LOCATE x%,1:PRINT CHR$(200)
70 LOCATE x%,25:PRINT CHR$(200);
80 NEXT
90 FOR y%=2 TO 24
100 LOCATE 1,y%:PRINT CHR$(200)
110 LOCATE 40,y%:PRINT CHR$(200)
120 NEXT
130 PEN 2
140 FOR n%=1 TO 6
150 IF n%=1 THEN p%=127
160 IF n%=2 THEN p%=202
170 IF n%=3 THEN p%=203
180 IF n%=4 THEN p%=206
190 IF n%=5 THEN p%=207
200 IF n%=6 THEN p%=143
210 x%=INT(RND(TIME)*38)+2
220 y%=INT(RND(TIME)*23)+2
230 LOCATE x%,y%:PRINT CHR$(p%)
240 NEXT
250 x%=20:y%=12:LOCATE x%,y%
260 IF ASC(COPYCHR$(#0))<>32 THEN x%=x%+1:y%=y%+1:LOCATE x%,y%:GOTO 260
270 xt%=x%:yt%=y%:p%=248:GOSUB 410
280 'BUCLE PRINCIPAL
290 IF INKEY(1)=0 THEN x%=x%+1:p%=251:GOSUB 370:GOSUB 410
300 IF INKEY(8)=0 THEN x%=x%-1:p%=250:GOSUB 370:GOSUB 410
310 IF INKEY(0)=0 THEN y%=y%-1:p%=249:GOSUB 370:GOSUB 410
320 IF INKEY(2)=0 THEN y%=y%+1:p%=249:GOSUB 370:GOSUB 410
330 IF p%<>248 THEN p%=248:FRAME:GOSUB 410
340 GOTO 290
350 p%=238:GOSUB 410:CLEAR INPUT:FOR n%=0 TO 2000:NEXT:CLS:PEN 1:GOTO 50
360 CLS:PEN 1:INK 1,24:END
370 'DETECTA COLISION
380 LOCATE x%,y%:IF ASC(COPYCHR$(#0))<>32 THEN GOTO 350
390 RETURN
400 'ACTUALIZA PERSONAJE
410 LOCATE xt%,yt%:PRINT CHR$(32)
420 LOCATE x%,y%:PRINT CHR$(p%)
430 xt%=x%:yt%=y%
440 RETURN
450 'x% e y% son las coordenadas del prota
460 'xt% e yt% son las coordenadas de borrado del fondo
470 'p% indica el "sprite" a utilizar en la animacion