Cristalab

Sincronizar peliculas a diferente velocidad de fotogramas

Por: Zguillez + 08.10.2006

Cuando cargamos una pelicula externa dentro de una pelicula principal, la velocidad de fotogramas de la pelicula cargada se adapta a la velocidad de la pelicula principal, y esto nos dará problemas de sincronización si estamos importando pelicuals a diferentes velocidades.

Supongamos que tenemos esta animación:



Esta animación tiene una velocidad de 12 fotogramas por segundo y una duración de 200 fotogramas.

Esta misma animación la podríamos haber conseguido a 24 fotogramas por segundo y 400 fotogramas de duración.



Si visualizamos estas dos animaciones por separado parecen tener la misma velocidad.

El problema nos vendrá si queremos colocar estas dos animaciones dentro de una misma pelicula. Por ejemplo, colocamos estas dos peliculas dentro de una pelicula a 24 fotogramas por segundo.



La pelicula de 12 fotogramas por segundo pasa a tener la velocidad de 24 fotogramas por segundo de la pelicula principal, pero mantiene su duracion que es de 200 fotogramas, con lo que parece tener el doble de velocidad...

Esto lo podemos solucionar con una clase que permita modificar la velocidad de fotogramas de un MovieClip concreto:

Código :

class FrameRate extends MovieClip {
   function FrameRate(clip, fps) {
      clip.stop();
      if (clip.__fpsInt__ != undefined) {
         clearInterval(clip.__fpsInt__);
         delete clip.__fpsInt__;
      }
      clip.__nextFrame__ = function(ptr) {
         if (ptr._currentframe < ptr._totalframes) {
            ptr.nextFrame();
         } else {
            ptr.gotoAndStop(1);
         }
         updateAfterEvent();
      };
      clip.__fpsInt__ = setInterval(clip.__nextFrame__, Math.round(1000 / fps), clip);
   }
}

Este código lo copiaremos y pegaremos dentro de un archivo de código y lo llamaremos "FrameRate.as" (respetando las mayúsculas)

Y cambiaremos el FrameRate del clip que contiene la animación de 12 fotogramas por segundo de la siguiente manera:

Código :

var carga:MovieClipLoader = new MovieClipLoader();
carga.loadClip("ani1.swf", contenedor1);
carga.loadClip("ani2.swf", contenedor2);
ani1 = new FrameRate(contenedor1, 12);

El resultado es que la animación mantiene la velocidad de fotogramas original.

Etiquetas actionscript

Comentarios | Enviar un comentario
Grfx, te volviste a adelantar Riendo
Por cierto, está bien sistematizarlo en una clase, pero ya que sólo tiene una función, yo la pondría en un archivo .as, que se refiera a MovieClip.prototype y que se acceda a ella con un #include

Código :

MovieClip.prototype.frameRate = function(fps) {
   this.stop();
   if (this.__fpsInt__ != undefined) {
      clearInterval(this.__fpsInt__);
      delete this.__fpsInt__;
   }
   this.__nextFrame__ = function(ptr) {
      if (ptr._currentframe<ptr._totalframes) {
         ptr.nextFrame();
      } else {
         ptr.gotoAndStop(1);
      }
      updateAfterEvent();
   };
   this.__fpsInt__ = setInterval(this.__nextFrame__, Math.round(1000/fps), this);
};


Y para utilizarla:

Código :


#include "frameRate.as"
var carga:MovieClipLoader = new MovieClipLoader();
carga.loadClip("ani1.swf", contenedor1);
carga.loadClip("ani2.swf", contenedor2);
contenedor1.frameRate(12);

Por: Zah
Despues de un buen rato de descuadran
Por: dablak
Es cierto parece ser que la animacion de arriba corre un poco mas rapido
Por: Freaze_blog
Sí. es por esta línea, el Math.round sobra.

Código :


//this.__fpsInt__ = setInterval(this.__nextFrame__, Math.round(1000/fps), this);
this.__fpsInt__ = setInterval(this.__nextFrame__, 1000/fps, this);//Así mejor

Por: Zah
igualmente, este es un asunto muy consultado en los foros, sera de mucha ayuda miau
Por: Mariux
mmm... si es verdad que se descuadra un poco... pero bueno es un descuadre minimo comparado con el descuadre inicial. Posiblemente Zah tenga razón y sea por el redondeo.

