Ir al contenido

publicidad

Foto

[Ayuda]Animación con javascript en html5


Este tema ha sido archivado. Esto significa que no puedes responder en este tema.
3 respuestas en este tema

  • uziel5

  • Valefor

  • vida restante: 100%
  • Registrado: 08 sep 2007
  • Mensajes: 1.955
#1

Escrito 22 julio 2011 - 05:24

Hola, pues verán, ahora mismo estoy queriendo realizar juegos en HTML5 y javascript, yo normalmente utilizo java y para mi, javascript es algo nuevo, por lo que de repente se me vienen algunos problemas de los cuales la mayoría puedo resolver pero otros no, como en este caso.

Ahora mismo estoy queriendo realizar animaciones de sprites en javascript, y ya logré animar un sprite, pero tengo problemas a la hora de animar un segundo sprite, aquí les dejo mi código lo mejor explicada posible:

[code:1]var fps = 16;//intervalo en el que consigo acutalizar cada animacion
var tiempoInicio = new Date().getTime();//obtengo el tiempo en el que mi programa arranca

var ash = new Sprite("ash", new Image(), "imagenes/ash.png", 3, 64, 0, 64, 64, 0, 0, 64, 64);// creo un objeto del tipo sprite, el cual, va a ser dibujado
var pacman = new Sprite("pacman", new Image(), "imagenes/pacman.png", 17, 50, 0, 50, 50, 80, 20, 50, 50);//creo otro objeto del tipo sprite que también será dibujado

setInterval("inicializar(pacman)",fps);//llamo al método que me dibuja y anima el sprite en un intervalo de 16 milisegundos
setInterval("inicializar(ash)",fps);//llamo al método que me dibuja y anima el segundo sprite en un intervalo de 16 milisegundos

function obtenerContexto(idCanvas){//este método lo uso para obtener el contexto del canvas, sobre el cual dibujo
canvas = document.getElementById(idCanvas);
if(canvas && canvas.getContext){
contexto = canvas.getContext('2d');
if(contexto){
return contexto;
}
}
return false;
}

function inicializar(sprite){// metodo que llama a mi funcion de animar sprite, me podria ahorrar esta funcion
tiempoActual = new Date().getTime();//obtengo el tiempo actual
lapso = tiempoActual - tiempoInicio;//con esto saco la diferencia de milisegundos desde que se arranco el programa hasta el tiempo actual
animarSprite(sprite);//llamo a mi clase de animar sprite
}

function modificarTiempoInicio(){//llamo a esta funcion para modificar el tiempo en el que se inicio el programa y lo cual me permite llevar con control en el tiempo en que se ejecuta cada animacion
tiempoInicio = new Date().getTime();
}

function animarSprite(sprite){//esta funcion es la que me anima el sprite
contexto = obtenerContexto('canvas');//obtengo el contexto del canvas
sprite.img.src = sprite.src;//le doy la ruta de mi imagen al objeto imagen que contiene mi sprite
contexto.clearRect(sprite.lienzoX,sprite.lienzoY,sprite.lienzoAncho,sprite.lienzoAlto);//borro el frame anterior
if(sprite.cuadroActual >= sprite.cuadros){//si la animacion se termina vuelvo a continuarla
sprite.cuadroActual = 0;//reinicio el numero de frame a dibujar
contexto.drawImage(sprite.img, sprite.cuadroActual*sprite.imgX, sprite.imgY, sprite.imgAncho, sprite.imgAlto, sprite.lienzoX, sprite.lienzoY, sprite.lienzoAncho, sprite.lienzoAlto);//dibujo frame actual
}else{
if(lapso > 75){//si el lapso de tiempo supera los 75 milisegundos paso al siguiente frame
sprite.cuadroActual++;//paso al siguiente frame
modificarTiempoInicio();//reinicio el tiempo inicial
contexto.drawImage(sprite.img, sprite.cuadroActual*sprite.imgX, sprite.imgY, sprite.imgAncho, sprite.imgAlto, sprite.lienzoX, sprite.lienzoY, sprite.lienzoAncho, sprite.lienzoAlto);//dibujo el frame
}else{
contexto.drawImage(sprite.img, sprite.cuadroActual*sprite.imgX, sprite.imgY, sprite.imgAncho, sprite.imgAlto, sprite.lienzoX, sprite.lienzoY, sprite.lienzoAncho, sprite.lienzoAlto);//dibujo el frame
}
}
}

function Sprite(nombre, img, src, cuadros, imgX, imgY, imgAncho, imgAlto, lienzoX, lienzoY, lienzoAncho, lienzoAlto){ //creo mi "clase" sprite
this.nombre = nombre; //nombre de mi "clase" sprite
this.img = img; //imagen que contiene mi "clase" sprite
this.src = src; //ruta de la imagen que contiene mi "clase" sprite
this.cuadroActual = 0;// frame inicial de animacion
this.cuadros = cuadros; //numero de frames que contiene cada animacion
this.imgX = imgX; //coordenada en el eje X en el que empieza a dibujar de la imagen
this.imgY = imgY; //coordenada en el eje Y en el que empieza a dibujar de la imagen
this.imgAncho = imgAncho; //ancho en el que empieza a dibujar de la imagen
this.imgAlto = imgAlto; //Alto en el que empieza a dibujar de la imagen
this.lienzoX = lienzoX; //coordenada en el eje X en el que empieza a dibujar en el canvas
this.lienzoY = lienzoY; //coordenada en el eje Y en el que empieza a dibujar en el canvas
this.lienzoAncho = lienzoAncho; //ancho en el que empieza a dibujar en el canvas
this.lienzoAlto = lienzoAlto; //Alto en el que empieza a dibujar en el canvas
}[/code]

