Estoy intentando hacer videojuegos con HTML5 y Javascript.
Basándome en un tutorial hice lo siguiente:
Código HTML:
Ver original
<!doctype html> <html> </head> <body BGCOLOR="black"> <TABLE border="0" align="center" valign="center"> </TABLE> <SCRIPT type="text/javascript"> // Objetos importantes de canvas var canvas = document.getElementById('aliens'); var ctx = canvas.getContext('2d'); this.buffer = document.createElement('canvas'); this.buffer.width = this.canvas.width; this.buffer.height = this.canvas.height; this.bufferCtx = this.buffer.getContext('2d'); // Crear el objeto de Christian de Lugano var chris ; var chrisx=300,chrisy=600; var chrisEstado="vivo"; var chrisContador=0; var juego = { estado: 'iniciando' }; var textoRespuesta = { contador: -1, titulo: " ", subtitulo: " " } var enemigos = []; var teclado = {}; var disparos = []; var disparosEnemigos = []; // Definición de variables para las imágenes var fondo; // Definición de funciones function cargarMedia() { fondo = new Image(); fondo.src = 'LuganoAliens.jpg'; fondo.onload = function() { var intervalo = window.setInterval(frameLoop,1000/55); } } function dibujarEnemigos() { if(chrisEstado!="hitiado" && chrisEstado!="muerto") { for(var i in enemigos) { var enemigo = enemigos[i]; ctx.save(); ctx.fillStyle = 'rgb(0,175,0)'; ctx.beginPath(); ctx.arc(enemigo.x, enemigo.y, enemigo.width-8, 2.8, 2 * Math.PI, true); ctx.closePath(); ctx.fill(); ctx.restore(); } } } function dibujarFondo() { ctx.drawImage(fondo,0,0); } function dibujarChris() { if(chrisEstado!="hitiado" && chrisEstado!="muerto") { ctx.save(); chris = new Image(); chris.src = 'http://4.bp.blogspot.com/-_0CPUimtvv8/UlAkk0Y0wWI/AAAAAAAAAI0/rLe0XtQ8p9w/s1600/esqueprovi.png'; chris.onload = function(){ ctx.drawImage(chris,chrisx,chrisy,70,170); } ctx.restore(); } } // ESTA FUNCIÓN ES LA POSTA, SEGURO LA USO SIEMPRE EN TODOS LOS JUEGUITOS function agregarEventosTeclado() { agregarEvento(document,"keydown",function(e) { // Ponemos en true la tecla apretada teclado[e.keyCode] = true; }); agregarEvento(document,"keyup",function(e) { // Ponemos en false la tecla desapretada teclado[e.keyCode] = false; }); function agregarEvento(elemento,nombreEvento,funcion) { if(elemento.addEventListener) { // Navegadores posta elemento.addEventListener(nombreEvento,funcion,false); } else if(elemnto.attachEvent) { // Para Internet Explorer elemento.attachEvent(nombreEvento,funcion); } } } function moverChris(){ // Movimiento a la izquierda if(teclado[37]) { chrisx -= 10; if(chrisx < 0) chrisx = 0; } // Movimiento a la derecha if(teclado[39]) { chrisx += 10; if(chrisx > 960) chrisx = 960; } // Disparos if(teclado[32]) { if(!teclado.disparar) { disparar(); teclado.disparar = true; } } else teclado.disparar = false; if(chrisEstado == "hitiado") { chrisContador++; if(chrisContador >= 20) { chrisEstado = "muerto"; juego.estado = "perdiste"; textoRespuesta.titulo = " GAME OVER"; textoRespuesta.subtitulo = "Apreta R y mandale cumbia de nuevo"; textoRespuesta.contador = 0; } } } function dibujarDisparosEnemigos() { for (var i in disparosEnemigos) { var disparo = disparosEnemigos[i]; ctx.save(); ctx.fillStyle = "yellow"; ctx.fillRect(disparo.x,disparo.y,disparo.width,disparo.height); ctx.restore(); } } function moverDisparosEnemigos() { for(var i in disparosEnemigos) { var disparo = disparosEnemigos[i]; disparo.y += 5; if((disparo.y>=chrisy) && (disparo.x<=(chrisx+70) && disparo.x>=(chrisx))) { chrisEstado = "hitiado"; } } disparosEnemigos = disparosEnemigos.filter(function(disparo) { return disparo.y < canvas.height; }); } function actualizaEnemigos() { function agregarDisparosEnemigos(enemigo) { return { x: enemigo.x, y: enemigo.y, width: 10, height: 33, contador: 0 } } if(juego.estado == 'iniciando') { var filaAliens=0; for(var j=0;j<6;j++) { for(var i=0;i<12;i++) { enemigos.push({ x: 17 + (i*64), y: filaAliens+10, height: 35, width:35, estado: 'vivo', contador: 0 }); } filaAliens += 50; } juego.estado = 'jugando'; } for(var i in enemigos) { var enemigo = enemigos[i]; if(!enemigo) continue; if(enemigo && enemigo.estado == 'vivo') { enemigo.contador++; enemigo.x += Math.sin(enemigo.contador * Math.PI /90) *5; enemigo.y += 0.02; if(randonmente(0,enemigos.length * 15) == 2) { disparosEnemigos.push(agregarDisparosEnemigos(enemigo)); } } if(enemigo && enemigo.estado == 'hitiado') { enemigo.contador++; if(enemigo.contador >= 1) { enemigo.estado = 'muerto'; enemigo.contador = 0; } } } enemigos = enemigos.filter(function(enemigo) { if(enemigo && enemigo.estado != 'muerto') return true; else return false; }); } function moverDisparos() { for(var i in disparos) { var disparo = disparos[i]; disparo.y -= 5; } disparos = disparos.filter(function(disparo) { return disparo.y > 0; }); } function disparar() { disparos.push({ x: chrisx + 20, y: chrisy - 10, width: 10, height: 30 }); } function dibujarDisparos() { ctx.save(); ctx.fillStyle = 'white'; for(var i in disparos) { var disparo = disparos[i]; ctx.fillRect(disparo.x, disparo.y, disparo.width, disparo.height); } ctx.restore(); } function dibujarTexto() { if(textoRespuesta.contador == -1) return; var alfa = textoRespuesta.contador/50.0; if(alfa>1) { for(var i in enemigos) { delete enemigos[i]; } } ctx.save(); ctx.globalAlpha = alfa; if(juego.estado == "ganaste" || juego.estado == "perdiste") { ctx.fillStyle = "white"; ctx.font = 'Bold 40pt Arial'; ctx.fillText(textoRespuesta.titulo, 70,100); ctx.font = '25pt Arial'; ctx.fillText(textoRespuesta.subtitulo, 250,170); } ctx.restore(); } function actualizarEstadoJuego() { if(juego.estado == 'jugando' && enemigos.length == 0) { juego.estado = 'ganaste'; textoRespuesta.titulo = "LES ROMPISTE EL ORTO A TODOS"; textoRespuesta.subtitulo = "Apreta R y mandale cumbia de nuevo"; textoRespuesta.contador = 0; } if(textoRespuesta.contador >= 0) { textoRespuesta.contador++; } if((juego.estado == "perdiste" || juego.estado == "ganaste") && teclado[82]) { juego.estado = "iniciando"; chrisEstado = "vivo"; chrisContador = 0; textoRespuesta.contador = -1; } } function hitiar(a,b) { var hit = false; if(b.x + b.width >= a.x && b.x < a.x + a.width) { if(b.y + b.height >= a.y && b.y < a.y + a.height) { hit = true; } } if(b.x <= a.x && b.x + b.width >= a.x + a.width) { if(b.y <= a.y && b.y + b.height >= a.y + a.heigth) { hit = true; } } if(a.x <= b.x && a.x + a.width >= b.x + b.width) { if(a.y <= b.y && a.y + a.height >= b.y + b.heigth) { hit = true; } } return hit; } function verificarContacto() { for (var i in disparos) { var disparo = disparos[i]; for(j in enemigos) { var enemigo = enemigos[j]; if(hitiar(disparo,enemigo)) { enemigo.estado = 'hitiado'; enemigo.contador = 0; disparos[i] = disparos.filter(function(disparo) { return disparo.y < 0; }); } } } if(chrisEstado == "hitiado" || chrisEstado == "muerto") return; for(var i in disparosEnemigos) { var disparo = disparosEnemigos[i]; } } function randonmente(inferior,superior) { var posibilidades = superior - inferior; var a = Math.random() * posibilidades; a = Math.floor(a); return parseInt(inferior) + a; } function frameLoop() { actualizarEstadoJuego(); moverChris(); actualizaEnemigos(); moverDisparos(); moverDisparosEnemigos(); dibujarFondo(); verificarContacto(); dibujarEnemigos(); dibujarDisparosEnemigos(); dibujarDisparos(); dibujarTexto(); dibujarChris(); } // Ejecución de funciones cargarMedia(); agregarEventosTeclado(); </SCRIPT> </BODY> </HTML>
El juego se basa en Christian de Lugano, un personaje real argentino salido de Youtube. Básicamente es una adaptación del Space Invaders, pero con escenario en Buenos Aires.
El problema en cuestión, por lo que inferí, viene dado por el tema de la función drawImage, ya que la imágen del protagonista Christian parpadea (a veces mucho, a veces poco), y no pude corregirlo variando la frecuencia de refrescado de los Intervals. Además, solo esta imagen que cargué con drawImage tiene este problema, los polígonos de las navecitas aliens y los disparos no presentan ningún problema. Por otro lado, las navecitas las tuve que hacer con polígonos, ya que si usaba imágenes con drawImage solamente se visualizaban de a una.
El juego lo subí a internet, usando un blogspot como página de control, y el juego en si lo subí a un host gratuito (http://www.hostinger.com.ar/).
Este es el link del juego:
http://christiandeluganovj.blogspot.com.ar/
Usando el navegador Chrome se ve un menor parpadeo que en los demás. Y cuando lo cargo desde mi computadora descubrí que también está el parpadeo, solo que es muy poquito y antes no me había dado cuenta.
Muchas gracias y saludos !!