LIBRARY: Tutorials Reviews Interviews Editorials Features Business Authors RSS Feed

Creating an Interactive Snow Globe with Action Script 3.0

COW Library : Adobe Flash Tutorials : Domani Studios : Creating an Interactive Snow Globe with Action Script 3.0
A Creative Cow Adobe Flash CS4 Tutorial


Creating a Snow Globe with Action Script 3.0

Article Focus:
In this tutorial, Chris Smith and Scott Hiers from Domani Studios create a shake-snow globe using Flash CS4 and Action Script 3.0. In this tutorial, you can either watch the video or follow along with the text tutorial below.

Play Video Tutorial





Finished Project

1. Create a new ActionScript 3.0 Flash File.    

  

 

2. Set up the default document properties 

 

 

3. Choose "New > ActionScript File" and name this file "HolidayCardTutorial.as". This code handles the root of the document. In this case, it’s not very complicated, it only needs to make our shadow follow the globe around the table for a more realistic looking environment and set some basic stage properties.

 

package {

        

         import flash.events.Event;

         import flash.display.Sprite;

         import flash.display.MovieClip;

        

         public class HolidayCardTutorial extends Sprite {

                 

                  public var globe:SnowGlobeContainer;

                  public var shadow:MovieClip;

                 

                  public function HolidayCardTutorial() {

                           super();

                           // initial stage settings

                           stage.scaleMode = "noScale";

                           stage.align = "left";

                           // enter frame loop

                           addEventListener(Event.ENTER_FRAME, update);

                  }

                 

                  public function update(e:Event):void{

                           // keep the shadow under the globe and scale it based on how high the globe is lifted

                           shadow.x = globe.x;                        

                           var s:Number = Math.abs(globe.startPos.y - globe.y) / 650;

                           shadow.scaleX = shadow.scaleY = 1-s;

                           shadow.alpha = .8-s;

                  }

         }

}

  1.  Link the document stage properties base class to this file 

 

 

4. Create 3 Layers for background, shadow, ribbon and the snow globe (I added a shadow mask too because there is a table in the background image that the shadow needs to stay on)



 

 

5. Choose "Insert > new Symbol..." and in the properties window make the type MovieClip and name the new object "SnowGlobeContainer.as" and check “Export for ActionScript”. This clip will contain our awesome globe. The guts and glory of our app will live within this object.



6. Choose "New > ActionScript File" and name the file "SnowGlobeContainer.as". Making our snow globe interactive in the way that we want is not too difficult, really. What we need to do is be able to click and drag the globe around the stage. For this demo I chose to manually call the mouse over & mouse out with coordinates because sometimes if you drag your mouse out of the player there could be some strange behavior. Other than that, the code in the update function is what runs the mouse interaction. It watches the speed of the mouse and controls what happens when you shake or let go of the object. There are some simple physics when you drop the globe to give it a fun and realistic bounce effect.

 

