Tutorial de la librería Ming para PHP

Iniciado por дٳŦ٭, 28 Marzo 2007, 05:15 AM

0 Miembros y 1 Visitante están viendo este tema.

дٳŦ٭

Tutorial Ming

¿Qué es Ming?
Ming es una librería C de código abierto (LGPL) que escribe películas SWF ("Flash"). También es un juego de envoltorios para los lenguajes de script más populares: PHP, Python, y Ruby.

Ming soporta casi todas las características de Flash 4, incluyendo: formas, gradientes, bitmaps (pngs y jpegs), transformaciones ("cambio de forma"), texto, botones, acciones, símbolos gráficos ("clips de película"), soporte audio mp3, y las transformaciones de color. La única característica que está haciendo falta es los eventos de sonido.

Además, Ming no tiene absolutamente nada que ver con MNG, el descendiente animado de PNG. Los dos se usan para animación web, ambos son declarados "ming", pero sólo uno se usa para hacer las engorrosas películas flash.

Dibujando
El objeto fundamental en una película flash es una forma. O, en Ming, una SWFShape. En php, instancia un objeto SWFShape con la simple expresión:

Código (php) [Seleccionar]

<?php
New SWFShape();
?>



Aunque la librería Ming está escrita en código C plano, está diseñada para ser utilizada en un ambiente orientado a objetos; por consiguiente, en PHP tu puedes acceder a las funciones de dibujo de Ming mediante el objeto SWFShape. Para dibujar un cuadrado rojo de 400 unidades en cada lado con una anchura de línea de 20 unidades haz:

Código (php) [Seleccionar]

<?php
$s 
= new SWFShape ();
$s->setLine(200xff00);
$s->drawLineTo(4000);
$s->drawLineTo(400400);
$s->drawLineTo(0400);
$s->drawLineTo(00);
?>



Primero, una nota acerca de las unidades: la especificación flash indica una escala de veinte unidades por pixel, así, el cuadrado generado mediante el código anterior tendría 20 pixeles de lado y una línea de un pixel. Sin embargo, esta escala no es forzada en ninguna parte; la escala depende únicamente del tamaño que tu especifiques cuando insertes la película en tu código html y del tamaño del marco que establezcas dentro de la película (lo puedes cambiar después). Nosotros podríamos haber dibujado el cuadrado también de 20 unidades con una línea de 1 unidad. De cualquier modo, nosotros conseguimos el mismo cuadrado si escalamos la película junto con esta.

Ahora, probablemente notaste que el método "drawLineto" únicamente recibe dos argumentos considerando que una línea normal tiene cuatro parámetros, estos son una coordenada "x" y una coordenada "y" para ambos puntos finales. Y probablemente concluiste que esto significa que el dibujo en Ming es basado en pluma; es decir, el objeto forma guarda una referencia de la ubicación de la pluma imaginaria en la superficie del dibujo, y los comandos de dibujo referencian y afectan implícitamente la ubicación de la pluma. Esto debió ser suficiente para que aprendieras que drawLineTo tiene una función drawLine relacionada que usa posicionamiento relativo en lugar de coordenadas absolutas. En otras palabras, las funciones de dibujo anteriores podrían reemplazarse por:

Código (php) [Seleccionar]

<?php
$s
->drawLine(4000);
$s->drawLine(0400);
$s->drawLine(-4000);
$s->drawLine(0, -400);
?>



y obtendríamos el mismo cuadrado rojo.

El método setLine recibe cuatro (o cinco) los argumentos: el ancho de la línea, y el rojo, verde, y azul (y opcionalmente la transparencia), componentes del color de la línea. Cuando fijas el estilo de línea, este se aplica a todos los comandos de dibujo subsecuentes hasta que cambie de nuevo el estilo de línea con setLine. Para no utilizar estilo de línea (que, a propósito, es el valor por defecto para las formas), simplemente fija el ancho en cero.

Finalmente, estos son dos de los comandos de dibujo más útiles:

Código (php) [Seleccionar]

<?php
$s
->movePenTo(x,y);
?>



