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
|
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.geom.Matrix;
protected function createReflection()
{
// you'll need to rewrite this, my _art variable is a covert art from a CD loaded dynamically, and I scale it previously
var xscale:Number = _art.scaleX;
var yscale:Number = _art.scaleY;
// create my scaling matrix to draw the bitmap into a bitmap data, since even it it's containing Sprite is scaled, it will draw the thing in full proportions otherwise
var scaleMatrix:flash.geom.Matrix;
scaleMatrix = new Matrix();
scaleMatrix.scale(xscale, yscale);
// create a bitmap data for the source bitmap, of the full dimensions of the image we are using to create the reflection from
var sourceBmp:BitmapData;
sourceBmp = new BitmapData(_art.width, _art.height, true, 0x00ffffff);
// draw the source (covert art in my case, into the bitmap data.
sourceBmp.draw(_art, scaleMatrix);
// the height of my reflection is 1/3 of the original image
var reflectionHeight:Number = Math.round(_art.height/3);
// variable to track the row we are writing in the target bitmapdata
var targetRow:Number;
// this is our starting alpha value (0 to 255). The reflection starts at 1/4th of alpha, going gradually to 0
var curAlpha:Number = 64;
// this is the step by which the alpha will lessen on each row, calculated based on the height of our reflection
var steps:Number = 64 / reflectionHeight;
// create our target bitmap data, same width as the original image, and using the height we calculated earlier
var targetBmp:BitmapData = new BitmapData(_art.width, reflectionHeight, true, 0x00FFFFFF);
// loop through the rows of pixels, starting at the bottom of the image to be reflected
for(var row:Number = _art.height-1; row > _art.height - reflectionHeight; row--)
{
// our target row is opposite the sourcerow, since we are reflecting it
targetRow = _art.height - row - 1;
// for each row, decrement the alpha
curAlpha -= steps;
// we go through columns left to right in both source and target image
for(var col:Number = 0; col < _art.width; col++)
{
// we set the pixel in the target image, using col, targetrow, and changing the alpha value of the pixel we get from the source image on the way
targetBmp.setPixel32(col, targetRow, changeAlpha(sourceBmp.getPixel32(col, row), Math.round(curAlpha)));
}
}
// create a bitmap from the bitmapdata
var image:Bitmap = new Bitmap(targetBmp);
// add it to the sprite we use to contain the reflection
_artReflection.addChild(image);
// and eventually position _art and _artReflection so that _art is right OVER the _artReflection
}
// this function alters the alpha value of a 0xAARRGGBB color value and returns the new color value
protected function changeAlpha(color:uint, alpha:int):uint
{
// decompose the 0xAARRGGBB value, each component is a byte, therefore from 0 to 255 in value.
var blueOffset:Number = color % 256;
var greenOffset:Number = ( color >> 8 ) % 256;
var redOffset:Number = ( color >> 16 ) % 256;
var alphaOffset:Number = ( color >> 24) % 256;
// i'm not sure why sometimes the color values are negative, but I remember 7 years ago in C++ under windows I did this hack and it worked.
if(greenOffset < 0)
greenOffset += 256;
if(redOffset < 0)
redOffset += 256;
if(blueOffset < 0)
blueOffset += 256;
//trace("blue:"+blueOffset+", green:"+greenOffset+", red:"+redOffset+", alpha:"+alpha);
// recompose the 0xAARRGGBB value
return (alpha<<24|redOffset<<16|greenOffset<<8|blueOffset);
} |