Copy link to clipboard
Copied
Hello. I am creating an animation in Animate CC that includes some snow created using ActionScript 3 on a layer above a background. I would like to be able to hide the snow for a little bit during the animation and then have it come back later. I thought having a movie clip animation with a solid background fade in on a layer above the snow would do this for me, but it seems the snow action script layer stays on top of all layers no matter what. At least how I am doing it. Is there any way to control this? I tried putting a mask layer on the snow AS3 layer and changing the opacity, but that didn't work. I also tried placing the snow AS3 layer inside a movie clip layer and fading that out and back in again and this did not work either. Any help as soon as I can get it would be great as I'm trying to get this animation/movie out soon for the holidays.
Btw, in case it can help, here's the code I used for the snow:
addEventListener (Event.ENTER_FRAME,snow);
function snow (event:Event):void {
var scale:Number=Math.random()*.6;
var _sf:snowflake2=new snowflake2();
_sf.x=Math.random()*900;
_sf.scaleX=scale;
_sf.scaleY=scale;
var speed:Number=Math.random()*3;
var RA:Array=new Array(-1,0);
var lf:int=RA[Math.round(Math.random())];
stage.addChild (_sf);
_sf.addEventListener (Event.ENTER_FRAME,snowfall);
function snowfall (event:Event):void {
_sf.y+=speed;
_sf.rotation+=Math.random()*10;
_sf.x+=(Math.random()*1)*lf;
}
}
Have you ckecked the FLA? You can use it as a template.
Remember that layers are not acessible by AS3. What you have to do is to create a Movie Clip called container and add the particles to it.
And if you don't want the button, the code will be:
...var snowFlakes:Vector.<snowflake2> = new Vector.<snowflake2>();
function generateSnow(total):void
{
var i:uint;
for (i = 0; i < total; i++)
{
var snowFlake:snowflake2 = new snowflake2();
reset(snowFlake);
Copy link to clipboard
Copied
Add your snow particle to a container Movie Clip instead of the stage.
So the line:
stage.addChild (_sf);
Could be:
container.addChild (_sf);
Then you just have to set this container Movie Clip to be invisible, to have a alpha = 0, and so on.
And also make sure to remove the
_sf.addEventListener (Event.ENTER_FRAME,snowfall);
when you don't need it to not waste resources while the snow is invisible. Just call:
_sf.removeEventListener (Event.ENTER_FRAME,snowfall);
And then add it back later.
Regards,
JC
Copy link to clipboard
Copied
Thanks for your quick reply. Just a quick question to clarify this:
So, leading up to this, should I add a layer, insert a new symbol to this layer, call that symbol "container" and make it a movie symbol, then open that movie symbol from the Library and add the code to the first frame?
Copy link to clipboard
Copied
Hi.
The important thing is to add all your snow particles to a single container. Then if you need to show or hide all the particles, all you have to do is to show/hide the parent (container). In this way it's only a matter of choosing the layer to put the container and control precisely the display index of the snowflakes.
If you don't mind, I rewrote your code a bit because only after you replied that I noticed that your code was adding a new event listener for every single particle created! Also, I made some quick optimitazions and opted for a more OOP approach.
For performance sake it's better to use the concept of object pool and create a predefined number of particles and then reuse them, instead of creating new ones from time to time. It keeps memory usage stable.
In our case, I fill up the container and a corresponding vector with a certain amount of particles (200, but you can choose whatever), then I check if the particle is below the bottom of the stage to reset its values and set it back to the top.
Here is the code:
import flash.events.MouseEvent;
var snowFlakes:Vector.<snowflake2> = new Vector.<snowflake2>();
function clickHandler(e:MouseEvent):void
{
if (container.show)
showSnow();
else
hideSnow();
container.show = !container.show;
}
function showSnow():void
{
container.visible = true;
stage.addEventListener(Event.ENTER_FRAME, enterFrameHandler);
}
function hideSnow():void
{
container.visible = false;
stage.removeEventListener(Event.ENTER_FRAME, enterFrameHandler);
}
function generateSnow(total):void
{
var i:uint;
for (i = 0; i < total; i++)
{
var snowFlake:snowflake2 = new snowflake2();
reset(snowFlake);
container.addChild(snowFlake);
snowFlakes.push(snowFlake);
}
}
function reset(particle:snowflake2):void
{
particle.scaleX = particle.scaleY = Math.random() * .6;
particle.x = Math.random() * stage.stageWidth;
particle.y = -stage.stageHeight * 0.25;
particle.speed = 0.5 + Math.random() * 2.5;
particle.lifetime = int(-Math.random() * 2);
}
function enterFrameHandler(event:Event):void
{
var i:uint;
var total:uint = snowFlakes.length;
for (i = 0; i < total; i++)
{
snowFlakes.x += (Math.random() * 1) * snowFlakes.lifetime;
snowFlakes.y += snowFlakes.speed;
snowFlakes.rotation += Math.random() * 10;
if (snowFlakes.y > stage.stageHeight + snowFlakes.height * 0.5)
reset(snowFlakes);
}
}
container.show = false;
generateSnow(200);
stage.addEventListener(Event.ENTER_FRAME, enterFrameHandler);
showHide.addEventListener(MouseEvent.CLICK, clickHandler);
The code is a bit bigger because I added the interactivity of showing/hiding the snowflakes.
Here is the project to download: hide_snow.zip.
I hope it helps and don't hesitate to ask if you have any further questions.
Regards,
JC
Copy link to clipboard
Copied
This is a really nice representation of what I need except for the event of clicking a button. This is not going to be an interactive animation, but rather an animation that is exported to a movie and hosted. I tried your code and added a "container" layer like you did, but it's giving me errors. I'm assuming because I don't have a button. Since it's going to be a movie and I don't need a button to turn it on or off, can I adjust that code?
Copy link to clipboard
Copied
Have you ckecked the FLA? You can use it as a template.
Remember that layers are not acessible by AS3. What you have to do is to create a Movie Clip called container and add the particles to it.
And if you don't want the button, the code will be:
var snowFlakes:Vector.<snowflake2> = new Vector.<snowflake2>();
function generateSnow(total):void
{
var i:uint;
for (i = 0; i < total; i++)
{
var snowFlake:snowflake2 = new snowflake2();
reset(snowFlake);
container.addChild(snowFlake);
snowFlakes.push(snowFlake);
}
}
function reset(particle:snowflake2):void
{
particle.scaleX = particle.scaleY = Math.random() * .6;
particle.x = Math.random() * stage.stageWidth;
particle.y = -stage.stageHeight * 0.25;
particle.speed = 0.5 + Math.random() * 2.5;
particle.lifetime = int(-Math.random() * 2);
}
function enterFrameHandler(event:Event):void
{
var i:uint;
var total:uint = snowFlakes.length;
for (i = 0; i < total; i++)
{
snowFlakes.x += (Math.random() * 1) * snowFlakes.lifetime;
snowFlakes.y += snowFlakes.speed;
snowFlakes.rotation += Math.random() * 10;
if (snowFlakes.y > stage.stageHeight + snowFlakes.height * 0.5)
reset(snowFlakes);
}
}
generateSnow(200);
stage.addEventListener(Event.ENTER_FRAME, enterFrameHandler);
But how you intend to hide the snow anyway?
Copy link to clipboard
Copied
I'll try this. I plan on hiding it by having a layer fade in on top of it and basically just covering it up. Kind of like your candy cane layer.
Do I have to add all 200 pieces of snow to the container movie clip? And if so, do I just line them up at the top outside of the frame randomly? And at random sizes?
Copy link to clipboard
Copied
Got it!
No. The code will do it all for you: add the pieces, place them at the top, and randomize the values.
The important thing for you is this line:
generateSnow(200);
Change this number to whatever amount of particles you want.
P.S.: I left a layer in the .fla called 'container bottom'. You can throw that away.
Copy link to clipboard
Copied
I think I'm doing something wrong. I get this message when I Test Scene:
Scene 1, Layer 'actions', Frame 1, Line 13, Column 9 | 1120: Access of undefined property container. |
Copy link to clipboard
Copied
Make sure your Movie Clip is named 'container' on the Properties panel, not on the Library.
Also make sure your container is positioned at 0,0 so the snow will be distributed the way expected.
Copy link to clipboard
Copied
That was exactly it! I knew I was missing something simple. Thank you so much. This problem has been driving me nuts. You're the best!
Copy link to clipboard
Copied
You're welcome!
I'm really glad that it worked for you!