Archive for the ‘ Flash ’ Category

La nueva forma de indexar contenido SWF de google

Hace dos años Google anunció que estaba colaborando con Adobe para encontrar una forma de indexar contenido dentro de swfs. Su primera versión fue una gran avance para la comunidad Flash pero carecía de grandes propiedades. Por ejemplo ésta versión solo indexaba texto dinámico que ya esté dentro dela película. osea que el tipo de campo de texto sea dinámico y que el texto esté en el campo a la hora de compilar la película. No funcionaba si el texto era cargado via xml o algún otro método en tiempo de ejecución, tampoco funcionaba si el campo de texto era estático.

Bueno Google nunca dejó de trabaja en su googleBot para conseguir mejores resultado, y ésta nueva versión indexa contenido swf sin importar su procedencia. Básicamente aseguran que todo texto que pueda leer un humano es leído por el robot de google, incluso aseguran que sigue links dentro del swf. Incluso esta versión lee los metadatos de videos flash para indexar su contenido he incluso guardar un thumbnail. La otra gran falencia que tenia la version anterior es que no podía leer swf que estaban publicadas usando cierto métodos de javascript, la nueva versión también corrige esto.

En fin grande noticias para la comunidad Flash, ya habíamos dicho en éste blog que Flash está lejos de morir y sigue dando pelea aunque Apple se niegue a incluirlo en iOS y empuje hacia html5. Siento que de a poco Flash va recuperando terreno perdido gracias a la injurias proclamadas por Apple.

más información en el google oficial de google: http://googlewebmastercentral.blogspot.com/2010/11/what-feeling-even-better-indexing-of.html

Eventos personalizado en AS3

Hasta hace muy poco tiempo siempre que tenia que hacer un script que esperar a que terminara la animacion de un moviclip para hacer otra cosa, lo que hacia era poner una variable en el ultimo frame de la aminacion del movieclip y luego usaba un setInterval o un onEnterFrame y adentro un if y preguntaba si esa variable habia cambiado.
Por ejemplo algo como:
en el ultimo frame de la animación ponía

1
2
 _root.termino=true;
stop();

y luego en el root ponía

1
2
3
4
5
6
miMovieClip_mc.onEnterFrame = function() {
      if(_root.termino==true) {
             trace ("terminó la animación se prosigue con lo siguiente");
           delete miMovieClip_mc.onEnterFrame;
      }
}

no creo que haya nada de malo en seguir utilizando este método si la aplicación es simple. cuando tenemos varios onEnterFrame o intervals dando vuelta al mismo tiempo.

AS3 se destaca por ser un leguage de programación más robusto y cuenta con todas las propiedades de los leguajes orientados a objetos, y una de esas cosas con los eventos. Por lo cual el dilema anterior queda reducido a simplemente poner un eventListener y luego disparar un evento cuando la animación termina.
Ejemplo:

1
2
3
4
5
6
function terminoAnimacion(event:Event)
{
	trace('terminó la animación');
}
 
miMovieClip_mc.addEventListener("termino", terminoAnimacion);

y luego en el último frame del movieClip disparamos el evento:

1
2
dispatchEvent(new Event("termino"));
stop();

mouseX y mouseY relativo a objetos distintos

Muchas veces necesitamos saber en donde ésta el mouse con respecto a algo. Y en cualquier momento podemos obtener su ubicación relativa al escenario o a un objeto de manera muy simple.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import flash.events.MouseEvent;
 
cuadrado_mc.addEventListener(MouseEvent.MOUSE_OVER, onDown);
function onDown(e:MouseEvent):void
{
    e.target.addEventListener(MouseEvent.MOUSE_MOVE,onMove);
}
 
function onMove(e:MouseEvent):void
{
    trace(e.localX,e.localY);
 
    debug_txt.htmlText="<b>entre del cuadrado</b>\nx: "+e.localX+"\ny: "+e.localY+"\n\n<b>mouse relativo al escenario</b>\nx: "+mouseX+"\ny: "+mouseY;
}