package {

        

         import flash.display.MovieClip;

         import flash.display.Sprite;

         import flash.events.Event;

         import flash.events.MouseEvent;

         import flash.geom.Rectangle;

         import flash.geom.Point;

        

         public class SnowGlobeContainer extends Sprite {

                 

                  public var snowForeground:SnowGeneratorCircle;

                  public var snowBackground:SnowGeneratorCircle;

                  public var cursor:MovieClip;               

                  public var drag:Boolean = false;                 

                  public var over:Boolean = false;        

                  public var startPos:Point = new Point;

                  public var mouseDownOffset:Point = new Point;

                  public var bounds:Rectangle = new Rectangle;               

                  public var vel:Point = new Point(0,0);

                  public var pos:Point = new Point(x,y);

                  public var old:Point = new Point(x,y);

                  public var gravity:Number = 5+(Math.random()*1);

                  public var restitution:Number = 0.5;

                  public var friction:Number = 0.9;        

        

                  public function SnowGlobeContainer() {        

                           // save some initial persistant properties     

                           startPos.x = this.x;

                           startPos.y = this.y;

                           old.x = this.x;

                           old.y = this.y;

                           bounds.x = 0;

                           bounds.y = 0;

                           bounds.width = 600;

                           bounds.height = startPos.y;              

                           // add mouse interaction listeners and show the cursor on rollover

                           this.mouseChildren = false;

                           this.useHandCursor = true;

                           this.buttonMode = true;

                           this.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);

                           this.addEventListener(MouseEvent.MOUSE_UP, onMouseUp);

                           this.addEventListener(Event.ENTER_FRAME, update);

                  }

                 

                  protected function onMouseOver(e:MouseEvent=null):void { over = true; }

                 

                  protected function onMouseOut(e:MouseEvent=null):void {  over = false; }

                 

                  protected function onMouseDown(e:MouseEvent=null):void {

                           // Save the offset of your mouse when you first start dragging. Same functionality as startDrag(false)

                           mouseDownOffset.x = mouseX;

                           mouseDownOffset.y = mouseY;

                           drag = true;

                  }

                 

                  protected function onMouseUp(e:MouseEvent=null):void {

                           vel.x = vel.y = 0;

                           pos.x = x;

                           pos.y = y;

                           drag = false; 

                  }

                 

                  public function update(e:Event):void {

                           // this if/else statement controls the mouse over and out instead of using event listeners

                           if(mouseY < -175 || mouseY > 175 || mouseX < -175 || mouseX > 175){

                                    if(over) onMouseOut();

                           }else{

                                    if(!over) onMouseOver();

                           }

                                            

                           if(drag){

                                    // drag around..

                                    this.x = parent.mouseX - mouseDownOffset.x;

                                    this.y = parent.mouseY - mouseDownOffset.y;

                                    // keep this thing on the table :)

                                    if(y >= bounds.height) y = bounds.height;

                                    // if you "shake" or move the mouse quickly, we are going to reset the snow particles

                                    var d:Point = new Point(Math.abs(old.x - x), Math.abs(old.y - y));

                                    if(d.x > 50 || d.y > 50 ){

                                             snowForeground.reset();

                                             snowBackground.reset();

                                    }                         

                                    // update the history position   

                                    old.x = x;

                                    old.y = y;                               

                                    vel.y = (y-old.y)/2;

                           }else{

                                    // if you drop this object it should have a bit of realistic falling..

                                    vel.y += gravity;

                                    pos.y += vel.y;                                         

                                    // bounce

                                    if(pos.y > bounds.height){

                                             pos.y = bounds.height;

                                             vel.y *= -(Math.random()*restitution);

                                    }

                                    y = pos.y;

                           }

                  }

         }

}

 

7. Create the globe. In order to create the globe we are going to, in this case, use graphics that were built in Photoshop. If you wanted to use your own graphics that would be fine too. Just follow the same procedures and you should be able to replace the graphics with whatever you choose! We will set it up in a way that makes the most sense. Highlights and the glass will go on the top layer. Followed in order by the things you need to see. The snow layers will be on either side of the inner content so that you have a bit of depth on either side of the buildings. Finally, the base will live in the bottom-most layer behind the glass and content.



 

8. Create 5 layers for the base, snow behind, inner content, snow in front, and glass highlight



9. Draw these assets within flash or use Photoshop to create these graphics

 

10. Choose "Insert > New Symbol", name this new MovieClip "SnowGeneratorCircle.as" and choose "Export for ActionScript"

 

11. Choose "New > ActionScript File" and name this file "SnowGeneratorCircle.as". The snow generator is an empty MovieClip that will create our snow particles and have a simple method to reset all of them when the globe is shaken. It’s set up to be a MovieClip with code attached to it so that it could easily be used in the authoring environment for placement.

 

