Juego sencillo implementado en processing.js
Siguiendo con las entregas sobre la utilización de la librería processing.js, vamos a abordar la implementación de un juego sencillo en el que utilizamos variables de control, haremos uso de la instrucción millis() para el control de tiempo y random() para generar valores aleatorios. El juego se basa en localizar una forma concreta entre varias posibles que van apareciendo en pantalla con el objetivo de medir los aciertos y el tiempo dedicado. Si acertamos la forma haciendo clic sobre ella, repintaremos la pantalla añadiendo nuevas formas de manera que la dificultad se incrementa a cada pantalla.
Las variables de control que usaremos son repinta y jugar. La variable jugar se encargará de definir el estado «fin de partida» que detendrá la partida justo cuando fallemos en localizar la forma buscada. La variable repinta funciona como una especie de semáforo que controlará el momento en que debemos regenerar la pantalla con nuevas formas y posiciones de objetos. El resto de variables que necesitamos en el programa deben contemplar la posición del objeto a localizar mediante las coordenadas posx y posy, los puntos acumulados en punts y el tamaño de nuestro objetivo, que será un círculo rojo, en la variable tamany.
var posx = 0; var posy = 0; var punts = 0; var repinta = 1; var jugar = 1; var tamany = 35;
Como ya vimos en el artículo anterior, definimos la pantalla de juego en la función setup:
void setup(){ size(800,600); background(0,0,0); cursor(CROSS); };
La función principal a utilizar, será un bloque draw que repintará la pantalla cuando se active el semáforo repinta y solamente mientras estemos en juego. Para ello, invocaremos la función dibuixa_formes() cuando las variables de control tengan los valores adecuados. De esta manera, y asignando el valor 0 a repinta justo tras generar la pantalla evitaremos que draw genere nuevas pantallas de forma continua, logrando congelar el estado de la pantalla hasta que realicemos una interacción a través de teclado.
draw = function(){ if (jugar===1 && repinta===1){ dibuixar_formes(); } };
La función dibuixar_formes() será la encargada de generar una pantalla con objetivos falsos y el objetivo real. Para ello, realizaremos los siguientes pasos:
- Limpiar la pantalla generando un nuevo fondo vacio con la instrucción background
background(0,0,0);
- Generar formas falsas mediante un bucle for, de manera que las formas generadas se van incrementando con la puntuación acumulada y adquieren valores aleatorios de color y de posición. La función random(ini,fin) se encarga de generar valores aleatorios entre un límite inferior y uno superior.
for(var i=0; i<=punts; i++){ fill(floor(random(0,255)),floor(random(0,255)),floor(random(0,255))); ellipse(floor(random(50,750)),floor(random(100,550)),tamany,tamany); }
- Seguidamente, dibujaremos la forma objetivo en una posición aleatoria. Nos interesa dibujarla en último lugar para que nunca quede oculta tras una de las formas falsas ya que el programa va dibujando de forma secuencial una forma tras otra como si de capas se tratara.
posx=floor(random(50,750)); posy=floor(random(100,550)) fill(255,0,0); ellipse(posx,posy,tamany,tamany);
- Tras ello, pasamos a informar mediante mensajes en la parte superior de pantalla de los puntos acumulados y el tiempo que llevamos jugando la partida. Para el control del tiempo usaremos la función millis() que muestra directamente el tiempo que nos interesa:
fill(255,0,0); textAlign(CENTER); textSize(18); text("Punts: " + punts, 250, 30); fill(255,0,0); textAlign(LEFT); textSize(18); text("Temps: " + millis()/1000 , 20, 30);
- Finalmente, cambiamos el valor de la variable repinta, para activar el semáforo. De esta manera evitaremos un nuevo repintado hasta recibir la interacción correspondiente por parte del usuario:
repinta=0;
A continuación, podemos ver la función en su conjunto:
void dibuixar_formes(){ background(0,0,0); //Formes Despiste for(var i=0; i<=punts; i++){ fill(floor(random(0,255)),floor(random(0,255)),floor(random(0,255))); ellipse(floor(random(50,750)),floor(random(100,550)),tamany,tamany); } //Forma Objectiu posx=floor(random(50,750)); posy=floor(random(100,550)) fill(255,0,0); ellipse(posx,posy,tamany,tamany); //Escriu puntuacio fill(255,0,0); textAlign(CENTER); textSize(18); text("Punts: " + (punts), 250, 30); //Escriu puntuacio fill(255,0,0); textAlign(LEFT); textSize(18); text("Temps: " + millis()/1000 , 20, 30); //Prepara nova pantalla repinta=0; };
Ya solo nos queda examinar la función encargada del control del ratón. Con mouseClicked() controlaremos el momento en que el usuario marque una posición en pantalla, la compararemos con las coordenadas del objetivo y en función del acierto o no, acumularemos puntos permitiendo un nuevo repintado o mostraremos el mensaje de final de partida.
Controlamos que seguimos en juego para evitar clics una vez finalizada la partida. En este juego sencillo, si queremos volver a jugar, obligamos a refrescar pantalla y volver a iniciar el entorno.
if (jugar===1){
Como ha existido interacción del usuario, activaremos el semáforo para la función draw regenere el escenario en la siguiente pasada.
if (repinta === 0) { repinta = 1;}
Validamos si el clic está dentro de la figura objetivo para incrementar los puntos o generar el mensaje de fin de partida:
if (mouseX>posx-tamany && mouseX<posx+tamany && mouseY>posy-tamany && mouseY<posy+tamany){ punts+=1; }else{ jugar=0; fill(255,0,0); textAlign(RIGHT); textSize(18); text("GAME OVER: " + punts + " en " +millis()/1000 + " segons ", 780, 30); }
A continuación, podemos ver la función en su conjunto:
void mouseClicked(){ if (jugar===1){ if (repinta === 0) { repinta = 1;} if (mouseX>posx-tamany && mouseX<posx+tamany && mouseY>posy-tamany && mouseY<posy+tamany){ punts+=1; }else{ jugar=0; //Escriu Game Over fill(255,0,0); textAlign(RIGHT); textSize(18); text("GAME OVER: " + punts + " en " +millis()/1000 + " segons ", 780, 30); } } };
En conclusión, hemos realizado un sencillo juego en el que interactuamos a través del clic y posición del ratón. Utilizando un semáforo y la función random() logramos generar pantallas nuevas a cada paso, y con la función millis() logramos controlar el tiempo dedicado a localizar el objetivo. Programar un juego es muy sencillo utilizando librerías y un conjunto relativamente escaso de instrucciones. Como es habitual, en los enlaces dispones de la implementación y del código fuente necesario para replicar los ejemplos utilizados.
- Ejemplo
- Código fuente del ejemplo
- Librería processing.js
- Khan Academy – Introducción a JS: dibujo y animación