Etiquetas: threshold
No sé si le servirá a alguien, pero hoy entrenando se me ha ocurrido hacer esto y creo que puedo tener alguna aplicación interesante.
Se trata de recortar una imagen en cuadrados, haciendo que los recortes afecten solo a los pixels no transparentes de la imagen, utilizando threshold y Bitmapdata.
Primero dividimos la imagen en cuadrados, y comprobamos si los cuadrados contienen algún pixel no vacío (es decir, que no sea transparente). Si el cuadrado no está vacio, creamos un botón con el trozo de imagen que le corresponde, y si no no.
Por último, en los botones que hemos creado, mostramos solo el handCursor cuando el pixel sobre el que está el ratón no es transparente.
Como a veces es un poco difícil imaginar como van a afectar a su aspecto las transformaciones en las propiedades de los elementos en 3d, me he hecho esta mini-aplicación con Sliders para ver como se muestra un plano al rotarlo sobre sus tres ejes.
Espero que a alguien más le sea útil, dejo los fuentes (está hecho con Papervision GreatWhite) por si queréis modificar otras propiedades.
Etiquetas: RegExp
Esta función utiliza una expresión regular para comprobar si una cadena es un email válido.
La expresión regular no la he construido yo, pero no puedo citar la fuente porque la he visto en muchos foros de actionscript, en castellano e inglés. La función en cuestión es esta:
function emailValido(email:String):Boolean{
var emailExpression:RegExp = /^[a-z][\w.-]+@\w[\w.-]+\.[\w.-]*[a-z][a-z]$/i;
return emailExpression.test(email);
}Y estos serían algunos resultados:
@hotmail.com: false
pepe@hotmail.: false
paco@hotmail.hola.com: true
www.hotmail.com: false
paco@hola@hotmail.com: false
carmen@hotmail.com: true
Etiquetas: System totalMemory
Podemos comprobar cantidad de memoria utilizada por Flash Player mediante la propiedad System.totalMemory, que devuelve el valor en bytes.
Por ejemplo, si queremos ver el valor en KBs de la memoria utilizada por nuestra aplicación, pondríamos:
import flash.system.System;
trace(System.totalMemory / 1024 + " KBs")
Etiquetas: BitmapData Bitmap smoothing mask drawCircle
En este ejemplo voy a tratar de explicar como se hace el "Efecto lupa" en Flash, con Actionscript 3.0.
Para simplificar voy a explicar la teoria basándome en una imagen que tengo en un MovieClip el escenario. Por supuesto esto se puede modificar para cargar imágenes externamente o como se necesite.
Los pasos que tenemos que seguir para crear el "efecto lupa" son estos:
-Crear una copia del MovieClip en BitmapData, y ponerla por encima a una escala mayor que el original:
//Creo un pantallazo del clip, lo pongo con una escala == zoomvar myBitmapData:BitmapData = new BitmapData(clip.width, clip.height);
myBitmapData.draw(clip);
var bmp:Bitmap = new Bitmap(myBitmapData);
bmp.smoothing = true;
contenedor.addChild(bmp);
contenedor.scaleX = contenedor.scaleY = zoom;
addChild(contenedor);
-Poner a la copia una máscara circular, de manera que solo se vea el trozo de imágen tapado por la máscara:
//Le pongo una mascara del tamaño t al contenedormascara.graphics.beginFill(0x000000, 1);
mascara.graphics.drawCircle(0, 0, t);
contenedor.mask = mascara;addChild(mascara);
-Añadimos un evento enterframe. Dentro de la función del evento vamos a mover la máscara siguiendo al ratón, y a recolocar la "copia grande":
addEventListener(Event.ENTER_FRAME,renderizar)
En la función del evento tenemos que mover la máscara para que siga al ratón, y recolocar la imagen grande para que el trozo que se vé sea el que corresponde a la imagen pequeña. La función es cuestión es esta:
private function renderizar(e:Event):void {
//Calculo el porcentaje que tengo que mover el pantallazovar porcentajeX = clip.mouseX / clip.width;
var porcentajeY = clip.mouseY / clip.height;
//Recoloco el contenedorcontenedor.x = -(contenedor.width - clip.width) * porcentajeX
contenedor.y = -(contenedor.height - clip.height) * porcentajeY
//Muevo la mascaramascara.x = escenario.mouseX;
mascara.y = escenario.mouseY;
}Adjunto fuentes con todos los materiales, por si queda alguna duda.
Etiquetas: mouseChildren
Una de las trampas que me encontré cunado empecé con Actionscript 3.0 era esta:
-Creaba un MovieClip con un campo de texto dinámico dentro (por ejemplo para el botón de un menú).
-Le añadía un evento de ratón y ponia su propiedad buttonMode como true.
Resultado: no se veía el handCursor (la mano típica al hacer over sobre un botón) cuando ponía el ratón encima.
En aquel momento, para solucionar el inconveniente (estaba haciendo unos cambios delante del cliente), puse un botón transparente dentro del MovieClip, por encima del resto de elementos, de tal manera que al hacer over sobre el clip se hacia over sobre el botón y se mostraba el handCursor. Mas tarde, pude investigar un poco, y descubrí que lo que pasaba era que el campo de texto dentro del clip "interfería" con los eventos de ratón, y por eso no se mostraba "la mano".
Para solucionarlo, podemos utilizar la propiedad mouseChildren de los DisplayObjectContainer, que determina si los elementos secundarios de un objeto están habilitados para ratón. Su valor predeterminado es true.
En Actionscript 3.0 disponemos de dos operadores para verificar tipos: "as" e "is". Es decir, con estos operadores podemos comprobar, por ejemplo, si un elemento del escenario es de tipo Sprite, o si una variable es de tipo Number.
Para ver como funcionan estos dos operadores voy a utilizar un escenario sobre el que tengo 3 MovieClips de la clase "Cuadrado", que extiende de MovieClip, y 3 MovieClips de la clase "Circulo", que también extiende de MovieClip.
El operador is
Permite comprobar si una variable o expresión forma parte de un tipo de datos. No solo verifica si un objeto es una instancia de la clase especificada, sino también si es una subclase de ella o implementa la misma interfaz.
Por ejemplo, si en el escenario que hemos propuesto ponemos:
for(var i:uint = 0; i < numChildren; i++){
if (getChildAt(i) is DisplayObject) {
getChildAt(i).alpha = .1
}}Obtenemos:
Como vemos, "parpadean" círculos y cuadrados, ya que todos son instancias de clases que heredan de DisplayObject. Sin embargo, si ponemos:
for(var i:uint = 0; i < numChildren; i++){
if (getChildAt(i) is Cuadrado) {
getChildAt(i).alpha = .1
}}
vemos que solamente parpadean los cuadrados, ya que los circulos no pertenecen a la misma clase ni heredan de "Cuadrado".
El operador as
También permite comprobar si un elemento es miembro de un tipo de datos. Sin embargo, en lugar de devolver true o false, devuelve el valor de la expresión en lugar de true, y null en lugar de false. Por ejemplo:
trace(miCirculo as Circulo) //Devuelve: [object Circulo]
trace(miCirculo as Sprite) //Devuelve: [object Circulo]
trace(miCirculo as Cuadrado) //Devuelve: null
Etiquetas: URLLoader URLRequest currentTarget
Este ejemplo intenta mostrar una forma básica de hacer un menú dinámico con Flash y XML. La misma teoria que se aplica aquí para crear los elementos del menú, se puede aplicar en la creación, por ejemplo, de una galeria de imágenes o videos.
La idea es hacer un menú cuyos elementos se crean a partir de los nodos de un XML. De esta forma se hace más sencillo el mantenimiento del menú, ya que por ejemplo para añadir un botón solo habría que añadir un nuevo nodo con los contenidos necesarios. El XML que vamos a utilizar es este:
<?xml version="1.0" encoding="utf-8" ?><data> <elementos> <elemento><titulo>Google</titulo>
<enlace>http://www.google.com</enlace>
</elemento> <elemento><titulo>Yahoo</titulo>
<enlace>http://www.yahoo.com</enlace>
</elemento> <elemento><titulo>Altavista</titulo>
<enlace>http://www.altavista.com</enlace>
</elemento> <elemento><titulo>Lycos</titulo>
<enlace>http://www.lycos.com</enlace>
</elemento> </elementos></data>Vemos que cada elemento tiene un título, que vamos a poner en el texto del botón, y un enlace, que es la url que vamos a cargar al hacer click en el botón.
Una vez que tenemos el XML, vamos a flash y creamos el botón que vamos a utilizar para crear el menú. En este caso es un fondo blanco con un campo de texto dinámico llamado "Texto_txt". Una vez creado pulsamos con el botón derecho en el símbolo que tenemos en la biblioteca y seleccionamos "Vinculación". Tenemos que asociar el botón a la clase ElementoMenu, que es el nombre de clase que vamos a utilizar para crear los botones.