PD. lo del include# es una opción, pero yo prefiero trabajar con clases... miau
Por: Zguillez
quizas ese pequeño desface se podria solucionar si se aplica la logica de Drop Frame. claro que eso es mas instantaneo, en todo caso este dato es de gran ayuda.
Por: supermac_blog
OMFG!!!! por fin, y todo encapsuladito... que MONO, es genial Muy Feliz

Gracias Zguillez, has aportado luz a uno de los secretos más oscuros que teniamos con los multiswfs Sonrisa
Por: MorphX_blog
Como preguntan mucho por esto en el foro, dejo el código para hacer que vaya hacia atrás:

Código :

MovieClip.prototype.frameRate = function(fps) {
   this.stop();
   if (this.__fpsrevInt__ != undefined) {
      clearInterval(this.__fpsrevInt__);
      delete this.__fpsrevInt__;
   }
   this.__prevFrame__ = function() {
      if (this._currentframe != 1) {
         this.prevFrame();
      } else {
         this.reverseComplete();
         this.gotoAndStop(this._totalframes);
      }
      updateAfterEvent();
   };
   this.__fpsrevInt__ = setInterval(this.__nextFrame__, 1000/fps, this);
};

Por: Zah

zah :

Como preguntan mucho por esto en el foro, dejo el código para hacer que vaya hacia atrás:

cOOl Thumbs up
Por: Zguillez
Perdón, la función anterior tiene 5 o 6 errores de niño Apenado

Código :

MovieClip.prototype.rewindAnimation = function(fps) {
   this.stop();
   if (this.__fpsrevInt__ != undefined) {
      clearInterval(this.__fpsrevInt__);
      delete this.__fpsrevInt__;
   }
   this.__prevFrame__ = function(ptr) {
      if (ptr._currentframe != 1) {
         ptr.prevFrame();
      } else {
         ptr.reverseComplete();
         ptr.gotoAndStop(ptr._totalframes);
      }
      updateAfterEvent();
   };
   this.__fpsrevInt__ = setInterval(this.__prevFrame__, 1000/fps, this);
};

Ahora, me estoy dando cuenta de que así se carga uno los play, stop, gotos y demás. Habría que hacer una clase que extienda a MovieClip, con métodos como _stop o algo así. Maikel me ensñó cómo aquí
Por: Zah
Por ahora mejor dejarlo así:

Código :

MovieClip.prototype.rewindAnimation = function(fps) {
   this.stop();
   if (this.__fpsrevInt__ != undefined) {
      clearInterval(this.__fpsrevInt__);
      delete this.__fpsrevInt__;
   }
   this.__prevFrame__ = function(ptr) {
      if (ptr._currentframe != 1) {
         ptr.prevFrame();
      } else {
         clearInterval(ptr.__fpsrevInt__);
         delete ptr.__fpsrevInt__;
      }
      updateAfterEvent();
   };
   this.__fpsrevInt__ = setInterval(this.__prevFrame__, 1000/fps, this);
};

Por: Zah
Lo primero mencionado, solo funciona con loadClip no?
Porque yo lo hago con un loadMovie y no me funciona...
Por: t3rzer_blog
Donde he de colocar la 2 parte del codigo que dice cambiar el framrate del clip de 12 fotogramas ?

var carga:MovieClipLoader = new MovieClipLoader();
carga.loadClip("ani1.swf", contenedor1);
carga.loadClip("ani2.swf", contenedor2);
ani1 = new FrameRate(contenedor1, 12);
Por: JkoRn
Deja un comentario
IMPORTANTE

Recuerda ser respetuoso, no insultes a otras personas, ni uses palabrotas, hay una persona al otro lado de la pantalla.

Habla bien, NO ESCRIBAS EN MAYUSCULA TODO, no escribas como en un SMS, evita cosas como "ke", "x q" y demás abreviaciones.

Aquí funcionan las etiquetas de los foros, puedes usar [b] para negrita, [img] para las imágenes, [url] para los enlaces, etc.

Si tienes preguntas técnicas, envíalas mejor al foro.