Mas sobre Flash


Koala Technologies (koalatec.com)
En este tutorial mostraré un par de sencillos ejemplos en cuanto al uso de una de las novedades de Adobe Flash CS4 que mas me ha llamado la atención (en cuanto a ActionScript se refiere), estoy hablando de la adición del método DrawTriangles() a la clase Graphics.

Este método es muy útil al momento de crear figuras tridimensionales a partir de triángulos, así como también para modificar la apariencia de un bitmap (que explicare mas adelante), y en el mas sencillo de los casos dibujar una figura vectorizada (con forma de triangulo) similar a lo que harían el resto de los métodos de Graphics.

A continuación, el resultado final:

Content on this page requires a newer version of Adobe Flash Player.

Get Adobe Flash player


Arrastra los recuadros negros, para modificar la imagen.

Como podrás ver, el bitmap esta dividido por 2 triángulos rectángulos, unidos a través de sus hipotenusas formando un rectángulo. Explico a detalle como crearlo:

Aprendiendo la Teoria

Antes de hecharle un vistazo al código completo, pienso que es mas importante comprender la manera básica de como trabaja este.

Primero hay que imaginar que ya tenemos en nuestro escenario, un objeto bitmap sin mayor chiste, cuyo contorno esta formado por algún tipo de cuadrángulo al cual aplicaremos la deformación mas adelante:

Para ello vamos a dividirlo en un par de triángulos iguales, considerando las cuatro vértices propias del cuadrángulo y que son 3 vértices por cada triangulo nos quedarían faltando 2 puntos para completar la figura:

Por fortuna podemos optimizar ese paso, y evitarnos el tener que crear otros dos objetos adicionales definiendo como puntos en común P2 y P3 así ahorrándonos los 2 vértices que nos faltaban:

Para poder graficar y manejar texturas con drawTriangles() es necesario emplear las coordenadas U para el eje horizontal cuyo valor sera igual al ancho total de la imagen (x, width), y V para el eje vertical cuyo valor sera el de la altura total de la imagen (y, heigth).

Como ejemplo usando la siguiente imagen, el triangulo 1 (T1) estará formado por la unión de P1 (0, 0), a P2 (1, 0) para terminar en P3 (0, 1).


Ejemplo utilizando como puntos de coordenadas U, y V

Así mismo podemos definir cualquier triangulo sin batallar por el tamaño de la imagen ya que este sera definido por el tamaño total, en la siguiente imagen podemos ver un triangulo cuyos puntos estarán unidos por P1 (.5, 0), P2 (1, .25) y P3 (0, 1).

Comprendiendo la Practica

Si estabas esperando a ver el código fuente del primer ejemplo, te diré que jamas has estado tan cerca pero aun te falta llegar mas abajo.

Primero crearemos un triangulo rellenado con la bitmapData de un elemento en la biblioteca, instanciado como "Image" y utilizaremos la nueva Clase Vector para ello, no entraré mucho en eso.

graphics.clear(); // Borramos cualquier dibujo creado por graphics
graphics.beginBitmapFill(new Image(0,0)); // Indicamos que se use "Image" como color de relleno graphics.drawTriangles( // Comenzamos con el método a explicar
Vector.([10,10, 100,100, 10,300, 100,200]), // Linea A
Vector.([0,1,2, 1,3,2]), // Linea B
Vector.([0,0, 1,0, 0,1, 1,1])); // Linea C

Primero que nada en la linea A fijaremos las coordenadas dentro del escenario de cada punto, estos puntos estarán determinados a través del sistema de coordenadas (U, V) en la linea C tal y como ya explique arriba y finalmente en la linea B indicamos como trazar los triángulos a partir de cada punto que conforman la figura, cosa que también ya fue mencionada. Así se formara una figura similar a la siguiente:

Ahora, comprendido todo lo anterior me parece apropiado mostrar la clase fuente del primer ejemplo con todas sus explicaciones comentadas entre lineas, con algunas referencias hacia los ejemplos anteriores:

