Taller
>> Taller >> Curso De Iniciación A DIV by Wakroo >> Cap. 2, Procesos.

Los procesos son "partes" de código. Cada proceso, en principio, tiene su propio código y lo ejecuta y se relaciona con los demás procesos según sus órdenes. En este momento del curso podéis relacionar proceso con gráfico en pantalla, aunque se pueden hacer también procesos que no aparecen en pantalla (no asignándole un gráfico).

Cada proceso debe empezar con la palabra reservada PROCESS, seguida de las varibles privadas, si las hay (ver el capítulo anterior), y luego un BEGIN, las sentencias y un END. Ese proceso puede ejecutar todas las órdenes que se quieran, llamar a otros procesos, "matarlos" (hacer que dejen de ejecutar su código), congelarlos (hacer que paren de ejecutar su código, pero sin "matarlo"), dormirlos (congelarlo haciendo que su gráfico no aparezca en pantalla), interactuar con ellos y cualquier otra cosa que se nos ocurra. Se puede hacer más de una llamada a un proceso concreto (ej.: cada vez que el protagonista tenga que disparar se llama al mismo proceso, ahorrando muchísimas líneas de código). Y pueden existir infindad de procesos a la vez, cada uno ejecutando su código único (lo que puede ralentizar el ordenador si hay demasiados, pero nada es perfecto :( ).

Empecemos a analizar un proceso, y lo haremos con un ejemplo. Así también podréis hacer vuestro primer juego, y mato dos pájaros de un tiro :) . Por cierto, tened en cuenta que el MAIN (el BEGIN ... END del principio) no es más que el primer proceso del programa, y por lo tanto se trata como cualquier otro proceso (aunque es un poco más difícil de manejar, puesto que no tiene nombre; normalmente se usa para cargar lo que vayamos a usar y llamar a otro proceso que toma el control, dejando que el MAIN llegue a su END y que finalice). La estructura es así:

......PROGRAM juego_de_ejemplo;

......BEGIN
..........set_mode(m640x480);
..........load_fpg("c:\cursoDIV\curso1.fpg");
..........personaje();
......END

Éste sería el MAIN. Paso a explicar cada sentencia. set_mode(m640x480) pone la resolución en pantalla a 640 x 480 pixels, la cual considero adecuada para la mayoría de los proyectos. La resolución por defecto es 320 x 240, que es en la que trabajaríamos si no ponemos este comando. La lista de resoluciones posibles está en la ayuda de DIV, que por cierto es bastante completa. load_fpg carga un fpg (Fichero Para Gráficos, ocurrente, eh?), que es donde están guardados los gráficos que usaremos en los juegos. Deberéis crear uno y poner la ruta completa entre " " (esa es solo un ejemplo). Os recomiendo que cada juego tenga su directorio personal e intrasferible a efectos de orden. Si no podéis perfectamente perder los archivos y borrarlos sin querer. Lo último es una llamada a un proceso, llamado en este caso "personaje". El paréntesis sirve para poner parámetros. Después del MAIN ponemos esto:

......PROCESS personaje();

......BEGIN
..........x=320; y=240; graph=1;
..........LOOP
..............IF (key(_up)) y-=10; END
..............IF (key(_down)) y+=10; END
..............IF (key(_left)) x-=10; END
..............IF (key(_right)) x+=10; END
..............FRAME;
..........END
......END

Y os preguntaréis, ¿qué hace eso? Muy sencillo. x e y son la posición del gráfico en la pantalla. El punto (0,0) está en la esquina superior izquierda de la pantalla, y como tiene 640 puntos de ancho y 480 de alto el gráfico estará en el centro. graph es el código del gráfico en el fpg, por lo que tendremos que dibujar un gráfico no muy grande (30 x 30 es un tamaño adecuado) y meterlo en el fpg (arrastrándolo hasta él). Por lo que en el centro de la pantalla aparecerá el gráfico que tan "cuidadosamente" hemos dibujado. El resultado podría ser algo parecido a esto:

No muy impresionante, ¿verdad? Pero esto es sólo el principio. Dentro de poco seréis capaces de hacer cosas mucho más elaboradas que esto (la verdad es que para hacer esto no hace falta demasiado trabajo, pero bueno...).

Sigamos. A continuación nos encontramos un LOOP, que comienza un bucle infinito, es decir, empieza ahí, ejecuta todas las órdenes hasta el final (marcado por su END correspondiente) y vuelve a empezar. Así mientras el proceso exista (más adelante veremos maneras de romper un bucle). Las estructuras que hay en el interior son de las que más se usan. IF se utiliza para crear condiciones, que se expresan entre paréntesis. Luego se ponen las órdenes a ejecutar a continuación y se cierra con un END. En este caso se comprueba a ver si alguna de las