Mueve la pluma a las coordenadas (x,y) sin dibujar línea (y movePen es su primo más cercano), mientras que:

Código (php) [Seleccionar]

<?php
$s
->drawCurveTo(cxcyel hachael ay);
?>



Dibuja una curva cuadrática bezier simple desde la ubicación actual de la pluma hasta el punto (ax,ay) usando el punto (cx,cy) como un punto de control. Como esperamos, drawCurve hace lo mismo, excepto que usa coordenadas relativas a la posición actual de la pluma.

Estilos De Relleno

Esto puede llegar a ser una cosa muy confusa acerca de Ming, de manera que haré algunas aclaraciones antes. El formato swf está diseñado para ser compacto y fácil de utilizar, esto significa que las optimizaciones en los atributos de formas son hechas en el acto, no por el reproductor. Y que significa eso, significa que las formas se dibujan de manera tal que nuestros cerebros inferiores humanos no lo perciben xDD.

Específicamente, cuando estás definiendo una forma debes decirle al reproductor qué porción del espacio entre las líneas debe quedar rellena. La razón para esto (y me siento libre de saltar este párrafo, y no estará en el ejemplo) es que el reproductor flash dibuja la forma mientras verifica las líneas, y como este recorre cada borde en su definición de forma, revisa los registros de relleno del lado izquierdo y del lado derecho para ver que estilo de relleno se está aplicando sobre la línea. Si el borde es más denso al norte que al sur, el explorador de línea se esta moviendo al lado derecho del borde mientras cruza sobre la línea desde la derecha hacia la izquierda, así empieza rellenando con el estilo de relleno del borde del lado derecho. Si el borde fuera más denso al sur que al norte, usaría el estilo relleno del lado izquierdo.

Fija el relleno del lado izquierdo y del lado derecho mediante los métodos setRightFill y setLeftFill. Éstos simplemente trabajan como setLine, se aplican a todos los bordes subsecuentes hasta que cambie el estilo de relleno de nuevo. setRightFill y setLeftFill reciben un argumento, un objeto SWFFill.

SWFFill
SWFFill abarca rellenos sólidos, gradientes, y mapas de bits. En lugar de instanciar un SWFFill directamente, solicitas un SWFShape para que se cree uno para utilizar el método addFill de SWFShape. La lógica detrás de esto es que el relleno sólo tiene significado dentro del contexto de la forma, y veremos por qué brevemente. addFill viene en una variedad de formatos, uno para cada uno de los tipos de relleno que puede crear: colores sólidos, mapas de bits, y gradientes.

Código (php) [Seleccionar]

<?php
$f 
$s->addFill(rg[,a]);
?>



Crea un relleno de color sólido con los componentes especificados rojo, verde, y azul (y opcionalmente transparencia). Dibujemos un cuadrado rojo relleno:

Código (php) [Seleccionar]

<?php
$s 
= new SWFShape ();
$f $s->addFill(rg[,a]);
$s->setRightFill($f);
$s->movePenTo(-200, -200);
$s->drawLine(4000);
$s->drawLine(0400);
$s->drawLine(-4000);
$s->drawLine(0, -400);
?>



Nosotros usamos setRightFill aquí porque dibujamos el contorno del cuadrado en sentido de las manecillas del reloj, así, el interior del cuadrado se rellena desde el borde del lado derecho. Si hubiéramos dibujado el cuadrado un sentido contrario a las agujas del reloj, habríamos usado el método setLeftFill.

SWFBitmap
Para agregar un relleno de mapa de bits a una forma, usamos:

Código (php) [Seleccionar]

<?php
$f 
$s->addFill(bitmap [, flags]);
?>



Donde el mapa de bitas es un objeto SWFBitmap, creado con,:

Código (php) [Seleccionar]

<?php
$b 
= new SWFBitmap(filename [, maskname]);
?>