package {

  

   import flash.display.Sprite;

   import flash.events.Event;

  

   public class SnowGeneratorCircle extends Sprite {

           

            var totalFlakes:int = 500;

            var flakes:Array = new Array();

           

            public function SnowGeneratorCircle() {

                     addSnowFlakes();

                     addEventListener(Event.ENTER_FRAME, update);

            }

           

            protected function addSnowFlakes():void{

                     for(var i:int=0; i<totalFlakes; i++){

                              var f:SnowFlake = new SnowFlake();

                              addChild(f);

                              flakes.push(f);                                

                     }

            }

           

            public function reset():void{

                     for(var i:int=0; i<totalFlakes; i++){

                              var f:SnowFlake = flakes[i];

                              f.reset();

                     }

            }

           

            public function update(e:Event=null):void {

                     for(var i:int=0; i<totalFlakes; i++){

                              var f:SnowFlake = flakes[i];

                              f.update(0);

                     }

            }

   }

}

 

 

12. Choose "New > ActionScript File" and name this file "Circle.as". The Circle object is a class that I wrote to do a couple of math calculations for the things involving a circle in our app.

 

 

package

{       

         import flash.geom.Point;

        

         public class Circle

         {                

                  public var x:Number;

                  public var y:Number;

                  public var radius:Number;

                 

                  public function Circle(x:Number, y:Number, radius:Number) {        

                           this.x = x;

                           this.y = y;

                           this.radius = radius;

                  }

                 

                  public function circleExists(objX:Number, objY:Number, objRadius:Number):Boolean {

                           // find out if a smaller circle exists within the bounds of this circle

                           var dist:Number = Math.sqrt( Math.pow(objX, 2) + Math.pow(objY, 2) );

                           return Boolean(Math.ceil(dist) <= radius-objRadius);

                  }

                 

                  public function getPointInRange(minAngle:Number,maxAngle:Number,minRadius:Number,maxRadius:Number):Point {

                           // fetches a point within given params. This isn't tied to this circle radius specifically

                           var p:Point = new Point();

                           var a:Number = (Math.random()*(maxAngle-minAngle)) + minAngle;

                           var r:Number = (Math.random()*(maxRadius-minRadius))  + minRadius;

                           p.x = Math.cos(a * Math.PI/180) * r;

                           p.y = Math.sin(a * Math.PI/180) * r;

                           return p;

                  }

                 

                  public function getRandomPoint(maxRadius:Number):Point {

                           // fetches a random point within this circle radius

                           var p:Point = new Point();

                           var a:Number = (Math.random()*360);

                           var r:Number = (Math.random()*maxRadius);

                           p.x = Math.cos(a * Math.PI/180) * r;

                           p.y = Math.sin(a * Math.PI/180) * r;

                           return p;

                  }

         }

}

 

13. Choose "New > ActionScript File" and name this file "SnowFlake.as". Our snowflake is the coolest part about this app. At first I thought of having real physics for the snowflakes, but for simplicity of tutorial sake I decided to use simple falling physics and just reset the flake to a random position in the globe when you shake it. When you instantiate a SnowFlake it draws its own graphics, sets a few variables for simple physics and adds some depth of field blur based on a randomized depth.

 

package