package
{
// Importamos todos los paquetes necesarios
import flash.geom.*;
import flash.events.Event;
import flash.events.TimerEvent;
import flash.events.MouseEvent;
import flash.display.Sprite;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.TriangleCulling;
import flash.display.MovieClip;
import flash.display.Graphics;
//
public class Main extends MovieClip {
// Este sera el tamaño de la imagen una vez cargada dentro del escenario
private var size:int = 260;
// Aqui se guardara la bitmapData, como su nombre indica sera el contenedor...
// ...cargado al centro del escenario
private var container:Sprite;
// La bitmapData sobre la cual trabajaremos
private var bitmapData:BitmapData;
// Los dos vectores que representaran los catetos y vertices al dibujar los Triangulos
private var vertices:Vector.;
private var catetos:Vector.;
// Estos seran los Sprites encargados de modificar la BitmapData...
// ...al igual que en los ejemplos anteriores se trataran de P1,P2,P3 y P4
private var P1:Sprite;
private var P2:Sprite;
private var P3:Sprite;
private var P4:Sprite;
//
public function Main():void
{
// Lo primero a hacer sera cargar el objeto bitmap de nuestra biblioteca
bitmapData = new bitmap(0, 0);
// Luego, creamos el contenedor de la BitmapData ya cargada...
container = new Sprite();
// ...y lo colocamos centrado en el escenario
container.x = (stage.stageWidth - bitmapData.width) /2;
container.y = (stage.stageHeight - bitmapData.height) /2;
addChild(container);
// Finalmente llamamos a estas dos funciones, que explicare mas adelante...
setPoints();
drawTriangle();
}
// A las siguientes dos funciones llegaran todos los listeners de cada punto...
// ...por lo que cumplen una importante funcion al querer arrastrar y modificar la bitmap
private function EventHandler(event:Event)
{
// Diferenciamos los eventos recibidos
switch(event.type)
{
// Detectamos el evento MouseUp
case MouseEvent.MOUSE_UP:
removeEventListener(MouseEvent.MOUSE_MOVE, EventHandler);
stopDrag();
//
default: drawTriangle();
}
}
private function startPointDrag(event:MouseEvent):void
{
addEventListener(MouseEvent.MOUSE_MOVE, EventHandler);
event.currentTarget.startDrag();
drawTriangle();
}
// Esta es la funcion que dividira la imagen cargada desde la bilioteca...
// ...en dos triangulos, de esto ya hablamos mas arriba
private function drawTriangle():void
{
vertices = new Vector.();
catetos = new Vector.();
// Señalamos los puntos que forman el Triangulo 1
vertices.push(P1.x, P1.y);
vertices.push(P2.x, P2.y);
vertices.push(P3.x, P3.y);
// ...y los del Triangulo 2
vertices.push(P2.x, P2.y);
vertices.push(P4.x, P4.y);
vertices.push(P3.x, P3.y);
// Una vez hecho eso, dividimos el cuadrangulo en dos triangulos
// Utilizando las coordenadas (U, V) tanto para el Triangulo 1
catetos.push(0, 0);
catetos.push(1, 0);
catetos.push(0, 1);
// ...como para el Triangulo 2
catetos.push(1, 0);
catetos.push(1, 1);
catetos.push(0, 1);
//
container.graphics.clear();
container.graphics.beginBitmapFill(bitmapData);
container.graphics.drawTriangles(vertices, null, catetos, TriangleCulling.NONE);
}
// Esta funcion esta encargada de acomodar los puntos P1~P4 y...
// ...agregarles sus respectivos listeners
private function setPoints():void {
P1 = newPoint();
P2 = newPoint();
P3 = newPoint();
P4 = newPoint();
// Fijamos cada uno de los puntos en los margenes de la imagen cargada...
// ...logrando que cuando utilizemos las coordenadas (U, V) estas queden...
// ...acomodadas en los limites debidos
P4.x = P2.x = bitmapData.width;
P4.y = P3.y = bitmapData.height;
// Añadimos todos los listeners necesarios para cada punto
P1.addEventListener(MouseEvent.MOUSE_DOWN, startPointDrag);
P2.addEventListener(MouseEvent.MOUSE_DOWN, startPointDrag);
P3.addEventListener(MouseEvent.MOUSE_DOWN, startPointDrag);
P4.addEventListener(MouseEvent.MOUSE_DOWN, startPointDrag);
stage.addEventListener(MouseEvent.MOUSE_UP, EventHandler);
}
// Esta funcion, llamada por "setPoints" dibuja los puntos P1~P4 a arrastrar
private function newPoint():Sprite {
var point:Sprite = new Sprite();
point.graphics.beginFill(0x000000);
point.graphics.drawRect(-5, -5, 10, 10);
point.graphics.endFill();
point.buttonMode = true;
//
container.addChild(point);
return point;
}
}
}

NOTA: Hay un pequeño detalle a tener en cuenta al utilizar este método sobre imágenes vectoriales, y es que al vaciar la imagen como relleno en un bitmap la rasteriza en el proceso, por lo que al dar un acercamiento muy grande los pixeles se harán evidentes.

|
This entry was posted on 10:31 and is filed under . You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.

1 comentarios:

On 27 de marzo de 2018, 1:46 , Unknown dijo...

ayok main tunggu apa lagi ambil bonus nya di bolavita...
www.Bolavita.org

 

Relacionados