Donde filename es el nombre de un jpeg o un archivo dbl. Un archivo "dbl" es un fichero png convertido mediante la utilidad "png2dbl" el cual Ming puede procesar más fácilmente. (Estas conversiones son un "rasgo" de ming que usted encontrará de vez en cuando. La única razón por la que le pedimos que pase por estos pasos extra es para no tener que utilizar varias bibliotecas de apoyo como libpng para usar ming. Algún día autoconf ordenará este lío y será capaz de leer pngs, gifs y ttfs con una simple llamada a una función.) El programa png2dbl es incluido en el paquete fuente de Ming. También sea consciente de que Ming actualmente puede procesar básicamente archivos comprimidos jpeg. No trabaja la lectura básica, optimizada y progresiva de jpegs.

El argumento opcional mascara especifica un archivo "msk" que agrega un canal de transparencia a un mapa de bits jpeg. El archivo msk se crea con "gif2mask", también incluido en el paquete fuente Ming. El archivo gif de entrada debe ser del mismo tamaño del jpeg. El mapa de bits resultante es opaco donde la mascara de imagen es blanca, semi-transparente donde es gris, y totalmente transparente donde es negra. Es decir, el valor de los pixeles del archivo de máscara se usa como el nivel de transparencia para los pixeles de la imagen jpeg.

El argumento flags puede ser SWFFILL_CLIPPED_BITMAP o SWFFILL_TILED_BITMAP, e indica si los mapas de bits deben seguir una secuencia (qué es el valor por defecto, en lugar del argumento flags) o deben superponerse, respectivamente.

SWFBitmap también tiene métodos para obtener las dimensiones de su imagen:

Código (php) [Seleccionar]

<?php
$b
->getWidth ();
$b->getHeight ();
?>



Qué le permite dibujar un rectángulo del mismo tamaño de tu mapa de bits, que de hecho es bastante útil.

SWFGradient

Los gradientes, como ya bien sabes, son las transiciones uniformes entre colores. En Flash, los gradientes pueden ser lineales o radiales, pueden contener hasta ocho colores, y pueden tener transparencia. Para construir una relleno de gradiente, primero cree un objeto SWFGradient:

Código (php) [Seleccionar]

<?php
$g 
= new SWFGradient ();
?>



Entonces fija los valores iniciales mediante:

Código (php) [Seleccionar]

<?php
$g
->addEntry(ratiorg[,a]);
?>



Donde ratio es un número entre 0 y 1, y r, g, y b (y opcionalmente a) especifican los componentes rojo, verde, y azul (y transparencia) de la ubicación especifica del gradiente. Debes (tienes que hacerlo) agregarlos en orden de incremento de ratio.

Por ejemplo, así es cómo creas un simple gradiente negro a blanco:

Código (php) [Seleccionar]

<?php
$g 
= new SWFGradient ();
$g->addEntry(0000);
$g->addEntry(1.00xff0xff0xff);
?>



Finalmente, tu agrega el gradiente a su forma con:

Código (php) [Seleccionar]

<?php
$f 
$s->addFill(gradient [, flags]);
?>



Donde gradient es su recién creado SWFGradient y las banderas son SWFFILL_RADIAL_GRADIENT para un (sorpresa!) gradiente radial, o SWFFILL_LINEAR_GRADIENT para el viejo y aburrido gradiente lineal. Si no se proporcionan banderas, el gradiente por defecto es lineal.

Transformando su relleno

Suponiendo que para ti el nuevo gradiente y relleno con mapas de bits no son muy divertidos en su estado por defecto, nosotros amablemente hemos proporcionado los siguientes métodos:

Código (php) [Seleccionar]

<?php
$f
->moveTo(x,y);
?>



Mueve el relleno a las coordenadas (el x,y):

Código (php) [Seleccionar]

<?php
$f
->rotateTo(deg);
?>



Gira el relleno deg grados, y:

Código (php) [Seleccionar]

<?php
$f
->scaleTo(xscale [, yscale]);
?>



Fija la escala de relleno en xscale en dirección x y yscale en dirección y. Si sólo se proporciona un argumento, ambas dimensiones son escaladas por xscale. Por último:

Código (php) [Seleccionar]

<?php
$f
->skewXTo(s);
$f->skewYTo(s);
?>



Sesga el relleno por s en el eje x o en el eje y. Una s de 0 no es sesgada, una s de 1.0 es sesgada a un ángulo de 45 grados.