{

         import flash.display.Shape;

         import flash.geom.Point;

         import flash.filters.BlurFilter;

        

         public class SnowFlake extends Shape

         {

                  public var vel:Point = new Point;

                  public var radius:Number = 10;

                  public var circle:Circle = new Circle(0,0,175);

                 

                  public function SnowFlake() {    

                           // draw snowflake           

                           graphics.lineStyle(3,0xffffff);

                           graphics.moveTo(0,0);

                           graphics.lineTo(0.2,0.2);         

                           // place the snowflake randomly

                           var p:Point = circle.getRandomPoint( circle.radius - this.radius );                          

                           this.x = p.x;

                           this.y = p.y;

                           // set a z "depth" index to give it some scale

                           var z:Number = (Math.random()*300)-150;                   

                           radius = calculatePerspectiveSize(z);           

                           scaleX = scaleY = radius;

                           // give our flake some depth of feild blur

                           if(z<-150) {

                                    var bluramount:Number = z+150;                                 

                                    bluramount /= -100;                                 

                                    bluramount = (bluramount * 20) + 2; 

                                    filters = [new BlurFilter(bluramount, bluramount, 2)];

                           } else  {

                                    filters = [new BlurFilter(2,2,2)];

                           }

                           // cache this vector object as a bitmap so the flash player will render it faster

                           cacheAsBitmap = true;

                           // some velocity properties

                           vel.x = (Math.random()*2)-1;

                           vel.y = 1.5;

                           vel.x*=radius;

                           vel.y*=radius;

                  }

                 

                  public function reset():void{

                           // reset our snowflake to a new random position             

                           var p:Point = circle.getRandomPoint( circle.radius - this.radius );

                           this.x = p.x;

                           this.y = p.y;

                           if(this.y > 125) this.y = 0;

                  }

                 

                  public function update(wind:Number):void {

                           // this function is called on an enter frame event from the Generator class

                           if( circle.circleExists(x,y,radius) && y < 125 ){

                                    x+=vel.x;

                                    y+=vel.y;

                                    x += (wind*radius);

                           }

                  }

                 

                  public function calculatePerspectiveSize(z:Number) : Number {

                           var fov:Number = 300;                     

                           return fov/(z+fov);

                  }

         }       

}

 

14. Good luck and Publish!

 

(On the Left)  CHRIS SMITH, Senior Interactive Developer – Domani Studios
 
Chris has been experimenting with digital design and development since the age of 17.   By pouring his strong emphasis on usability, innovation and expansion in a bowl, then mixing together his diverse skill-set, Chris has helped Domani Studios bring award winning projects for Porsche, Hanes and Allstate to life.    When not channeling his inner-ninja, he spends his days making things look rad and his nights playing lightning fast guitar. Chris specializes in the Adobe suite, animation and experimental visual programming.

(On the Right) SCOTT HIERS, Art Director – Domani Studios

Scott is a multi-disciplined Art Director at Domani Studios Chicago. With over seven years of experience in the digital and interactive design realm he's come to embrace the diverse roster of clients and creatives that have inspired him. Scott is extremely fortunate to be book-ended by the creative challenges and unique exploration that this industry provides. One his biggest challenges at DS is keeping gravity from hindering Chris's hair via an Aqua-Net defense shield.

###

Comments

Re: Creating an Interactive Snow Globe with Action Script 3.0
by Alex Roby
Not having much luck with this, either getting a static globe with Error #1010... or a flashing globe with snow that just gives Error #1009...

Would really like to recreate this for something, are there any source files or has anyone found anything to help?

Thanks
Re: Creating an Interactive Snow Globe with Action Script 3.0
by Lu Soto
Hi guys, The interactive snow glove is very cool, but am trying to recreate it and is not working, am not sure what am doing wrong. Where can I view the source for this?
Re: Creating an Interactive Snow Globe with Action Script 3.0
by Sian Evans
I get this error:

TypeError: Error #1009: Cannot access a property or method of a null object reference.
at SnowGlobeContainer/update()

which seems to refer to snowForeground even though I have that labelled correctly on the top snow layer. The snow falls once when it opens, but no new snow comes when you shake it. HEEEELLLLP!
Re: Creating an Interactive Snow Globe with Action Script 3.0
by Mike Halak
Great tutorial, thanks for posting. But- I get and endless error output of:


TypeError: Error #1009: Cannot access a property or method of a null object reference.
at HolidayCardTutorial/update()


when published. Any tips on resolving?

Also a .zip with all the assets would be a nice present for the holidays :)

Thanks again!

Thanks,

Mike Halak
MikeHalak.com
Re: Creating an Interactive Snow Globe with Action Script 3.0
by Grant Davis
@Katie Steed