Esto requiero Flash player 9

Tierra en paperVision

Estuve jugando con PV3d en Flash Builder 4 y termine con este experimento. es el tipico Hello World, en este caso el nuestro mundo ;-)

El experimento se trató de ver como se comportaban dos texturas una arriba de otra. lo que hice fue crear dos primitivas de, dos esferas, una esfera minimamente más grande que la otra. Luego le apliqué una textura distinta a cada una.  finalmente agregue una particulas con un bitmap que simula ser una extrella.

Como toque final puse un onEnterFrame para renderizar la escena, mientras muevo giro en el eje de la Y ambas esferas a velocidades distintas y tambien muevo minimamente las particulas. Es bastante pesado para el procesador, pero no pain no gain.

Esto requiero Flash player 9

acá dejo el código:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
package {
import flash.display.BitmapData;
import flash.events.Event;
 
import org.papervision3d.core.math.Number3D;
import org.papervision3d.materials.special.MovieParticleMaterial;
 
import org.papervision3d.core.geom.Particles;
import org.papervision3d.core.geom.renderables.Particle;
import org.papervision3d.lights.PointLight3D;
import org.papervision3d.materials.BitmapMaterial;
import org.papervision3d.materials.shaders.GouraudShader;
import org.papervision3d.materials.shaders.ShadedMaterial;
import org.papervision3d.materials.shaders.Shader;
import org.papervision3d.materials.special.BitmapParticleMaterial;
import org.papervision3d.materials.special.ParticleBitmap;
import org.papervision3d.materials.special.ParticleMaterial;
import org.papervision3d.objects.primitives.Sphere;
import org.papervision3d.objects.special.ParticleField;
import org.papervision3d.view.BasicView;
 
[SWF (width="450", height="300", backgroundColor="0x000000", frameRate="30")]
 
public class earth extends BasicView
{
 
public var sphere:Sphere;
public var sphere2:Sphere;
 
public var light : PointLight3D;
 
public var shader : Shader;     
 
public var stars : ParticleField;
public var cloudMaterial : BitmapMaterial;
 
[Embed (source="/../assets/Earth.jpg")]
private var EarthMap : Class;
 
[Embed (source="/../assets/star.png")]
private var particleBitmap : Class;
 
[Embed (source="/../assets/earthcloudmap.png")]
private var CloudMap : Class;
 
public var particles : Particles;
public var particle : Particle
public var counter : int = 0 ;
 
public function earth()
{
super(500,400);
 
var earthbmp:BitmapData = new EarthMap().bitmapData;
var earthmaterial:BitmapMaterial = new BitmapMaterial(earthbmp);
 
var clouds : BitmapData = new CloudMap().bitmapData;
 
// luz
light = new PointLight3D();
light.x = 300;
light.y = 300;
 
// tipo de shader que uso...
 
shader = new GouraudShader(light, 0xFFFFFF,0x404040)
 
// y el material.
var shadedmaterial:ShadedMaterial = new ShadedMaterial(earthmaterial, shader);
shadedmaterial.smooth=true;
 
//creo la primer esfera, la tierra
sphere = new Sphere(shadedmaterial, 150,24,16);
 
//material para la nubes
cloudMaterial = new BitmapMaterial(clouds)
cloudMaterial.smooth = true;
cloudMaterial.doubleSided = false;
 
// creo la segunda esfera
sphere2 = new Sphere(cloudMaterial,160,24,16); 
 
//creo el sistema de particulas
particles = new Particles();
 
//saco el bitmap para crear un material que sera aplicado a cada particula
var particlematerial : BitmapParticleMaterial = new BitmapParticleMaterial(new particleBitmap().bitmapData,0.5,-32,-32);
 
//creo 500 estrellas y la dispongo en el espacio entre 1000 y -500
for(var i : int = 0; i< 500; i++)
{
var particle : Particle = new Particle(particlematerial, 1, (Math.random()*1000) -500, (Math.random()*1000) -500, (Math.random()*3000) -1500);
particles.addParticle(particle);
}
//agrego al sceneario el sistema de particulas
scene.addChild(particles);
 
//agrego la tierra
scene.addChild(sphere);
//agrego las nubes
scene.addChild(sphere2); 
 
//punto de interes de la camara
camera.fov = 30;
 
addEventListener(Event.ENTER_FRAME, enterFrame);             
 
}
 
public function enterFrame(e:Event) : void
{
counter++;
 
sphere.yaw(-1);
sphere2.yaw(-0.5);
particles.yaw(-0.01);
particles.pitch(-0.01);
 
//camera.x = Math.sin(counter*0.02) * 2000;  si quieren que sea automatico en vez de seguir el mouse lo pueden hacer con una onda senoidal
camera.x = ((320-mouseX)*0.01) * 2000;
singleRender();
 
}
 
}
}