Animación

Ahora que hemos definido una forma, seguro nos gustaría poder verla. Para hacer esto, necesitamos un lienzo en el cual dibujar. Ese lienzo es el venerado SWFMovie.

Código (php) [Seleccionar]

<?php
$m 
= new SWFMovie ();
?>



Crea un nuevo objeto SWFMovie, base para la animación. Nosotros podemos usar

Código (php) [Seleccionar]

<?php
$m
->setBackground(rgb);
?>



Para fijar el color del fondo:

Código (php) [Seleccionar]

<?php
$m
->setRate(rate);
?>



Para fijar el frame rate (en frames por segundo), y:

Código (php) [Seleccionar]

<?php
$m
->setDimension(widthheight);
?>



Para fijar el tamaño de la película. Acuerdate lo que dijimos acerca del escalamiento: el tamaño de la presentación establecido en su html determina el tamaño real. Las dimensiones de la película fijadas aquí determinan la escala en la que sus formas serán dibujadas. Si usted fija el tamaño de su película en 3200x2400 y lo empotra en una página html de 320x240, sus formas serán 1/10 del tamaño que usted especificó en sus comandos de dibujo.

Tu forma no se dibujará en la película hasta que usted cree una instancia de ella llamando:

Código (php) [Seleccionar]

<?php
$i 
$m->add($s);
?>



Este método crea una instancia de la forma en la película y retorna una referencia con la que puede alterar la apariencia de la instancia. Puedes, de hecho, agregar la misma forma a su película tantas veces como quieras (siendo razonable, claro) y usar los apuntadores retornados para referenciar cada uno individualmente.

Usar Ming para hacer películas flash es análogo a usar una cámara de movimiento: debes poner las formas en su lienzo, colóquelos como usted guste, pulse entonces el obturador para grabar el arreglo y avance al siguiente frame. Coloca:

Código (php) [Seleccionar]

<?php
$m
->nextFrame ();
?>



El paso "arreglo" es realizado llamando métodos proporcionados por el apuntador a la instancia (que se generó con el método add de SWFMovie, recuerdas?). Estos métodos son idénticos a los métodos de transformación que vimos en SWFFill, excepto que cada uno tiene una versión relativa que actúa en relación con la posición actual, escala, rotación, e inclinación. Por ejemplo:

Código (php) [Seleccionar]

<?php
$i
->moveTo(x,y);
?>



Mueve el objeto a las coordenadas (el x,y), mientras:

Código (php) [Seleccionar]

<?php
$i
->move(x,y);
?>



Desplaza el objeto con el vector (el x,y). El resto de los métodos son:

Código (php) [Seleccionar]

<?php
$i
->rotateTo(deg);
$i->rotate(deg);
$i->scaleTo(xscale [, yscale]);
$i->scale(xscale [, yscale]);
$i->skewXTo(s);
$i->skewX(s);
$i->skewYTo(s);
$i->skewY(s);
?>



Confio en que ya leiste la sección de transformación de rellenos y puedes deducir lo que hacen estos métodos ok?.

Tu también puedes quitar un objeto de la lista de despliegue si estás cansado de su fisonomía:

Código (php) [Seleccionar]

<?php
$m
->remove($i);
?>



Transformar Colores

Otra cosa divertida que podemos hacer es alterar el color del objeto xDDD:

Código (php) [Seleccionar]

<?php
$i
->addColor(rg[,a]);
$i->multColor(rg[,a]);
?>



El primer método agrega un valor constante a cada uno de los canales del objeto de despliegue: rojo, verde, y azul (y opcionalmente transparencia). El segundo multiplica los canales por los valores de escala dados.

Nota que estos valores pueden ser negativos; para invertir el canal azul de un objeto desplegado, tu utilizarías:

Código (php) [Seleccionar]

<?php
$i
->addColor(000xff);
$i->multColor(1.01.0, -1.0);
?>



Nota también que estos métodos no son conmutativos, así:

Código (php) [Seleccionar]

<?php
$i
->addColor(0xff00);
$i->addColor(00xff0);
?>