I made a snowman that changes outfits randomly every time you shake the snowglobe. To do this I created the movieclip for each element (for example, "hair" with 16 frames of various hairstyles) on the inner content layer.
Then in the SnowGlobeContainer.as file I listed the variables (around Line 49: public var hair:MovieClip;). Finally, within the update function below the line 'snowBackground.reset();' I added this line: 'hair.gotoAndStop(Math.floor(Math.random() * (maxNum - minNum + 1)) + minNum);'.

If you dont want it to be random it could just do a NextFrame script and you have the fade in worked into the timeline. Or use tweennano functions. Maybe that will help you.
@Grant Davi
by Veronica Rubio
HI I know this is 2 YEARS Old but I was hoping on a little help. I'm trying to make the contents of my scene elements change / fade to another scene ... but I'm STUCK. If you're still around & have a second could we chat?
Re: Creating an Interactive Snow Globe with Action Script 3.0
by Katie Steed
Thanks for this tutorial guys - really useful and worked perfectly first time!

I really need some help though, does anyone know how to make it so the contents of the globe change when the user shakes it? Preferably fading in and out too...?
Many thanks :)
+1
Re: Creating an Interactive Snow Globe with Action Script 3.0
by Grant Davis
I believe the snow layer objects need to be labeled 'snowForeground' and 'snowBackground', respectively to get rid of the SnowGlobeContainer.as 1009 error.

The issue I am having is that the snow is falling on a simple click of the globe and not just on the shaking, and I am unsure of where I need to edit that.
Re: Creating an Interactive Snow Globe with Action Script 3.0
by Sara Neumann
I was wondering if you would be posting the source files at all?
Re: Creating an Interactive Snow Globe with Action Script 3.0
by Em Brook
Hi This is a great tutorial and it seems to be working fine for me however, I would love it to play a Christmas tune in the background and can't seem to do this....any help or update on this tutorial to do this would be really appreciated.

Thank you
Re: Creating an Interactive Snow Globe with Action Script 3.0
by Em Brook
Loving this but to repeat a previous comment is there a way to add music and for it to run smoothly with this file as I'm struggling to put a christmas tune in the background.

Thank you
Re: Creating an Interactive Snow Globe with Action Script 3.0
by Jessica Gallmon
Love this tutorial thank you. Only issue I am having is that when I add music and want the interaction to fade to something else at the end of the music.

Right now, if I just watch the animation and do not interact with the globe during the animation, the timing with the music works out perfectly. If you then refresh to play again and view it a second time, this time interacting with the globe, it slows down animation time considerably and then it doesn't even come close to matching the length of the music. Is there some way to get around this? Or is it just the lag time of the actionscript with the interaction? Thank you for any help!
Re: Creating an Interactive Snow Globe with Action Script 3.0
by Laura Lee
Love the tutorial, and the globe moves, but I am having trouble making it snow. I do however, get a flurry of errors...

"TypeError: Error #1009: Cannot access a property..."

Have any tips? Thank you in advance!
Re: Creating an Interactive Snow Globe with Action Script 3.0
by Mandy Stos
Hi Guys! This is awesome! I've got it all to work pretty much but am having an issue with the SnowGeneratorCircle.as - For some reason i get errors and im not getting any snow.

My snow globe doesnt appear to move either with the mouse. It just stays stationary. Not sure if these all tie in together. Any help at all I totally appreciate. You guys rock.


Related Articles / Tutorials:
Adobe Flash
Adobe Edge Animate/The Missing Manual Software/Book Review

Adobe Edge Animate/The Missing Manual Software/Book Review

Increasingly, web developers are being asked to create sites that are viewable on tablets and mobile devices, as well as desktops and laptops running Windows, OS X or Linux. One of the challenges in creating a site like that is animation. Flash, for many years the preferred cross-platform animation solution, is no longer supported on many tablets and mobile devices. Michael looks for - and finds - answers within Adobe's Edge Animate.

Review, Editorial
Michael Hurwicz
Adobe Flash
HTML5 (CreateJS): Interactivity and Debugging

HTML5 (CreateJS): Interactivity and Debugging
  Play Video