Ahora vamos a cargar el XML. Creamos un URLLoader, añadimos los eventos, y creamos las funciones de carga y error. Se puede ver el proceso de carga más detallado en el
for (var i:uint = 0; i < datos.elementos.elemento.length(); i++) {
}En cada "vuelta" del for, vamos a crear un botón, rellenamos su campo Texto_txt con el nodo titulo, y almacenamos en una variable dentro del botón el valos del nodo enlace. Lo colocamos en "y" descendente según avanzamos para que salgan uno debajo de otro, y por último le añadimos un evento click que llama a la función navegar:
boton = new ElementoMenu();
boton.Texto_txt.text = datos.elementos.elemento[i].titulo;
boton.enlace = datos.elementos.elemento[i].enlace;
boton.y = i * 25
boton.buttonMode = true;
boton.mouseChildren = false;
boton.addEventListener(MouseEvent.CLICK, navegar);
addChild(boton);
Ahora, cada vez que hagamos click en un botón, se ejecutará la función navegar. En esta función recogemos el valor de la variable que hemos almacenado en enlace dentro del botón, por medio de currentTarget:
private function navegar(e:MouseEvent):void {
navigateToURL(new URLRequest(e.currentTarget.enlace), "_blank");
}Espero haberlo explicado de una manera fácil. Para cualquier duda podéis utilizar los comentarios.
ESPECIFICACIONES
Lenguaje: Actionscript 3.0 con Away3D y XML
Compatibilidad: Flash Player 9 o superior
Peso: 125KB
Etiquetas: complexIntersectionRectangle hitTestObject
La función hitTestObject(obj:DisplayObject) evalúa un objeto para comprobar si choca con el objeto obj. Por ejemplo, si tenemos dos objetos "Item1_mc" e "Item2_mc", podemos comprobar si chocan con:
Item1_mc.hitTestObject(Item2_mc)
Esta función, tiene el inconveniente de que comprueba los choques entre los contenedores rectangulares de los objetos. Por ejemplo:

por tanto, sin queremos comprobar las colisiones entre dos objetos no rectangulares, puede devolver valores que aparentemente no son correctos. Aquí tenemos un ejemplo en Flash:
Si queremos utilizar colisiones a nivel de pixel, podemos crear un objeto bitmapData, superponer los dos objetos en el objeto bitmapData con un filtro de color cada uno, y comprobar si hay pixels que tienen el color de la combinación de filtros utilizados. En el blog de
HitTest.complexHitTestObject(Item1_mc,Item2_mc)
Y si queremos recibir el rectángulo de colisión:
var rect:Rectangle = HitTest.complexIntersectionRectangle(Item1_mc,Item2_mc);
El resultado, sería este:
Los fuentes, y la clase HitTest de tink, tras el salto.