Video full screen en flash

La semana pasada tuve un par de trabajos en los que requeria utilizar un video de flash como fondo y arriba de eso un sitio html puro. Asi que la idea de este mini tutorial es mostrar lo facil que es hacer que el video en flash tome el 100 porciento de la pantalla y se redimencione cuando se cambia el tamano de la pantalla.

1
2
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align = StageAlign.TOP_LEFT;

Con la primer linea especificamos que el tamano de la aplicacion flash tiene que se fija y que se mantiene fija incluso si cambia el tamano del explorador.
La segunda linea especifica que el escenario este alineado en la esquina superior izquierda.

1
2
3
var _netCon :NetConnection = null;
var _netStr :NetStream = null;
var _video :Video = null;

NetConnection es un objecto que podemos describir como un tubo entre el cliente y el servidor.

La clase Video muestra un video en la aplicacion sin incrustarlo en el swf. Digamos lo reproduce en un contenedor mediante streaming.

1
2
3
4
5
function SetupNetConnection() {
 _netCon = new NetConnection();
 _netCon.addEventListener(NetStatusEvent.NET_STATUS, NetStatus, false, 0, true);
 _netCon.connect(null);
}

Bueno, yahemso creado la conexion y agredado un listener que monitorea el estado de la conexion. el argumento null significa que no estamos conectando a un Flash media server sino que hacemos streaming de un archivo que reside en un servidor normal.

Ahora vamos a crear el stream que vamos a usar par ver el video mediante el objeto NetConnection y vamos a escuchar su estado mediante listener de ese mismo objeto.

1
2
3
4
5
6
7
8
9
10
11
12
function SetupNetStream() {
 var $customClient:Object = new Object();
$customClient.onMetaData = onMetaData;
_netStr = new NetStream(_netCon);
 _netStr.client = $customClient;
_netStr.addEventListener(NetStatusEvent.NET_STATUS, NetStatus, false, 0, true);
_video = new Video();
 _video.attachNetStream(_netStr);
 _video.smoothing = false;
 addChild(_video);
_netStr.play("video.flv");
 }

La funcion onMetaData va ser llamada tan pronto como el objeto NetStream obtenga informacion del archivo FLV.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
 
function onMetaData($info:Object):void {
 
}
 
function NetStatus($e:NetStatusEvent) {
 
switch ($e.info.code)   {
 
case "NetConnection.Connect.Success":
SetupNetStream();
break;
 
case "NetStream.Play.Stop":
_netStr.seek(0);
 }
}
 
 
 
function ResizeAndPosition($e:Event):void
{
_video.width = stage.stageWidth;
_video.height = stage.stageHeight;
}
 
stage.addEventListener(Event.RESIZE, ResizeAndPosition, false, 0, true);
 
ResizeAndPosition(null); 
 
SetupNetConnection();

Y el HTML que contrendria el player sería el siguiente:

1
2
3
4
<!--
*{ margin:0; padding:0; }
-->
<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="100%" height="100%" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="src" value="source.swf" /><embed type="application/x-shockwave-flash" width="100%" height="100%" src="source.swf"></embed></object>