Building on two previous tutorials on CreateJS for Flash Pro CS6, Creative COW leader Michael Hurwicz introduces interactivity (specifically, responding to a mouse click), debugging using the JavaScript "alert" statement, and assigning names to objects exported from Flash. Project files included.

Tutorial, Video Tutorial
Michael Hurwicz
Adobe Flash
HTML5 (CreateJS): Animate with JavaScript

HTML5 (CreateJS): Animate with JavaScript
  Play Video
Building on a previous introductory tutorial on CreateJS for Flash Pro CS6, Creative COW leader Michael Hurwicz shows how to modify the JavaScript exported from Flash, to change attributes such as position, speed, wait time, and color. Project files are included.

Tutorial, Video Tutorial
Michael Hurwicz
Adobe Flash
HTML5 (CreateJS) for Adobe Flash Professional CS6

HTML5 (CreateJS) for Adobe Flash Professional CS6
  Play Video
Creative COW leader Michael Hurwicz provides a brief introduction to CreateJS, an extension for Adobe Flash Professional CS6 that allows you to export Flash projects as HTML and JavaScript, even on platforms that do not support the Flash Player.

Tutorial, Video Tutorial
Michael Hurwicz
Adobe Flash
Building an Interactive Whiteboard in Flash: Part Two

Building an Interactive Whiteboard in Flash: Part Two
  Play Video
In part two of this series, Justin Junda walks you through the necessary steps to connect the graphical elements from part one, with Actionscript 3.0 using the Flash drawing API in order to bring this whiteboard to life.

Tutorial, Video Tutorial
Justin Junda
Adobe Flash
Building an Interactive Whiteboard in Flash: Part One

Building an Interactive Whiteboard in Flash: Part One
  Play Video
In this tutorial, Justin Junda takes you through the step by step process on how to build and interactive whiteboard. These whiteboard are often seen in drawing applications, scratch pads, and educational sites. This is part one of a two part series. Part one takes you through setting up all the graphical elements within the stage. Then part two shows a user how to connect the graphics to Actionscript using flashes drawing API to make this whiteboard truly interactive.

Tutorial, Video Tutorial
Justin Junda
Adobe Flash
Embedding a Speech Transcript in a Flash Video with Adobe CS5

Embedding a Speech Transcript in a Flash Video with Adobe CS5
  Play Video
In this tutorial, Creative COW Leader Michael Hurwicz shows you how to create a scrolling transcript synced with a Flash video, using Adobe Creative Suite 5 (Story, OnLocation, Premiere Pro, Soundbooth and Flash Professional).

Tutorial, Video Tutorial
Michael Hurwicz
Adobe Flash
Inverse Kinematics - Springs

Inverse Kinematics - Springs
  Play Video
Springs are a new feature for Inverse Kinematics in Flash CS5. In this video tutorial, Creative COW leader Michael Hurwicz shows you a simple technique for implementing springs, as well as several other "tricks and traps" to make your work with Inverse Kinematics in Flash easier, more flexible and more powerful.

Tutorial, Video Tutorial
Michael Hurwicz
Adobe Flash
Inverse Kinematics - Control Points

Inverse Kinematics - Control Points
  Play Video
Fine-tune your Inverse Kinematics animations in Flash CS5 by working with control points. In this Adobe Flash video tutorial, Creative COW leader Michael Hurwicz shows you how to associate bones with control points, how to move, add and delete control points, and how to adjust control point handles.

Tutorial, Video Tutorial
Michael Hurwicz
Adobe Flash
Inverse Kinematics

Inverse Kinematics
  Play Video
Inverse Kinematics allows you to create structures of bones and joints and use them to animate characters in Flash. Fun and easy! Creative COW leader Michael Hurwicz shows you how in this video tutorial, step by step. Learn some basic ActionScript, too!

Tutorial, Video Tutorial
Michael Hurwicz
MORE
© 2016 CreativeCOW.net All Rights Reserved
[TOP]