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.
Por Juanlu_001 el 01 de Septiembre de 2009
Buen aporte!
Por oscartitan el 01 de Septiembre de 2009
Por carnicero666 el 01 de Septiembre de 2009
Por papachan el 01 de Septiembre de 2009
Podrias postar un preloader simple como para que los novatos tengan una alternativa.
---
saludos
Por Juanlu_001 el 01 de Septiembre de 2009
Por tito el 07 de Octubre de 2009
para nosotros
Por pipe el 07 de Octubre de 2009
Por quitan el 07 de Octubre de 2009
matematicas
Por luis el 07 de Octubre de 2009
Por AlejandroGraficos el 12 de Octubre de 2009
http://www.codigoactionscript.org/el-uso-correcto-de-actionscript-20/
PD: Yo escribia codigo en As2, y esa explicacion me golpeo con el hecho de que en realidad escribo As1 . No es lo mas lindo del mundo darse cuenta de eso, pero es la verdad
Por nestorrente el 12 de Octubre de 2009
Por x4ch1 el 27 de Octubre de 2009
Por federico el 12 de Noviembre de 2009
Por dyei nightmare el 15 de Noviembre de 2009
mucha gente tiene suficiente con el a.s. 2 pero habemos gente que queremos meterle mas crema con galleta, y nos metemos al a.s. 3 con OOP porque ofrece muchas mas herramientas para hacer web...
yo no me quejo de que introdujeran un a.s. mas complejo, de hecho doy gracias a adobe por hacer eso.
Por nestorrente el 18 de Noviembre de 2009
federico-blog :
Pues lo cierto es que no lo sé prueba a borrar el caché y entrar de nuevo, por si acaso fue un problema de la conexión en ese momento...
Por nestorrente el 18 de Noviembre de 2009
Cuando pruebas la película lo haces simulando la descarga? Porque si no la simulas, da problemas como ese.
Saludos!