Con el ejemplo de la luna giratoria animada se muestran estas técnicas para trabajar con objetos Bitmap y datos de imagen de mapa de bits (objetos BitmapData). El ejemplo crea una animación de una luna esférica giratoria utilizando una imagen plana de la superficie de la luna como datos de imagen sin procesar. Se muestran las siguientes técnicas:
-
Carga de una imagen externa y acceso a sus datos de imagen sin procesar.
-
Creación de una animación copiando píxeles de forma repetida de diferentes partes de una imagen de origen.
-
Creación de una imagen de mapa de bits estableciendo valores de píxel
Para obtener los archivos de la aplicación de este ejemplo, consulte
www.adobe.com/go/learn_programmingAS3samples_flash_es
. Los archivos de la aplicación de la luna giratoria animada se encuentran en la carpeta Samples/SpinningMoon. La aplicación consta de los siguientes archivos:
Archivo
|
Descripción
|
SpinningMoon.mxml
o
SpinningMoon.fla
|
Archivo principal de la aplicación en Flex (MXML) o en Flash (FLA).
|
com/example/programmingas3/moon/MoonSphere.as
|
Clase que realiza la funcionalidad de cargar, visualizar y animar la luna.
|
moonMap.png
|
Archivo de imagen que contiene una fotografía de la superficie de la luna, que se carga y se utiliza para crear la luna giratoria animada.
|
Carga de una imagen externa como datos de mapa de bits
La primera tarea importante que se realiza en este ejemplo es cargar un archivo de imagen externo, que es una fotografía de la superficie de la luna. La operación de carga se administra mediante dos métodos en la clase MoonSphere: el constructor
MoonSphere()
, donde se inicia el proceso de carga y el método
imageLoadComplete()
, que se llama cuando la imagen externa está completamente cargada.
La carga de una imagen externa es similar a la carga de un archivo SWF externo; ambos utilizan una instancia de la clase flash.display.Loader para realizar la operación de carga. El código real del método
MoonSphere()
que inicia la carga de la imagen se presenta del siguiente modo:
var imageLoader:Loader = new Loader();
imageLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, imageLoadComplete);
imageLoader.load(new URLRequest("moonMap.png"));
La primera línea declara la instancia de Loader denominada
imageLoader
. La tercera línea inicia realmente el proceso de carga llamando al método
load()
del objeto Loader, transmitiendo una instancia de URLRequest que representa la URL de la imagen que se va a cargar. La segunda línea configura el detector de eventos que se activará cuando la imagen se haya cargado por completo. Se debe tener en cuenta que el método
addEventListener()
no se llama en la propia instancia de Loader; en cambio, se llama en la propiedad
contentLoaderInfo
del objeto Loader. La propia instancia de Loader no distribuye eventos relacionados con el contenido que se está cargando. No obstante, su propiedad
contentLoaderInfo
contiene una referencia al objeto LoaderInfo que se asocia al contenido que se está cargando en el objeto Loader (la imagen externa en este caso). El objeto LoaderInfo proporciona varios eventos relacionados con el curso y la finalización de la carga de contenido externo, incluyendo el evento
complete
(
Event.COMPLETE
) que activará una llamada al método
imageLoadComplete()
cuando la imagen se haya cargado por completo.
Aunque el inicio de la carga de la imagen externa es una parte importante del proceso, es igualmente relevante saber qué hacer cuando finalice la carga. Tal y como se muestra en el código anterior, la función
imageLoadComplete()
se llama cuando se carga la imagen. La función realiza varias operaciones con los datos de imagen cargados, lo que se describe posteriormente. No obstante, para utilizar los datos de imagen, es necesario acceder a los mismos. Si se usa un objeto Loader para cargar una imagen externa, la imagen cargada se convierte en una instancia de Bitmap, que se asocia como objeto de visualización secundario del objeto Loader. En este caso, la instancia de Loader está disponible para el método del detector de eventos como parte del objeto de evento que se transmite al método como parámetro. Las primeras líneas del método
imageLoadComplete()
se presentan del siguiente modo:
private function imageLoadComplete(event:Event):void
{
textureMap = event.target.content.bitmapData;
...
}
Observe que el parámetro del objeto de evento se denomina
event
y es una instancia de la clase Event. Todas las instancias de la clase Event disponen de una propiedad
target
, que hace referencia al objeto que activa el evento (en este caso, la instancia de LoaderInfo en la que se llamó el método
addEventListener()
, tal y como se describió anteriormente). Por su parte, el objeto LoaderInfo tiene una propiedad
content
que (una vez completado el proceso de carga) contiene la instancia de Bitmap con la imagen de mapa de bits cargada. Si desea visualizar la imagen directamente en pantalla, puede asociar esta instancia de Bitmap (
event.target.content
) a un contenedor de objetos de visualización. (También puede asociar el objeto Loader a un contenedor de objetos de visualización). No obstante, en este ejemplo el contenido cargado se utiliza como origen de los datos de la imagen sin procesar en lugar de mostrarse en pantalla. Por ello, la primera línea del método
imageLoadComplete()
lee la propiedad
bitmapData
de la instancia de Bitmap cargada (
event.target.content.bitmapData
) y la almacena en la variable de la instancia denominada
textureMap
, que se utiliza como origen de los datos de imagen para crear la animación de la luna en rotación. Este punto se describe a continuación.
Creación de animación con copia de píxeles
Una definición básica de animación es la ilusión de movimiento o cambio, creado mediante el cambio de una imagen en el tiempo. En este ejemplo, el objetivo es crear la ilusión de una rotación de la luna esférica alrededor de su eje vertical. Sin embargo, para los objetivos de la animación, se puede omitir el aspecto de distorsión esférica del ejemplo. Observe la imagen real que se carga y se utiliza como el origen de los datos de imagen de la luna:
Como se puede ver, la imagen no es una o varias esferas; se trata de una fotografía rectangular de la superficie de la luna. Debido a que la foto fue tomada exactamente en el ecuador de la luna, las partes de la imagen más cercanas a la parte superior e inferior de la imagen están expandidas y distorsionadas. Para eliminar la distorsión de la imagen y hacerla parecer esférica, utilizaremos un filtro de mapa de desplazamiento, tal y como se describe más adelante. Sin embargo. debido a que esta imagen de origen es un rectángulo, para crear la ilusión de que la esfera está girando, el código simplemente necesita deslizar la fotografía de la superficie de la luna horizontalmente.
Se debe tener en cuenta que la imagen incluye realmente dos copias de la fotografía de la superficie de la luna próximas entre sí. Esta imagen es la de origen a partir de la que los datos de imagen se copian repetidamente para crear la apariencia de movimiento. Al tener dos copias de la imagen próximas entre sí, un efecto de desplazamiento ininterrumpido y continuo puede ser más fácil de crear. Analicemos el proceso de animación paso a paso para ver su funcionamiento.
El proceso incluye dos objetos de ActionScript independientes. En primer lugar se dispone de la imagen de origen cargada, que en el código se representa mediante una instancia de BitmapData denominada
textureMap
. Tal y como se ha descrito anteriormente,
textureMap
se llena con datos de imagen una vez cargada la imagen externa, utilizando este código:
textureMap = event.target.content.bitmapData;
El contenido de
textureMap
es la imagen de la luna con forma rectangular. Asimismo, para crear la rotación animada, en el código se utiliza una instancia de Bitmap denominada
sphere
, que es el objeto de visualización real que muestra la imagen de la luna en pantalla. Al igual que sucede con
textureMap
, el objeto
sphere
se crea y se llena con sus datos de imagen inicial en el método
imageLoadComplete()
, empleando el siguiente código:
sphere = new Bitmap();
sphere.bitmapData = new BitmapData(textureMap.width / 2, textureMap.height);
sphere.bitmapData.copyPixels(textureMap,
new Rectangle(0, 0, sphere.width, sphere.height),
new Point(0, 0));
Tal y como muestra el código, se crea una instancia de
sphere
. Su propiedad
bitmapData
(los datos de la imagen sin procesar que se muestran mediante
sphere
) se crea con la misma altura y la mitad de anchura de
textureMap
. Es decir, el contenido de
sphere
será el tamaño de una fotografía de la luna (ya que la imagen
textureMap
contiene dos fotografías de la luna, una junto a otra). A continuación, la propiedad
bitmapData
se llena con los datos de imagen utilizando su método
copyPixels()
. Los parámetros en la llamada al método
copyPixels()
indican varios puntos:
-
El primer parámetro indica que los datos de imagen se copian desde
textureMap
.
-
El segundo parámetro, una nueva instancia de Rectangle, especifica desde qué parte de
textureMap
se debe tomar la instantánea de la imagen; en este caso, la instantánea es un rectángulo que comienza en la esquina superior izquierda de
textureMap
(indicado mediante los dos primeros parámetros
Rectangle()
:
0, 0
) y la altura y anchura de la instantánea del rectángulo coinciden con las propiedades
width
y
height
de
sphere
.
-
El tercer parámetro, una nueva instancia de Point con los valores x e y de
0
, define el destino de los datos de píxel; en este caso, la esquina superior izquierda de (0, 0) de
sphere.bitmapData
.
Representado visualmente, el código copia los píxeles desde
textureMap
destacado en la siguiente imagen y los pega en
sphere
. Es decir, el contenido de BitmapData de
sphere
es la parte de
textureMap
resaltada aquí:
No obstante, recuerde que esto solo es el estado inicial de
sphere
; el contenido de la primera imagen que se copia en
sphere
.
Con la imagen de origen cargada y
sphere
creada, la tarea final realizada por el método
imageLoadComplete()
es configurar la animación. La animación se activa mediante una instancia de Timer denominada
rotationTimer
, que se crea y se inicia mediante el siguiente código:
var rotationTimer:Timer = new Timer(15);
rotationTimer.addEventListener(TimerEvent.TIMER, rotateMoon);
rotationTimer.start();
En primer lugar, el código crea la instancia de Timer denominada
rotationTimer
; el parámetro transmitido al constructor
Timer()
indica que
rotationTimer
debe activar su evento
timer
cada 15 millisegundos. A continuación, se llama al método
addEventListener()
, especificando que cuando sucede el evento
timer
(
TimerEvent.TIMER
), se llama al método
rotateMoon()
. Finalmente, timer se inicia realmente llamando a su método
start()
.
Debido al modo en que se define
rotationTimer
, aproximadamente cada 15 millisegundos Flash Player llama al método
rotateMoon()
en la clase MoonSphere, que es donde sucede la animación de la luna. El código fuente del método
rotateMoon()
se presenta del siguiente modo:
private function rotateMoon(event:TimerEvent):void
{
sourceX += 1;
if (sourceX > textureMap.width / 2)
{
sourceX = 0;
}
sphere.Data.copyPixels(textureMap,
new Rectangle(sourceX, 0, sphere.width, sphere.height),
new Point(0, 0));
event.updateAfterEvent();
}
El código realiza tres operaciones:
-
El valor de la variable
sourceX
(establecido inicialmente en 0) se incrementa en 1.
sourceX += 1;
Tal y como se puede observar,
sourceX
se usa para determinar la ubicación en
textureMap
desde donde los píxeles se copiarán en
sphere
, por lo que este código tiene el efecto de mover el rectángulo un píxel a la derecha en
textureMap
. Volviendo a la representación visual, tras varios ciclos de animación, el rectángulo de origen se habrá movido varios píxeles hacia la derecha, tal y como se muestra a continuación:
Tras varios ciclos más, el rectángulo se habrá movido incluso más lejos:
Este cambio constante y gradual en la ubicación desde la que se copian los píxeles es la clave en la animación. Con el movimiento lento y continuo de la ubicación de origen hacia la derecha, la imagen que se muestra en la pantalla en
sphere
parecer deslizarse continuamente hacia la izquierda. Por este motivo, es necesario que la imagen de origen (
textureMap
) tenga dos copias de la fotografía de la superficie de la luna. Debido a que el rectángulo se mueve continuamente hacia derecha, la mayor parte del tiempo no lo hace sobre una sola fotografía de la luna, sino que se superponen las dos fotografías.
-
Con el movimiento lento del rectángulo de origen hacia la derecha, existe un problema. Finalmente el rectángulo llegará al borde derecho de
textureMap
y no dispondrá de píxeles de la fotografía de la luna para copiar en
sphere
:
En las siguientes líneas de código se aborda este problema:
if (sourceX >= textureMap.width / 2)
{
sourceX = 0;
}
El código comprueba si
sourceX
(borde izquierdo del rectángulo) ha alcanzado la mitad de
textureMap
. Si es así, vuelve a restablecer
sourceX
a 0, moviéndolo de nuevo hacia el borde izquierdo de
textureMap
y volviendo a iniciar el ciclo:
-
Con el valor adecuado y calculado de
sourceX
, el paso final en la creación de la animación consiste en copiar los nuevos píxeles del rectángulo de origen en
sphere
. El código que realiza esta operación es muy similar al que llenó en un principio
sphere
(descrito anteriormente); en este caso la única diferencia es que en la llamada al constructor
new Rectangle()
, el borde izquierdo del rectángulo se sitúa en
sourceX
:
sphere.bitmapData.copyPixels(textureMap,
new Rectangle(sourceX, 0, sphere.width, sphere.height),
new Point(0, 0));
Recuerde que este código se llama repetidamente, cada 15 milisegundos. Debido a que la ubicación del rectángulo de origen se desplaza continuamente y los píxeles se copian en
sphere
, la apariencia en pantalla es que la imagen de la fotografía de la luna representada mediante
sphere
se desliza constantemente. Es decir, la luna parece girar de forma continua.
Creación de la apariencia esférica
Obviamente, la luna es una esfera y no un rectángulo. Por lo tanto, en el ejemplo es necesario tomar la fotografía de la superficie de la luna rectangular, conforme se anima continuamente, y convertirla en una esfera. Esto implica dos pasos independientes: una máscara se utiliza para ocultar todo el contenido excepto una región circular de la fotografía de la superficie lunar y un filtro de mapa de desplazamiento se emplea para distorsionar la apariencia de la fotografía para hacerla parecer tridimensional.
En primer lugar, se usa una máscara con forma de círculo para ocultar todo el contenido del objeto MoonSphere excepto la esfera creada por el filtro. El siguiente código crea la máscara como una instancia de Shape y la aplica como la máscara de la instancia de MoonSphere:
moonMask = new Shape();
moonMask.graphics.beginFill(0);
moonMask.graphics.drawCircle(0, 0, radius);
this.addChild(moonMask);
this.mask = moonMask;
Se debe tener en cuenta que dado que MoonSphere es un objeto de visualización (se basa en la clase Sprite), la máscara se puede aplicar directamente a la instancia de MoonSphere utilizando su propiedad heredada
mask
.
Ocultar simplemente las partes de la fotografía utilizando una máscara con forma de círculo no es suficiente para crear un efecto de esfera giratoria con un aspecto realista. Debido al modo en que se tomó la fotografía de la superficie lunar, sus dimensiones no son proporcionales; las partes de la imagen que se encuentran más hacia la parte superior o inferior de la imagen están más distorsionadas y expandidas en comparación con las partes del ecuador. Para distorsionar la apariencia de la fotografía para hacerla parecer tridimensional, utilizaremos un filtro de mapa de desplazamiento.
Un filtro de mapa de desplazamiento es un tipo de filtro que se usa para distorsionar una imagen. En este caso, la fotografía de la luna se “distorsionará” para hacerla más realista, contrayendo la parte superior e inferior de la imagen horizontalmente, mientras el centro se deja sin cambio. Suponiendo que el filtro funcione en una parte con forma de cuadrado de la fotografía, la contracción de la parte superior e inferior pero no del centro convertirá el cuadrado en un círculo. Un efecto indirecto de la animación de esta imagen distorsionada es que el centro de la imagen parece moverse más lejos en la distancia de píxeles real que las áreas cercanas a la parte superior e inferior, lo que crea la ilusión de que el círculo es realmente un objeto tridimensional (una esfera).
El siguiente código se utiliza para crear el filtro de mapa de desplazamiento denominado
displaceFilter
:
var displaceFilter:DisplacementMapFilter;
displaceFilter = new DisplacementMapFilter(fisheyeLens,
new Point(radius, 0),
BitmapDataChannel.RED,
BitmapDataChannel.GREEN,
radius, 0);
El primer parámetro,
fisheyeLens
, se conoce como la imagen del mapa; en este caso se trata de un objeto BitmapData que se crea mediante programación. La creación de esta imagen se describe en
Creación de una imagen de mapa de bits estableciendo valores de píxel
. Los demás parámetros describen la posición en la imagen filtrada en la que se debe aplicar el filtro, qué canales de color se utilizarán para controlar el efecto de desplazamiento y hasta qué punto afectarán al desplazamiento. Una vez creado el filtro de mapa de desplazamiento, se aplica a
sphere
, aún en el método
imageLoadComplete()
:
sphere.filters = [displaceFilter];
La imagen final, con máscara y filtro de mapa de desplazamiento aplicados, presenta el siguiente aspecto:
Con cada ciclo de la animación de rotación de la luna, el contenido de BitmapData de la esfera se sobrescribe con una nueva instantánea de los datos de la imagen de origen. No obstante, el filtro no necesita volver a aplicarse cada vez. Esto se debe a que el filtro se aplica en la instancia de Bitmap (el objeto de visualización) en lugar de en los datos del mapa de bits (información del píxel sin procesar). Recuerde que la instancia de Bitmap no son los datos de mapa de bits reales; se trata de un objeto de visualización que muestra los datos de mapa de bits en pantalla. Para utilizar una analogía, una instancia de Bitmap es como el proyector de diapositivas que se utiliza para visualizar diapositivas fotográficas en una pantalla y un objeto BitmapData es como la diapositiva real que se puede presentar mediante un proyector. Es posible aplicar un filtro directamente a un objeto BitmapData, lo que sería comparable a dibujar directamente en una diapositiva fotográfica para alterar la imagen. También se puede aplicar un filtro a cualquier objeto de visualización, incluyendo una instancia de Bitmap; esto sería como colocar un filtro frente a la lente del proyector de diapositivas para distorsionar el resultado que se muestra en pantalla (sin que la diapositiva original se vea alterada). Debido a que se puede acceder a los datos de mapa de bits mediante la propiedad bitmapData de una instancia de Bitmap, el filtro podría haberse aplicado directamente en los datos de mapa bits sin procesar. Sin embargo, en este caso resulta lógico aplicar el filtro al objeto de visualización Bitmap en lugar de a los datos de mapa de bits.
Para obtener información detallada sobre el uso del filtro de mapa de desplazamiento en ActionScript, consulte
Aplicación de filtros a objetos de visualización
.
Creación de una imagen de mapa de bits estableciendo valores de píxel
Un aspecto importante del filtro de mapa de desplazamiento es que implica realmente dos imágenes. Una imagen, la imagen de origen, es la que se vé modificada por el filtro. En este ejemplo, la imagen de origen en la instancia de Bitmap denominada
sphere
. La otra imagen utilizada por el filtro se denomina imagen del mapa. La imagen del mapa no se visualiza realmente en pantalla. En cambio, el color de cada uno de sus píxeles se utiliza como una entrada en la función de desplazamiento; el color del píxel en una determinada coordenada x, y en la imagen del mapa determina el grado de desplazamiento (cambio físico de posición) que se aplica al píxel en dicha coordenada x, y en la imagen de origen.
Por lo tanto, para utilizar el filtro de mapa de desplazamiento para crear un efecto de esfera, el ejemplo necesita la imagen del mapa adecuada; una imagen con fondo gris y un círculo relleno con un degradado de un solo color (rojo) que pase horizontalmente de un tono oscuro a claro, tal y como se muestra a continuación:
Debido a que únicamente se utiliza un filtro y una imagen del mapa en este ejemplo, la imagen del mapa solo se crea una sola vez, en el método
imageLoadComplete()
(es decir, cuando la imagen externa termina de cargarse). La imagen del mapa, denominada
fisheyeLens
, se crea llamando al método
createFisheyeMap()
de la clase MoonSphere:
var fisheyeLens:BitmapData = createFisheyeMap(radius);
Dentro del método
createFisheyeMap()
, la imagen del mapa se dibuja un píxel cada vez utilizando el método
setPixel()
de la clase BitmapData. El código completo para el método
createFisheyeMap()
se incluye a continuación, seguido de un análisis paso a paso sobre su funcionamiento:
private function createFisheyeMap(radius:int):BitmapData
{
var diameter:int = 2 * radius;
var result:BitmapData = new BitmapData(diameter,
diameter,
false,
0x808080);
// Loop through the pixels in the image one by one
for (var i:int = 0; i < diameter; i++)
{
for (var j:int = 0; j < diameter; j++)
{
// Calculate the x and y distances of this pixel from
// the center of the circle (as a percentage of the radius).
var pctX:Number = (i - radius) / radius;
var pctY:Number = (j - radius) / radius;
// Calculate the linear distance of this pixel from
// the center of the circle (as a percentage of the radius).
var pctDistance:Number = Math.sqrt(pctX * pctX + pctY * pctY);
// If the current pixel is inside the circle,
// set its color.
if (pctDistance < 1)
{
// Calculate the appropriate color depending on the
// distance of this pixel from the center of the circle.
var red:int;
var green:int;
var blue:int;
var rgb:uint;
red = 128 * (1 + 0.75 * pctX * pctX * pctX / (1 - pctY * pctY));
green = 0;
blue = 0;
rgb = (red << 16 | green << 8 | blue);
// Set the pixel to the calculated color.
result.setPixel(i, j, rgb);
}
}
}
return result;
}
En primer lugar, cuando se llama al método este recibe un parámetro,
radius
, que indica el radio de la imagen de forma circular que se va a crear. A continuación, el código crea el objeto BitmapData en el que se dibujará el círculo. Dicho objeto, llamado
result
, se transmite finalmente como el valor devuelto del método. Tal y como se muestra en el siguiente fragmento de código, la instancia de BitmapData
result
se crea con una anchura y una altura similares al diámetro del círculo, sin transparencia (
false
para el tercer parámetro) y rellena previamente con el color
0x808080
(gris medio):
var result:BitmapData = new BitmapData(diameter,
diameter,
false,
0x808080);
A continuación, el código utiliza dos bucles para repetir cada píxel de la imagen. El bucle exterior recorre todas las columnas de la imagen de izquierda a derecha (utilizando la variable
i
para representar la posición horizontal del píxel que se está manipulando en ese momento), mientras que el bucle interior recorre todos los píxeles de la columna actual desde la parte superior a la inferior (con la variable
j
que representa la posición vertical del píxel actual). El código de los bucles (donde se omite el contenido del bucle interior) se muestra a continuación:
for (var i:int = 0; i < diameter; i++)
{
for (var j:int = 0; j < diameter; j++)
{
...
}
}
A medida que los bucles recorren los píxeles uno por uno, en cada píxel se calcula un valor (el valor del color del píxel en la imagen del mapa). Este proceso consta de cuatro pasos:
-
El código calcula la distancia del píxel actual desde el centro del círculo a través del eje x (
i - radius
). Dicho valor se divide por el radio para hacerlo un porcentaje del radio en lugar de una distancia absoluta (
(i - radius) / radius
). Ese valor del porcentaje se almacena en una variable denominada
pctX
y el valor equivalente para el eje y se calcula y almacena en la variable
pctY
, tal y como se indica en este código:
var pctX:Number = (i - radius) / radius;
var pctY:Number = (j - radius) / radius;
-
Utilizado una fórmula trigonométrica estándar, el teorema de Pitágoras, la distancia lineal entre el centro del círculo y el punto actual se calcula a partir de
pctX
y
pctY
. Dicho valor se almacena en una variable denominada
pctDistance
, tal y como se muestra a continuación:
var pctDistance:Number = Math.sqrt(pctX * pctX + pctY * pctY);
-
A continuación, el código comprueba si el porcentaje de distancia es inferior a 1 (lo que significa el 100% del radio; es decir, si el píxel que se considera está en el radio del círculo). Si el píxel se encuentra dentro del círculo, se la asigna un valor de color calculado (se omite aquí, pero se describe en el paso 4); de lo contrario, no sucede nada más con ese píxel, de forma que su color se deja como gris medio predeterminado:
if (pctDistance < 1)
{
...
}
-
Para los píxeles que se encuentren dentro del círculo, se calcula un valor de color. El color final será una tonalidad de rojo que comprende desde negro (0% rojo) en el borde izquierdo del círculo hasta rojo claro (100%) en el borde derecho del círculo. El valor de color se calcula en un principio en tres partes (rojo, verde y azul), tal y como se indica a continuación:
red = 128 * (1 + 0.75 * pctX * pctX * pctX / (1 - pctY * pctY));
green = 0;
blue = 0;
Se debe tener en cuenta que únicamente la parte roja del color (variable
red
) dispone realmente de un valor. Los valores de azul y verde (variables
green
y
blue
) se muestran aquí para mayor claridad, pero se pueden omitir. El objetivo de este método es crear un círculo que incluya un degradado de rojo, por lo que los valores de verde o azul no son necesarios.
Una vez que se determinen los tres valores de color independientes, se combinan en un solo valor de color entero utilizando un algoritmo estándar de desplazamiento de bits, tal y como se muestra en este código:
rgb = (red << 16 | green << 8 | blue);
Finalmente, con el valor de color calculado, dicho valor se asigna al píxel actual utilizando el método
setPixel()
del objeto BitmapData de
result
, tal y como se indica a continuación:
result.setPixel(i, j, rgb);
|
|
|