Comunidad de diseño web y desarrollo en internet online

Crear una precarga en Actionscript 3 con porcentaje

Nota Preliminar: Es posible que el código de este tip sea un poco complicado de entender, y que haya formas más sencillas de hacer lo mismo, y seguramente el código se pueda optimizar, pero acabo de empezar con ActionScript 3, y voy poco a poco, jeje. No obstante, ya me doy cuenta de la versatilidad de ActionScript 3 frente a AS2. Recomiendo a todos que se pasen a AS3 ;)

Éste es mi primer tip en ActionScript 3, pero creo que puede ser muy útil a la gente que haga animaciones grandes y pesadas:

El concepto de precarga inteligente significa que es un preloading que calcula el tiempo que tardará en cargarse el resto de la animación, y cuando el tiempo sea menor que la animación, comienza a reproducirla. Es algo parecido a lo que hace YouTube con sus vídeos, que te los deja sin esperar a que carguen completamente. Lo veremos mejor con un ejemplo:

Un programador aburrido :

  • Tenemos una animación de 2 minutos
  • La animación tarda 3 minutos en cargarse

Cuando haya pasado un minuto (y, por tanto, queden 2 minutos de carga, que es el tiempo que dura la animación), la animación se empezará a reproducir a la vez que continua cargando (pero asegurándonos que no se va a cortar*)

*Siempre es posible que se corte, ya que la velocidad de las conexiones no es estable, pero aún así es bastante fiable.

El sistema que sigue el preloading es el siguiente:
  • Durante el primer 10% de la descarga, se comporta como un preload normal
  • Cuando se ha descargado el 10% de la película, se hace un cálculo aproximado de la velocidad de descarga y del tiempo que se necesita para cargar la animación.
  • Por último, calcula el tiempo que dura la animación, y cuando éste sea mayor que el tiempo que tarda para terminar la carga, comienza a reproducirla.

Lo cierto es que no tengo mucho más que explicar, ya que el código está repleto de comentarios que van explicando cada línea:

Código :

//Escriba aquí sus fotogramas por segundo
var fps:Number = 25
//Paramos la reproducción
stop()
//Creamos la variable "porcentajeUsuario",
//que será el porcentaje que mostraremos al usuario
var porcentajeUsuario:int
//Creamos una variable que represente el porcentaje real de la descarga
var porcentajeReal:int
//tiempo en el cual se inició la película
var tiempoInicio:Number = getTimer()
//Iniciar la función "cargaInteligente" mediante
//un escuchador mientras se carga la película
this.loaderInfo.addEventListener(ProgressEvent.PROGRESS, cargaInteligente)
//Función "progreso"
function cargaInteligente(e:ProgressEvent){
   //bytes cargados
   var cargados:Number = e.bytesLoaded
   //bytes totales
   var totales:Number = e.bytesTotal
   //porcentaje de carga
   var porcentaje:int = cargados*100/totales
   //cuando se ha descargado el 10% de la película...
   if(porcentaje > 10){
      //calculamos el tiempo en el que estamos
      var tiempoActual:Number = getTimer()
      //calculamos los segundos transcurridos desde el inicio de la carga
      var tiempoTranscurrido:Number = (tiempoActual - tiempoInicio)/1000
      //calculamos los kilobytes totales
      var KBtotales:Number = totales/1024
      //calculamos los kilobytes descargados
      var KBcargados:Number = cargados/1024
      //calculamos los kilobytes restantes
      var KBrestantes:Number = KBtotales - KBcargados
      //calculamos la velocidad de descarga (KB/s)
      var velocidad:Number = KBcargados/tiempoTranscurrido
      //dejamos un margen de error a la velocidad
      //(por ello, utilizamos el 90% de la velocidad)
      var velocidadMargen:Number = velocidad*0.9
      //Calculamos el tiempo que tardaría en descargar el resto de la película
      var tiempoDeCargaRestante:Number = KBrestantes/velocidadMargen
      //Calculamos la duración de la película (en segundos)
      var tiempoPelicula:Number = this.totalFrames/fps
      //si el tiempo de carga es menor a la duración
      //de la película, comenzamos a reproducirla
      if(tiempoDeCargaRestante < tiempoPelicula){
         this.play()
      }
      //Invocamos la función "porcentajeAparente", que nos devolverá
      //un porcentaje en relación con el tiempo que falta para que
      //la reproducción de la película comience.
      porcentajeUsuario = porcentajeAparente(tiempoTranscurrido,tiempoDeCargaRestante,tiempoPelicula)
   }else{
      //Mientras no se ha descargado el 10% de la película
      //mostraremos al usuario el porcentaje real
      porcentajeUsuario = porcentaje
   }
   //Cuando la carga se ha completado
   if(porcentaje == 100){
      //Reproducimos la película si no se ha hecho todavía
      if(this.currentFrame == 1){
         this.play()
      }
      //Eliminamos el escuchador
      this.loaderInfo.removeEventListener(ProgressEvent.PROGRESS, cargaInteligente)
   }
   //Damos valor a la variable "porcentajeReal"
   porcentajeReal = porcentaje
}
//Función "porcentajeAparente"
function porcentajeAparente(transcurrido:Number, restante:Number, pelicula:Number){
   //"transcurrido" representa el tiempo que ha pasado
   //desde que se comenzó a descargar la película
   //
   //"restante" representa el tiempo restante que
   //falta para descargar toda la película
   //
   //"pelicula" representa la duración de la película
   //
   //Calculamos el tiempo que falta para iniciar la reproducción
   //(sabiendo que la película se iniciará cuando el tiempo restante
   //sea menor que la duración de la película...)
   var tiempoParaIniciar:Number = restante - pelicula
   //el "tiempo que falta para iniciar la reproducción"
   //junto con el "tiempo transcurrido", forman el
   //"tiempo total de espera" para ver la película
   var tiempoTotalDeEspera:Number = tiempoParaIniciar + transcurrido
   //Con el "tiempo total de espera" y el "tiempo transcurrido"
   //podemos crear un porcentaje para saber cuando tiempo llevamos
   //esperando en relación con el "tiempo total de espera"
   //NOTA: este porcentaje será mayor que cero cuando la película
   //se reproduzca, ya que el "tiempo transcurrido" seguirá aumentando.
   //Para solucionar esto:
   if(transcurrido > tiempoTotalDeEspera){
      transcurrido = tiempoTotalDeEspera
   }
   //Ahora sí: calculamos el porcentaje...
   var porcentajeAparente:int = transcurrido*100/tiempoTotalDeEspera
   //... y lo devolvemos
   return porcentajeAparente
}
//
//Como extra, añadimos un código para que se muestre el
//"porcentajeUsuario" en un campo de texto del escenario
this.addEventListener(Event.ENTER_FRAME, mostrarPorcentaje)
function mostrarPorcentaje(e:Event){
   if(this.currentFrame == 1){
      //Mientras que el fotograma actual sea el 1
      //(que es donde debe situarse este código)
      porcentaje_txt.text = String(porcentajeUsuario) + "% (Real: " + String(porcentajeReal) + "%)"
   }else{
      //En caso contrario, eliminamos el escuchador
      this.removeEventListener(Event.ENTER_FRAME, mostrarPorcentaje)
   }
}