Fija el color agregado al verde, no al amarillo xDDD.


Finalmente

Cuando tengas todo listo, llama a Ming para enviar la película al navegador

Código (php) [Seleccionar]

<?php
header
('Content-type: application/x-shockwave-flash ');
$m->output ();
?>



El comando header hace que tu servidor web le diga al navegador del cliente que esto es, de verdad, una película flash.

Para un ejemplo rápido, hagamos que el cuadrado rojo que creamos previamente (inmóvil en $s para ahorrarle a mis dedos un poco de uso) el giro:

Código (php) [Seleccionar]

$m = new SWFMovie ();
$m->setDimension(800, 600);

$i = $m->add($s);
$i->moveTo(400, 300);

for($j=0; $jnextFrame ();<5; ++$j)

{

  $m->nextFrame();
  $i->rotate(15);
}

$m->nextFrame ();

header('Content-type: application/x-shockwave-flash');
$m->output ();


Nosotros estamos siendo terriblemente diestros aquí al permitir que el ciclo de animación vuelva al principio después de rodar el pobre cuadrado sólo 75 grados ya que el primer frame es idéntico a una rotación de 90 grados. Verdaderamente muy inteligentes nosotros xDDD.

El texto

Primero, carga una fuente:

Código (php) [Seleccionar]

<?php
$f 
= new SWFFont(filename);
?>



Donde filename es un archivo fdb. (Sí, otro formato de archivo ad hoc - crea archivos fdb desde las plantillas de archivo flash swt con la utilidad makefdb de Ming.) El objeto SWFFont le proporciona alguna información métrica de la fuente:

Código (php) [Seleccionar]

<?php
$f
->getAscent ();
$f->getDescent ();
$f->getLeading ();
$f->getWidth(string);
?>



Cada método produce la métrica solicitada como un número, escalado a una altura de fuente de 1024. A menos que esté desplegando tu texto a una altura de 1024, necesitarás multiplicar el número retornado por alto/1024.

Puedes ver el manejo de texto mediante:

Código (php) [Seleccionar]

<?php
$t 
= new SWFText ();
$t->setFont($f);
$t->setHeight(240);
$t->setColor(0xff00);
$t->moveTo(10,250);
¡$t->addString ("no, por favor!  no mis dedos de los pies"!);
?>



Agrega un SWFText a tu película con el método add de SWFMovie animarlo con el apuntador retornado, así como con las formas.

SWFButton

Los botones pueden tener varios formas asociadas con ellos, el appearace general del botón; un encima de la forma, desplegó cuando el ratón mueve encima del botón; un baje la forma, desplegó cuando los clics del usuario abajo en el botón; y una región del golpe que nunca se muestra pero define el área del clickable del botón.

Crea un botón con:

Código (php) [Seleccionar]

<?php
$b 
nuevo SWFButton ();
?>



Y agrega una forma al botón declara con:

Código (php) [Seleccionar]

<?php
$B
->ADDSHAPE($SSWFBUTTON_HIT SWFBUTTON_DOWN SWFBUTTON_OVER SWFBUTTON_UP);
?>



Nota que esto agrega la misma forma a todos los estados que los medios que el área del clickable está igual que el área arrastrado de la forma y que el botón parece el mismo cuando tienes el mouse encima de él, no muy divertido en absoluto xDDD. Los botones en nuestro ejemplo no serán los mono-cubos de diversión, o, pero nosotros haremos una región del golpe separada:

Código (php) [Seleccionar]

<?php
//haz una región del golpe para el botón
$hit nuevo SWFShape ();
$hit->setRightFill($hit->addFill(0,0,0));
$hit->movePenTo(-600, -30);
$hit->drawLine(12000);
$hit->drawLine(060);
$hit->drawLine(-12000);
$hit->drawLine(0, -60);
?>



Sin esto, la región del golpe sería sólo el interior del texto del titular, qué simplemente sería raro. Ahora apretemos fuera esos botones:

Código (php) [Seleccionar]

