I have a player that can move around the stage.
I want to have a small illumination of the stage around the player such that enemies and the environment become harder to see the further out they are. I've been able to achieve this to a degree by using these answers here AS3: beginGradientFIll() doesn't make me a gradient!
Additionally, I'd like to be able to dynamically control the alpha such that when the player presses a designated key, more of the stage becomes illuminated. I've also been able to achieve this to an extent.
Here's the SWF so far. http://www.fastswf.com/9cOxDwo
Arrow keys to move and Z to increase illumination.
The problem that I have is that
a) the gradient is too harsh and
b) pressing Z reveals the entire stage whereas I just want to increase the radius of illumination.
Here's what my code looks like.
var circle:Shape = new Shape;
public function player():void
{
this.addEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
}
private function onAddedToStage(event:Event):void
{
var matrix:Matrix = new Matrix();
matrix.createGradientBox(1000, 1000)
circle.graphics.beginGradientFill(GradientType.RADIAL, [0x000000, 0x000000], [0, 1], [0, 255])
circle.graphics.drawCircle(0, 0, stage.stageWidth)
circle.graphics.endFill()
addChild(circle);
And to control the alpha I've just simply be using:
private function lux():void
{
circle.alpha = 0
}
private function onFrame(event:Event):void
{
if(circle.alpha < 1)
{
circle.alpha += 0.005
}
To solve b), could I somehow dynamically control the alpha parameter in the beginGradientFill() function?
I've also been looking at this but couldn't figure out how to mask the stage instead of a clip.
Save me AS3 gods.
Thanks.
Just a quick guide on setting up the overlays the manual way:
If all is done correctly (I hope I described all the steps correctly!), when you navigate back to the timeline where the container holds this entire setup, you should see the blendmode of the light "masking" the portion out of the shadow layer (only this does it smoother taking the gradient's alpha into account, compared to traditional masking in Flash layers).
You will still need code to tell the light Movieclip to follow your player / light-source, which could be approached in two ways:
After all this said and done, large screen changes in traditional Flash vector rendering tends to be slow in performance. The only recommendation I can give you after that is consider using a Stage3D powered engine (Starling, Genome2D, etc.) but that would be a large change to your game - and beyond the scope of this question.
EDIT: to give you a better answer regarding the hierarchy of DisplayObjects, here's a graph
(albeit made in ugly ASCII characters)
+ Root
|
|- Your HUD / UI elements (if applicable)
|
|--+ Container, set to "LAYER" (MovieClip, follows player position)
| |
| |-Erasing Light, set to "ERASE" (MovieClip)
| |-Shadow Rect, set to "LAYER" or "MULTIPLY" (MovieClip)
|
|- Your Player
|- Enemies, Items, Background Etc.
You can also view a screencast tutorial here:
https://www.screenr.com/6MJN
EDIT 2021:
Sorry folks, but looks like that ScreenR recording vanished from the internet since they got acquired by Articulate. Tried the shortlink /6MJN
on it, but no dice. Considering Flash is pretty much fully exterminated everywhere now, this recording probably doesn't matter much anymore.