Código Simplificado


Aquí les dejo el código sin comentarios, optimizado para un copy-paste (solo habría que añadir un campo de texto con nombre de instancia "porcentaje_txt" en el escenario, y cambiar el valor de la variable "fps", según los fotogramas por segundo de la película). La precarga tiene que estar necesariamente en el fotograma 1:

Código :

var fps:Number = 25
stop()
var porcentajeUsuario:int
var porcentajeReal:int
var tiempoInicio:Number = getTimer()
this.loaderInfo.addEventListener(ProgressEvent.PROGRESS, cargaInteligente)
function cargaInteligente(e:ProgressEvent){
   var cargados:Number = e.bytesLoaded
   var totales:Number = e.bytesTotal
   var porcentaje:int = cargados*100/totales
   if(porcentaje > 10){
      var tiempoActual:Number = getTimer()
      var tiempoTranscurrido:Number = (tiempoActual - tiempoInicio)/1000
      var KBtotales:Number = totales/1024
      var KBcargados:Number = cargados/1024
      var KBrestantes:Number = KBtotales - KBcargados
      var velocidad:Number = KBcargados/tiempoTranscurrido
      var velocidadMargen:Number = velocidad*0.9
      var tiempoDeCargaRestante:Number = KBrestantes/velocidadMargen
      var tiempoPelicula:Number = this.totalFrames/fps
      if(tiempoDeCargaRestante < tiempoPelicula){
         this.play()
      }
      porcentajeUsuario = porcentajeAparente(tiempoTranscurrido,tiempoDeCargaRestante,tiempoPelicula)
   }else{
      porcentajeUsuario = porcentaje
   }
   if(porcentaje == 100){
      if(this.currentFrame == 1){
         this.play()
      }
      this.loaderInfo.removeEventListener(ProgressEvent.PROGRESS, cargaInteligente)
   }
   porcentajeReal = porcentaje
}
function porcentajeAparente(transcurrido:Number, restante:Number, pelicula:Number){
   var tiempoParaIniciar:Number = restante - pelicula
   var tiempoTotalDeEspera:Number = tiempoParaIniciar + transcurrido
   if(transcurrido > tiempoTotalDeEspera){
      transcurrido = tiempoTotalDeEspera
   }
   var porcentajeAparente:int = transcurrido*100/tiempoTotalDeEspera
   return porcentajeAparente
}
this.addEventListener(Event.ENTER_FRAME, mostrarPorcentaje)
function mostrarPorcentaje(e:Event){
   if(this.currentFrame == 1){
      porcentaje_txt.text = String(porcentajeUsuario) + "%"
   }else{
      this.removeEventListener(Event.ENTER_FRAME, mostrarPorcentaje)
   }
}

¿Sabes SQL? ¿No-SQL? Aprende MySQL, PostgreSQL, MongoDB, Redis y más con el Curso Profesional de Bases de Datos que empieza el martes, en vivo.

Publica tu comentario

o puedes...

¿Estás registrado en Cristalab y quieres
publicar tu URL y avatar?

¿No estás registrado aún pero quieres hacerlo antes de publicar tu comentario?

Registrate