<?php
for($i=0$isetFont($f);<$count; ++$i)
{
  
$t = new SWFText();
  
$t->
  
$t->setHeight(40);
  
$t->setColor(0,0,0);
  
$t->moveTo(-$f->getWidth($title[$i]) * (40/1024)/220);
  
$t->addString($title[$i]);
  
$b[$i] = nuevo SWFButton ();
  
$B[$I]->ADDSHAPE($HITSWFBUTTON_HIT);
  
$B[$I]->ADDSHAPE($TSWFBUTTON_OVER SWFBUTTON_UP SWFBUTTON_DOWN);
  
$b[$i]->addAction(new SWFAction ("el getURL (' $url[$i] ', ' el popup')";),SWFBUTTON_MOUSEUP);
}
?>



Así ahora que nosotros tenemos nuestros botones construidos, animémoslos. Estos dos archivos contienen funciones que realizan las varias transiciones entre los titulares:

Código (php) [Seleccionar]

<?php
include (' infuncs.php');
include (
' outfuncs.php');
?>



Por ejemplo, la función siguiente de infuncs.php resbala el botón de la izquierda mientras la transparencia completa a totalmente opaco:

Código (php) [Seleccionar]

<?php
slideleftin
($movie de la función$shape)
{
  
$i $movie->add($shape);

   for(
$j=0$jmoveTo(600-($j-20)*($j-20), 30);<=20; ++$j)

  {

    
$i->
    
$i->multColor(1.01.01.0$j/20);
    
$movie->nextFrame ();
  }

  return 
$i;
}
?>



Todas las funciones en infuncs.php toman una película y una forma como los argumentos, y devuelve un caso de la forma en la película. Las funciones en outfuncs.php toman la película, la forma, y el caso creadas se aseguran que la lona está vacía cuando ellos vuelven.

Las funciones se listan en las series $infuncs y $outfuncs, mientras permitiéndonos formar, sin referente al php principal codifique en absoluto. Aquí es el pedazo final de código que realiza la animación:

Código (php) [Seleccionar]

<?php
for($n=0$nnextFrame ();<4; ++$n)

{

  for(
$i=0$i<$count; ++$i)

  {

    
$infunc $infuncs[rand(0count($infuncs)-1)];

    
$instance $infunc($m$b[$i]);



    for(
$j=0$j<60; ++$j)

      
$m->

    
$outfunc $outfuncs[rand(0count($outfuncs)-1)];
    
$outfunc($m$b[$i], $instance);
  }
}

header ("Content-type: application/x-shockwave-flash");
$m->output ();
?>






Parte de este tutorial lo he tomado de un txt que encontre entre mis cosas xDD ni url ni autor tenia, lo he corregido y agregado algunas funciones.

Cabe aclarar que esta librería está en desarrollo, lo cuál nos sugiere que dentro algún tiempo (muy cercano) cambiará, quizá hasta el 100%.

Saludos

http://ming.sourceforge.net/

Librerías Php para SWF
http://foro.elhacker.net/index.php/topic,110909.0.html


Con sangre andaluza :)


Ertai

Que bueno!

No lo conocia, le pongo chincheta para los despistados como yo...  ;D
Si la felicidad se comprara, entonces el dinero sería noble.


void rotar_by_ref(int& a, int& b) {
   /* Quien dijo que no se podia sin una variable temporal? */
   *a = *a ^ *b;
   *b = *a ^ *b;
   *a = *a ^ *b;
}

дٳŦ٭

Cita de: Ertai en 28 Marzo 2007, 18:15 PM
Que bueno!

No lo conocia, le pongo chincheta para los despistados como yo...  ;D

Sí, es muy poco conocido y muy dificil de implementar pero qué chuladas salen.

Saludos  ;)


Con sangre andaluza :)


chunchillo

Realmente interesante, ahorita no tengo tiempo pero lo tendre en cuenta para un rato mas

Saludos y nos leemos por ahi

дٳŦ٭

Otra que podemos user es el método de leer xml generados por PHP e interpretados por Flash (swf), es por eso que ésta clase casi nunca es utilizada.

Dentro de poco pondré algunos ejemplos ya que ando en algo similar.

Saludos


Con sangre andaluza :)