La experiencia del juego AltMegaRace:¿Cómo fue codificado?- Segunda parte.

Lo que se presenta a continuación es la explicación que el desarrollador de Intel ha brindado respecto a la codificación de su aplicación. Ésta es la segunda parte y trata los siguientes temas: • Detector de Colisiones • Matriz de Misiles • Matriz de Enemigos Detector de Colisiones En la primera parte del instructivo se observó que la nave era capaz de moverse en la pantalla pero podía perderse fácilmente. Se pensó entonces en los límites del juego y en los bordes internos del espacio del mismo de manera tal que la nave pudiera rebotar como una bola en la mesa de billar. Para eso, Duffy pensó que si golpeaba o excedía los bordes verticales la nave debería invertir el movimiento horizontal, mientras que al chocar o excederse de los límites horizontales, la misma debería revertir su movimiento vertical. En otras palabras, si la nave toca el borde, su marcha requiere ser invertida. Para hacer esto, verificó el shipx y la posición shipy cada vez que animaba la nave. Si la posición x de la nave se encontraba en una condición de choque con un borde vertical aplicaba x_speed =x_speed*-1. Si se encontraba coexistiendo más allá del borde horizontal, utilizaba y_speed = y_speed*-1. Con estos códigos logró el efecto rebote. El código descripto abajo verificará la posición x &y de la nave. if(shipx>gamew-radi){ shipx=gamew-radi; x_speed*=-1; } if(shipxgameh-radi){ shipy=gameh-radi; y_speed*=-1; } if(shipy=200 && shipy>200 && shipy<300 && shipx<=210){ x_speed*=-1; } if((shipx<=800 && shipy<300 && shipy>200 && shipx>790)){ x_speed*=-2; } if((shipy<=310 && shipx>200 && shipx<800 && shipy>300)){ y_speed*=-1; } if((shipy>=200 && shipx>200 && shipx<800 && shipy<210)){ y_speed*=-1; } Matriz de Misiles Una cosa que Duffy resalta de los viejos videojuegos es la restricción de fuegos de misiles en la pantalla. Space Invaders & Centipe, por ejemplo, permite un misil a la vez; entonces si pierdes la oportunidad de derribar al enemigo debes esperar para limpiar la pantalla y volver a disparar. Eso es lo que el desarrollador de Intel quería hacer en su juego pero añadiendo una capacidad de fuego rápido. Así, estableció el número de misiles para tener en pantalla en 3. De esta forma, si pierdes el objetivo, debes esperar que al menos uno de esos misiles limpie la pantalla para que tu nave vuelva a disparar. Esto hace el juego más estratégico y en donde la precisión del disparo juega un papel fundamental. Ahora bien, si coexisten 3 misiles en la pantalla, se requieren tres misiles diferentes coordinados al mismo tiempo y luego determinar si éstos han chocado contra el borde. Desafortunadamente, si ellos se estrellan contra los límites, desaparecen, en vez de cambiar de dirección como lo hace la nave. Para animar 3 misiles a lo largo de 3 sets de coordinadas x & y es necesario crear una matriz. Ésta es como una pequeña cuadrícula virtual que guarda la posición x & y del misil. Además, puede almacenar otros atributos del mismo como el color, por ejemplo, o darle a cada uno de ellos un disparo de diferente color. Una matriz es muy manipulable, permite guardar toda la información sobre un objeto. Crear una matriz de misiles Crear una matriz es muy simple en JavaScript. La pregunta es cuándo agregarla. Un nuevo misil es creado cada vez que hay un disparo. Entonces cada vez que se acciona el comando “S” es imprescindible crear una nueva matriz. Lo siguiente es agregado para el comando “S”: push.lasers(shipx, shipy, spin) Esto significa que cada vez que se presiona el botón de disparo (la tecla S) se agregará un misil a la matriz. Cuando una matriz es construida, asigna información a una variable con un número comenzando con 0. Entonces, después de accionar la tecla S tendré almacenados lasers(0), lasers(1) & lasers(2). Para todos aquellos estará guardada la posición X & Y y el ángulo de la nave. Serán almacenados como lasers(x)(0), lasers(x)(1) & lasers(x)(2). En otras palabras, si no tengo aún misiles disparados y mi nave está en X = 50; Y = 120 con un ángulo de 45, cuando presione S, un misil llamado 0 se creará así: lasers[0] = 50,120,45 Adicionalmente, cada uno de aquellos números pueden ser llamados variables, de la siguiente manera: lasers[0][0]=50 lasers[0][1]=120 lasers[0][2]=45 Lo anteriormente expuesto es una clave. Duffy intenta dibujar misiles basados en las variables de arriba y con el objetivo de animarlos busca aplicar algo de matemáticas sobre ellas para que los misiles se muevan en la pantalla. Finalmente utiliza las variables para verificar dónde está el misil. Si ya hay 3 misiles en el comando S no se debe agregar otro más a la matriz. Es fácil de codificar. La variable arrayname.length o, en este caso lasers.length dirá cuantos misiles están actualmente en la matriz. Entonces si lasers.length es < 3 puedo ejecutar push.lasers(shipx, shipy, spin). Remover misiles de la Matriz Por último, si se desean más de tres misiles siempre hay que remover uno de la matriz, ya sea que haya golpeado algún enemigo o se haya ido del espacio del juego. Se utiliza el mismo método de detección de colisiones para los misiles. El siguiente código establece las variables para los proyectiles var mcolor="red"; var missilespeed=20; var missilecount=3; var laserTotal = 2; var lasers = []; Este código es el elemento Canvas que dibuja la forma de los misiles function drawlaser(){ context.strokeStyle=mcolor; context.beginPath(); context.moveTo(0, shipsize*.2); context.lineTo(shipsize*-.1, 0); context.lineTo(0, shipsize*-.2); context.lineTo(shipsize*.1, 0); context.lineTo(0, shipsize*.2); context.stroke(); } Este código verifica cuántos misiles se tienen. function moveLaserXY() { if (lasers.length){ for (var i = 0; i < lasers.length; i++) { context.save(); // mcolor=mcolora[i]; lasers[i][0] = lasers[i][0] + missilespeed * Math.cos(lasers[i][2]); lasers[i][1] = lasers[i][1] + missilespeed * Math.sin(lasers[i][2]); context.translate(lasers[i][0], lasers[i][1]); context.rotate(spin * Math.PI/180); drawlaser(context); context.restore(); } } } Este es el código que determina si el misil ha tocado un borde del espacio del juego. Si así ha ocurrido, entonces lo remueve de la matriz. function killLaser() { for (var i = 0; i < lasers.length; i++) { if(lasers[i][0]>200 && lasers[i][1]>200 && lasers[i][1]<300 && lasers[i][0]<800){ lasers.splice(i, 1); } if(lasers[i][0]>gamew || lasers[i][0]<0 || lasers[i][1]>gameh ||lasers[i][1]<0){ lasers.splice(i, 1); } } } Naves Enemigas A estas alturas, un lindo y amigable juego ha tomado forma. Puedes viajar por el espacio y disparar misiles, pero es mucho mas divertido si tienes enemigos. Ésta es probablemente la parte más complicada del juego. Es preciso mover los enemigos de manera independiente y con cierta aleatoriedad para que el juego no sea súper predecible. Para ello, Duffy creó un set de 6 enemigos aleatoriamente ubicados en la parte de abajo de la pantalla. Al igual que con los misiles, se requiere para cada uno, una posición X & Y, para poderlos mover. Por lo tanto, es imprescindible crear una matriz para los enemigos y luego determinar el hecho de que si un misil derriba el enemigo sea posible remover tanto al misil como al enemigo. Variables para los enemigos: var enemycount = 6; // how many enemies I wish to start with var enemies =[]; // Empty array that I will use to store enemy info var enemyrotatedeg=0; // rotation of enemy, initially set to 0 var enemyx=200; // this is where I want to start creating enemies var enemyy=320; // same as above var enemyspeed=2; // how fast the enemies move. This will get faster with every other level En la primera parte del código se crean los enemigos. function createenemies(){ for (var i=0; i=320 &&enemies[i][0]<=enemies[i][6]){ enemies[i][4]=0; enemies[i][5]=-1; } if (enemies[i][1]<=200 && enemies[i][0]<=200 &&enemies[i][1]<=enemies[i][6]){ enemies[i][4]=1; enemies[i][5]=0; } if (enemies[i][1]<=200 && enemies[i][0]>=800 && enemies[i][0]>=1000-enemies[i][6]){ enemies[i][4]=0; enemies[i][5]=1; } if (enemies[i][1]>=320 && enemies[i][0]>=800 && enemies[i][1]>=320+enemies[i][6]*.8){ enemies[i][4]=-1; enemies[i][5]=0; } enemies[i][0]=enemies[i][0]+enemies[i][4]*enemyspeed; enemies[i][1]=enemies[i][1]+enemies[i][5]*enemyspeed; El código final rotará el interior de los cuadros de los enemigos context.strokeRect(-5,-5,10,10); context.beginPath(); context.arc(0, 0, 17, 0, Math.PI*2, true); context.closePath(); context.stroke(); context.rotate(enemyrotatedeg * Math.PI/180); context.lineWidth=1; drawenemy(); context.restore(); } } Disparar al enemigo Para que el juego esté completo se necesita poner las cosas juntas y permitirle a los misiles, destruir enemigos. Esto es básicamente el mismo proceso que se emplea para establecer la acción de los misiles cuando tocaban los bordes. A la detección de colisiones de misiles y enemigos. Duffy sumó un efecto de explosión para el choque entre el misil y el enemigo. Puede entonces haber mas de un estallido a la vez en la pantalla. Conclusión: también hay que crear una matriz para estos efectos. Variables var blast =[]; // this is the array of blast effects var bplus=6; //used to set the varied starburst effect of the ship and enemy blast var rnd = (Math.round(Math.random() * 50)); function drawBlast() { for (var i=0; i

Pour de plus amples informations sur les optimisations de compilation, consultez notre Avertissement concernant les optimisations.