PDA

View Full Version : help with fading bitmap/bitmapdata?


maskedMan
11-21-2009, 05:36 PM
So, I want to create an effect such that each frame I :

1 ) create a bitmap representation of the stage.
2 ) reduce the bitmap's alpha to .75
3 ) remove any currently existing bitmap from stage
3 ) add new bitmap to stage.


If I'm correct in my thinking, this should effectively create the illusion that the stage is fading over time, as every time you call bitmapData.draw() the bitmap will be set at .75 alpha. This *should* mean that when I apply .75 alpha to the new bitmap that it should effectively result in a new image that is .75 * .75 alpha (.56), then on the next frame again it should be lower still (.42), and on... .31, .23, .17, and so on...

But it seems that what's *actually* happening is that the new bitmap always *looks* like it's .75 alpha every frame.

I'm not sure what's happening here. Can someone give me a sanity check to make sure I'm not doing something stupid?


import flash.events.*;
import flash.display.*;

// draw a black box...
this.graphics.beginFill(0x000000);
this.graphics.drawRect(0,0,100,100);
this.graphics.endFill();

// make bitmap data of screen with box on it...
var bmd:BitmapData = new BitmapData(300,300);
bmd.draw(this);
var bm:Bitmap = new Bitmap(bmd);
bm.alpha = .75;

// add this new bitmap.
this.addChild(bm);

// clear the graphics object.
this.graphics.clear();

this.addEventListener(Event.ENTER_FRAME, onEnter);



function onEnter(e:Event):void{

// make a new bitmap copy of the stage, and reduce alpha.
bmd.draw(this);
this.removeChild(bm);
bm = new Bitmap(bmd);

bm.alpha = .75; // but it's not working?

this.addChild(bm);


}



Additionally, I've tried using stage.invalidate and doing parts of this in an Event.RENDER handler, but it didn't work either...

stenrap
11-21-2009, 06:19 PM
Flash is doing exactly what you're telling it to do: create a new bitmap on every frame and set that bitmap's alpha to .75.

Instead of always setting the new bitmap's alpha to .75, store the alpha in a global variable, and then set the new bitmap's alpha to the global alpha * .75.

Here's your code again, updated with my suggestion:


import flash.events.*;
import flash.display.*;

// draw a black box...
this.graphics.beginFill(0x000000);
this.graphics.drawRect(0,0,100,100);
this.graphics.endFill();

// make bitmap data of screen with box on it...
var bmd:BitmapData = new BitmapData(300,300);
bmd.draw(this);
var bm:Bitmap = new Bitmap(bmd);

var globalAlpha:Number = .75;

bm.alpha = globalAlpha;

// add this new bitmap.
this.addChild(bm);

// clear the graphics object. this.graphics.clear(); this.addEventListener(Event.ENTER_FRAME, onEnter);

function onEnter(e:Event):void{

// make a new bitmap copy of the stage, and reduce alpha.
bmd.draw(this);
this.removeChild(bm);
bm = new Bitmap(bmd);
bm.alpha = globalAlpha * .75; // now it's working

this.addChild(bm);
}

maskedMan
11-21-2009, 08:24 PM
That code didn't seem to cause anything to fade out over time, even once I uncommented the line about adding the event listener. Even still, I don't think it does what I need it to do. I modified the

bm.alpha = globalAlpha * .75;

to be

bm.alpha = globalAlpha *= .75;


Which does cause a fade out, but doesn't do what I want. A global alpha is overzealous. I want to be able to keep adding things to the stage and have them gradually alpha down from their own starting alpha number. That's why I tried to write my original code the way I did. With the global alpha, all new images added to the stage have the same alpha value as the original.


The best way I can describe what seems to be happening here is that regardless of the fact that the bm has alpha .75 when I call bmd.draw(this), the bitmapdata collects the data and interprets it as though the alpha were 1. When I make a new bitmap object from that bitmapdata, the alpha looks to be 1. Therefore, when setting it to .75, everything looks to have the same alpha value.

Here's a new sample code:


import flash.events.*;
import flash.display.*;

// draw a black box...
this.graphics.beginFill(0x000000);
this.graphics.drawRect(0,0,100,100);
this.graphics.endFill();

// make bitmap data of screen with box on it...
var bmd:BitmapData = new BitmapData(300,300,true,0x00000000);
bmd.draw(this);
var bm:Bitmap = new Bitmap(bmd);

var globalAlpha:Number = .75;

bm.alpha = globalAlpha;

// add this new bitmap.
this.addChild(bm);

// clear the graphics object.
this.graphics.clear();
this.addEventListener(Event.ENTER_FRAME, onEnter);

function onEnter(e:Event):void{

this.graphics.beginFill(0x000000);
this.graphics.drawRect(Math.random()*400,Math.rand om()*300,20,20);
this.graphics.endFill();

// make a new bitmap copy of the stage, and reduce alpha.
bmd.draw(this);

this.graphics.clear();

this.removeChild(bm);
bm = new Bitmap(bmd);

//bm.alpha = .75; // original
bm.alpha = globalAlpha *= .75; //with global & fade, but not what I need.

trace(globalAlpha)
this.addChild(bm);
}


If it were working correctly, every new box would appear at alpha .75 and fade down gradually.

Greg SS
11-21-2009, 08:34 PM
bm.alpha *= 0.75; ?

EDIT:
oh, you want to add stuff and fade them too, like, all the animation on the stage still works but leaves a transparent track? Why don't you use the colorTransform function on the bitmapData?

Greg SS
11-21-2009, 09:02 PM
import flash.events.*;
import flash.display.*;
import flash.geom.ColorTransform;

var cTfm:ColorTransform = new ColorTransform(1, 1, 1, 1, 0, 0, 0, -50);

// draw a black box...
this.graphics.beginFill(0x000000);
this.graphics.drawRect(0,0,100,100);
this.graphics.endFill();

// make bitmap data of screen with box on it...
var bmd:BitmapData = new BitmapData(300,300,true,0x00000000);
bmd.draw(this);
var bm:Bitmap = new Bitmap(bmd);

bm.alpha = 0.75;

// add this new bitmap.
this.addChild(bm);

// clear the graphics object.
this.graphics.clear();
this.addEventListener(Event.ENTER_FRAME, onEnter);

function onEnter(e:Event):void{

this.graphics.beginFill(0x000000);
this.graphics.drawRect(Math.random()*400,Math.rand om()*300,20,20);
this.graphics.endFill();

// make a new bitmap copy of the stage, and reduce alpha.
bmd.draw(this);
this.graphics.clear();
addChild(bm);
bmd.colorTransform( new Rectangle(0, 0, 300, 300), cTfm);
}

It looks like color transform alpha is buggy, if you set the rgb multiplier, it faithfully fade the background, but if you set the alpha multiplier, it seemed to stuck at certain alpha value. Same goes with the offset... the alpha just need bigger values for it to work, kinda weird.
But hey, this works!

maskedMan
11-21-2009, 09:46 PM
I'll try that when I get home. If it's really as simple as using a color transform-based solution, that is more excellent than you know. Hopefully this will work to counteract the effects of an ever-expanding glow filter.

maskedMan
11-22-2009, 05:39 AM
This works, and what's better is that I don't have to set the value to something crazy like -50 in my implementation. It works just fine at values as low as -1

Greg SS
11-22-2009, 12:01 PM
Really? Oh wow, then my player is all effed up...
Glad it works for you then.