Con este código me anima mi primer sprite (pacman) sin ningun problema, pero el segundo sprite (ash) se queda parado sin hacer nada, lo cual no me explico. Si le echan un ojo al código podrán darse cuenta que los objetos sprites tienen una tributo llamado frame actual, que indica el frame actual de cada sprite, les puse este atributo por que si lo declaraba global me daba un conclicto pues los dos compartian frame actual y me animaba solo 4 frames para cada sprite (ash solo tiene 4 frames y pacman tiene 18), pero curiosamente los dos sprites se animaban.

Quizás estoy haciendo una burrada al animar los sprites, pero es algo que no se pues no he visto mucha información en internet, tampoco se si puedo ejecutar dos setInterval() sin que halla problemas, pero por lo visto en javascript no exciten los hilos y me hallo un tanto perdido la verdad.

Cualquier consejo me vale, espero que me puedan ayudar.

Viendo el código veo cosas innecesarias y que bajan el rendimiento, haré todo el código de vuelta, una vez termine actualizo y cuento como me fué.

Una disculpa

Un saludo

  • Ollydbg

  • Bahamut

  • vida restante: 100%
  • Registrado: 05 sep 2008
  • Mensajes: 6.259
#2

Escrito 22 julio 2011 - 10:45

Esto...tu sistema de fps hace aguas por todos lados.
En primer lugar estableces 16 fotogramas por segundo
Sin embargo luego dibujas los sprites cada 75 milisegundos

Si ahora divides 1000 milisegundos entre 16 fotogramas, te da que eso es igual a 62,5 milisegundos, por lo tanto deberías dibujar los sprites cada 62,5 ms y no cada 75 ms.

Saludos.

  • uziel5

  • Valefor

  • vida restante: 100%
  • Registrado: 08 sep 2007
  • Mensajes: 1.955
#3

Escrito 23 julio 2011 - 07:52

Vaya lío me estoy haciendo con esto de los frames la verdad, supongamos que refresco mi pantalla cada 75 milisegundos, y la animación de un sprite consta de 4 frames (muy pocos pero lo tomo de ejemplo), esta animación consiste en caminar dos pasos a la derecha, entonces tardaría 300 milisegundos en dar dos pasos a la derecha, que son pocos...

Con tan pocos fotogramas para una animación, ¿mejor aumento el tiempo de refresco de pantalla verdad?, por que se supone que el frame rate es para que sea mas fluida la cosa y con tan pocos fotogramas por animación no veo la utilidad de un frame rate elevado.

Toca estudiar mas sobre el frame rate y muchas cosas mas, sirve de que me ahorro muchas tonterías XD

Modifiqué el código y me quedó así:

[code:1]var canvas, contexto;

function init(){
canvas = document.createElement('canvas');
canvas.width = 350;
canvas.height = 300;
contexto = canvas.getContext('2d');
document.body.appendChild(canvas);
}

function Sprite(nombre, ruta, numFotogramas, imgX, imgY, imgAncho, imgAlto, lienzoX, lienzoY, lienzoAncho, lienzoAlto){
this.nombre = nombre;
this.img = new Image();
this.img.src = ruta;
this.numFotogramas = numFotogramas;
this.fotogramaActual = 0;
this.imgX = imgX;
this.imgY = imgY;
this.imgAncho = imgAncho;
this.imgAlto = imgAlto;
this.lienzoX = lienzoX;
this.lienzoY = lienzoY;
this.lienzoAncho = lienzoAncho;
this.lienzoAlto = lienzoAlto;
this.dibujarSprite = dibujarSprite;
}

function dibujarSprite(){
contexto.clearRect(this.lienzoX, this.lienzoY, this.lienzoAncho, this.lienzoAlto);
contexto.drawImage(this.img, this.imgX*this.fotogramaActual, this.imgY, this.imgAncho, this.imgAlto, this.lienzoX, this.lienzoY, this.lienzoAncho, this.lienzoAlto);
this.fotogramaActual++;
if(this.fotogramaActual == this.numFotogramas){
this.fotogramaActual = 0;
}
}

function run(){
ash.dibujarSprite();
pacman.dibujarSprite();
}

init();
ash = new Sprite("ash", "imagenes/ash.png", 4, 64, 0, 64, 64, 0, 0, 64, 64);
pacman = new Sprite("pacman", "imagenes/pacman.png", 18, 50, 0, 50, 50, 100, 20,50,50);
setInterval("run()", 100);[/code]

Esta vez me ha quedado mucho mejor, está mas ordenado y tiene mejor rendimiento que el anterior.

El tema no es que tenga mucha utilidad a estas alturas, he pedido a moderación que eliminaran o cerraran el tema pero no contestan X-D

  • Forista

  • GRANDIS SUPERNUS

  • vida restante: 100%
  • Registrado: 24 jul 2002
  • Mensajes: 59.586
#4

Escrito 26 julio 2011 - 07:36

Cerrado a petición del autor ;-)

51p0p4k.gif

LlzhEuf.png     48646_s.gif       l8qd00i.png



Este tema ha sido archivado. Esto significa que no puedes responder en este tema.
publicidad