|
Taller
|
| >> Taller >> Curso De Iniciación A DIV by Wakroo >> Cap. 4, Parámetros. |
Teníamos el problema de la gran cantidad de enemigos que aparecen. Para solucionar eso vamos a hacer que aparezcan en un orden aleatorio. Y para eso usaremos la sentencia rand(); . Esta sentencia devuelve un número entero aleatorio entre los dos valores que hay que poner entre paréntesis. Así si ponemos rand(1,100); nos devolverá un número entero entre 1 y 100, ambos inclusive. Podríamos modificar el MAIN de manera que salgan los enemigos aleatoriamente, algo así:
......PROGRAM juego_de_ejemplo;
......BEGIN
..........set_mode(m640x480);
..........load_fpg("c:\cursoDIV\curso1.fpg");
..........personaje();
..........laberinto();
..........LOOP
..............IF
(rand(1,100))= =1)
..................enemigo();
..............END
..............FRAME;
..........END
......END
Esto haría que en uno de cada 100 frames se creara un enemigo. Como es aleatorio a veces serán más, a veces serán menos. Pero es muy poco probable que aparezcan todos a la vez, o incluso más de uno o dos cada segundo. Naturalmente, podéis poner la frecuencia que os de la gana. Ej.: IF (rand(1,100))<11),... Pero este método tiene un fallo: todos los enemigos serán iguales. Es cierto que podemos poner algunos rand(); en el proceso para cambiarlos, pero tendremos poco control sobre esos cambios. Por ejemplo, si en algún momento queremos que se cree un enemigo en algún lugar en concreto tendremos que crear otro proceso nuevo con su propio código. Esto no resulta práctico. Para solucionar esto existen los parámetros.
Los parámetros son datos que le pasamos al proceso en el momento de crearlo. Estos datos se ponen entre los paréntesis al final de la llamada al proceso. Luego, ya en el proceso en si, debemos poner que es cada dato. Me explico. En la llamada al proceso personaje(); podríamos haber puesto personaje(320,240,1); , y en el proceso PROCESS personaje(x,y,graph); , omitiendo en el código los valores x, y, graph. De esta manera le hemos asignado esos valores a esas varibles (el primer valor a la primera variable, el segundo valor a la segunda variable,...). Por lo tanto, podríamos hacer lo mismo con el proceso enemigo(); , siendo así muy fácil modificarlos y hacer que un enemigo salga, por ejemplo, en un lugar concreto de la pantalla.
Os estaréis preguntando cómo se hace el proceso enemigo(); . Está bien. Suponiendo que los enemigos aparecen en la parte superior de la pantalla y que van hacia abajo, podría ser algo parecido a esto:
......PROCESS enemigo(x,y,graph,size,incrementox,incrementoy);
......PRIVATE
..........incrementox; incrementoy;
......BEGIN
..........LOOP
..............x+=incrementox;
..............y+=incrementoy;
..............IF
(x<-20) BREAK; END
..............IF
(x>660) BREAK; END
..............IF
(y>500) BREAK; END
..............FRAME;
..........END
......END
La llamada al proceso sería:
......enemigo(rand(1,640),-50,3,rand(50,150),rand(-10,10),rand(5,10));
De esta manera se crearía un enemigo en una x al azar, 50 puntos por encima de la pantalla, con gráfico 3 (habrá que crear un gráfico y meterlo en el fpg), con tamaño aleatorio (size es una variable local predefinida que indica el tamaño del gráfico con respecto al original, en porcentaje) y cantidad de movimiento horizontal y vertical aleatorio. Con estos datos es muy poco probable que se creen dos enemigos exactamente iguales. También hay una nueva sentencia en el programa: BREAK;. Esta sentencia lo que hace es forzar al programa a romper el bucle y continuar justo después del END del mismo. En este caso, como después del END del LOOP viene el END del BEGIN (es decir, no hay más órdenes que ejecutar) el proceso finaliza. Los tres IF son por motivos prácticos. Que el gráfico salga de la pantalla no quiere decir que el proceso haya terminado Por lo tanto seguirá ejecutándo el código para siempre (o hasta que se termine el programa, una de dos). Puede no parecer importante, pero hasta el ordenador más rápido terminará por dar saltos cuando tenga que manejar demasiados procesos, puesto que se están creando nuevos procesos continuamente. Por eso al proceso se le obliga a terminar cuando sale de la pantalla.
Y os preguntaréis: ¿qué diferencia hay entre ponerlos así o ponerlos en el código? Pues imaginaos que queréis en algún momento queréis crear un enemigo con estas características: x=100; , size=150; , incrementox=10; , incrementoy=5; y un gráfico diferente (graph=4, aunque habría que meter ese gráfico también). Con los parámetros sería suficiente con llamar a ese proceso pasándole esos datos. Sin los parámetros habría que crear un nuevo proceso con su propio código (en el que la mayoría sería idéntico al del otro proceso, pero bueno). Como veis los parámetros son muy útiles.
Pero por ahora los enemigos son inofensivos. Lo único que hacen es aparecer en la pantalla, darse un paseíto y desaparecer. Ahora los vamos a convertir en un peligro para el personaje. En el proceso personaje(); , después de la comprobación de colisión con el laberinto, habría que hacer una comprobación de colisión con los enemigos. El código sería el siguiente:
..............IF (collision(TYPE enemigo)) BREAK; END
De esta manera, al chocar con algún enemigo, la sentencia BREAK; rompería el bucle LOOP, continuando después del END y terminando el proceso (puesto que después se llega al END del proceso). Y por lo tanto el juego habrá terminado, puesto que el jugador no tiene nada más que controlar.
Pero vamos a jugar con ese BREAK;. Si después del END del LOOP escribimos alguna sentencia ésta se cumplirá una vez que el personaje choque con algún enemigo. Por lo tanto podríamos poner algún comando que, por ejemplo, finalize el programa. Esa sentencia es exit(); , y necesita dos parámetros: un texto entre comillas que aparecerá al salir del programa y el código de retorno (es para programas externos; poned 0 y no le hagáis más caso por ahora). Entonces una sentencia correcta podría ser exit("Gracias por jugar",0); .
Aunque la verdad es que eso de salir así, sin más, queda un poco soso. Pues vamos a hacer que el personaje explote. Para eso crearemos otro proceso, llamado explosion(); . La llamada la haremos después del LOOP del proceso personaje, quitando la sentencia exit(); . Como queremos que la explosión suceda en el lugar donde está el personaje habrá que pasarle como parámetros la x y la y del personaje. ¿Y cómo se hace eso? Muy sencillo. Si la llamada la hacemos desde un proceso y ponemos como parámetro alguna de las variables del proceso le pasará el valor actual de esa variable. Por lo que si hacemos la llamada así: explosion(x,y); le estamos pasando el valor actual de x e y del proceso personaje(); , y por lo tanto la explosión tendrá lugar en el sitio donde está el personaje. Justo lo que queríamos. El código queda así:
......PROCESS explosion(x,y);
......BEGIN
..........FROM graph=11
TO 20; FRAME; END
......END
Así de simple. Me explico. Le hemos pasado las coordenadas x e y del proceso personaje como parámetros, por lo tanto no hay que especificarlas. Luego hemos usado una sentencia nueva: FROM. Esta sentencia modifica una variable desde el primer valor que se le da hasta el último incrementándola uno por uno y ejecutando las sentencias del interior. En esta caso después de cada incremento ejecuta la sentencia FRAME; , por lo que se visualiza el cambio de gráfico en pantalla y parece que está explotando. Los gráficos de la explosión los crearemos con el generador de explosiones y las meteremos en el fpg. Yo he usado diez imágenes, y he empezado a contar desde el 11 por una cuestión de orden, nada más (y repito, el orden y la limpieza son fundamentales). Las imágenes podrían ser algo parecido a esto:
También se podría aplicar el mismo método a las colisiones con el laberinto (cambiar los nuevos valores de x e y por una sentencia BREAK;). Después del FROM se podría poner un exit(); para terminar el juego, o una nueva llamada al proceso personaje para volver a empezar (aunque de esta manera los enemigos no desaparecerían).
Pero nuestro protagonista tiene un pequeño problema: no tiene ninguna forma de defenderse. Eso lo vamos a arreglar en seguida.