teclas está pulsada con la orden key(), que devuelve cierto si la tecla está pulsada. Éste es uno de los conceptos fundamentales de DIV. Cuando alguna función devuelve algo ese dato se puede usar para hacer o saber infinidad de cosas. Ya lo iremos viendo a medida que aparezcan. Si la condición se cumple corrige las coordenadas del gráfico, es decir, lo mueve. Podéis ver que he usado una manera un poco extraña de expresarlo, pero es la más corta y, por lo tanto, la que más uso. Escribir y+=10; o y=y+10; es exactamente lo mismo. Hay otra manera abrebiada: es lo mismo poner y++; , y+=1; o y=y+1; . Lo mismo es aplicable a la resta.

Finalmente llegamos a la sentencia FRAME. Ésta sentencia es fundamental. Indica cuando está el proceso listo para volcar la siguiente imagen a la pantalla. Hasta que todos los procesos activos hayan llegado hasta una sentencia FRAME el programa no seguirá. Por lo tanto, si ponemos un bucle infinito sin sentencia FRAME el programa se colgará. Estáis avisados.

También quiero llamar la atención sobre las tabulaciones en el código. Si os fijáis un poco veréis claramente que sentecias están dentro del BEGIN y del LOOP. Así es mucho más fácil revisar el código cuando falla o cuando se quiere modificar por alguna razón. Ya lo dije al principio y lo vuelvo a repetir: el orden es fundamental.

Pero os diréis: "Este juego es un peñazo. Moverse por la pantalla no es divertido." Os doy toda la razón del mundo, pero no esperaréis hacer un Super Mario Bross así, por inspiración del Espíritu Santo, ¿verdad? Paciencia, todo llegará. Pero vamos a darle un pequeño toque al programa. En el MAIN, debajo de personaje(); poned laberinto(); , y al final añadid estas líneas:

......PROCESS laberinto();

......BEGIN
..........x=320; y=240; graph=2;
..........LOOP
..............FRAME;
..........END
......END

Y donde en el proceso personaje(); , justo antes del FRAME, lo siguiente:
..............IF (collision(TYPE laberinto))
..................x=320; y=240;
..............END

Tendréis que hacer un gráfico de 640 x 480 y meterlo en el fpg, en el número 2. Quedará algo parecido a esto:

Ahora si al movernos chocamos contra el laberinto la nave vuelve al centro. Ya hemos puesto un dificultad. Dependiendo de lo cabritos que hayamos sido al dibujar el laberinto el juego será muy fácil, normal, difícil o imposible, pero ya será un juego con todas las letras. Por lo tanto, ya podéis decir que habéis hecho un juego. ¡Felicidades!

Veamos que nuevas órdenes hemos metido. En el MAIN tenemos una nueva llamada a otro proceso. Nada especial. En el proceso personaje(); tenemos una nueva orden: collision(TYPE laberinto); . Esta sentencia devuelve cierto si el gráfico del proceso que la llama y el gráfico del proceso entre paréntesis (se pone TYPE y luego el nombre del proceso) se superponen de alguna manera. Por lo tanto, el IF es cierto y se ejecutan las sentencias del interior. Y ahí nos encontramos

dos órdenes, que vuelven a poner el proceso personaje en el centro de la pantalla. Fácil, ¿verdad? Pues sí (vamos, creo yo; si has tenido problemas ponte en contacto conmigo e intentaré explicártelo de otra manera). Fijaros que en este ejemplo, si quisieramos hacer que se moviera más despacio o más deprisa tendríamos que alterar las cuatro cifras. Si en vez de 10 hubiésemos puesto una constante, como por ejemplo declarando velocidad=10; al principio (en las constantes; ver el capítulo anterior) y poniéndolo en vez de 10, bastaría con alterar el valor de la constante al principio del programa para alterar todo el movimiento, lo que en un programa extenso nos ahorraría muchísimo tiempo y nos aseguraría que no nos hemos dejado nada por cambiar. Como ya había dicho el uso de las constantes puede ahorrar mucho esfuerzo.

Finalmente, el movimiento del personaje no es muy realista, aunque es perfectamente válido. Cuando se pulsa la tecla se mueve y cuando se suelta se para. Simple, pero efectivo. ¿Pero qué pasa si queremos que tenga aceleración? ¿O si queremos que avance y gire? También es muy fácil.