Tutorial: A Simple script to create a random flicker

Objective:

To create a method that causes a random flickering effect.

To set this up , create a movieclip on stage and give it an instance name of myCoverUp. The script below, declares a variable on the main timeline so it can be used outside the scope of the function flicker(). Then the function flicker chooses a random number between 0-50, toggles the visibility of myCoverUp, then clears and creates a new interval timer using the random number as a delay.

var nextInterval = 100;
flickerInterval = setInterval(flicker, nextInterval);
function flicker(){
    nextInterval = Math.random() * 50;
    myCoverUp._visible = !myCoverUp._visible;
    clearInterval(flickerInterval);
    flickerInterval = setInterval(flicker, nextInterval);
} 

Tutorial: Create a Timeline scrubber

Objective: Build a MovieClip that controls the Timeline position of another MovieClip.

[kml_flashembed movie="http://www.theorigin.net/tutorialFiles/ScrubTimeline/scrub.swf" height="400" width="550" /]

The ability to control the position on a MovieClip Timeline graphically seems complex at first glance, but by using some object oriented philosophies, we can build a control bar that can scrub through the Timeline of a Movieclip with relatively little code.

The Setup

The first thing we need to do is setup a movieclip that we want to scrub through. For this tutorial , I just made a short animation that tweens an object between two keyframes. I called this “sequence” and placed an instance on the stage (also named “sequence”), but any animation will work similarly.

Then create another MovieClip that contains two other movieclips, this is the scrubber. Within the “scrubber” one of these two other MovieClips named “bar” that will serve as our base. The “bar” MovieClip should be as long as the entire scrubber, and we will use it to determine, relatively, where the sequence should be. The other movieclip, “handle”, will both graphically represent where on the timeline the target movieclip’s playhead is, and be used to manipulate that position.

Inside the scrubber, we need to setup a few properties and event handlers. First we’ll assign some event handlers to functions that are defined a bit later. By assigning these event handlers to functions rather than creating an anonymous function for them to execute directly, we have the flexibility to change how these events are handled at any point, then change back whenever we want.

Here onPressHandler and onRelease Handler refer to functions that we will define below. Also, I’ve assigned the onReleaseHandler function to both the onRelease event and the onReleaseOutside event just in case our mouse moves faster moves faster than the movie is updating (this is most problematic when using low framerates.

this.onEnterFrame  = null;
this.onPress =  onPressHandler;
this.onRelease =  this.onReleaseOutside = onReleaseHandler;

These properties are pretty simple. boundry_mc refers to the bar Movieclip we created above, again, it is referenced through a variable for flexibility. lowerBound is the minimum value of -X that we will allow our handle to have and similarly, upperBound is the maximum. upperBound is calculated in such a way that the handle can move across the entire “bar”, but since we don’t want it to butt up agains and not go beyond the end of the bar, we subtract out it’s width from the upper bound.

var  boundry_mc:MovieClip = bar;
var  lowerBound:Number = boundry_mc._x;
var  upperBound:Number = boundry_mc._width + boundry_mc._x -  handle._width;
var  target_mc:MovieClip = _root.sequence;

Now to setup those Event handler functions that we assigned to the event handlers above. onPressHandler assigns the function onEnterFrameDown to the onEnterFrame event, while onReleaseHandler clears onEnterFrame. See how we can dynamically change the functions based on user input when we use this method of assigining functions.

function  onPressHandler():Void{
    this.onEnterFrame  = onEnterFrameDown;
}
function  onReleaseHandler():Void{
    this.onEnterFrame  = null;
}

Using the general rule of one action per function, we can break down what we want to happen via the onEnterFrame event that is created via onPress (defined above) into two parts fow which we will create functions. dragWithin will move our handle across the timeline, and scrubMovie will adjust the position of the playhead in our target_mc (also defined above)

function  onEnterFrameDown():Void {
    dragWithin();
    scrubMovie(target_mc);
}

dragWithin simply compares the current _xmouse position to the upper and lower bounds we defined above and moves the handle to the _xmouse position if it is within the bounds. If the _xmouse position is outside of the bounds, the handle is moved to it’s outermost point in the direction on _xmouse.

function  dragWithin():Void{
 var  xmousePosition = this._xmouse;
    if  (xmousePosition > lowerBound && xmousePosition < upperBound){
        handle._x =  xmousePosition;
    } else if  (xmousePosition < lowerBound){
        handle._x =  lowerBound;
    } else if  (xmousePosition > upperBound){
        handle._x =  upperBound;
    }
}

scrubMovie calculates a ratio of the handle position as compared to the total length of the scrubber then applies that ratio to the total number of frames within our sequence to find the frame that corresponds to that position. Then it goes to that frame.

function  scrubMovie(f_target_mc:MovieClip):Void{
    var  totalFrames:Number = f_target_mc._totalframes;
    var  newFrame:Number = Math.round(totalFrames * handle._x / (upperBound -  lowerBound));
    f_target_mc.gotoAndStop(newFrame);
}

This is a simple implementation, but it could be expanded to tween between frames to have the sequence continue to play after the handle is released, or any number of other things. Have fun with it.

Download Source.

About the Author: Patrick Gunderson is a web developer and designer at NFL.com in Los Angeles.

Continue reading

Tutorial: Two Methods to Make a Countdown Timer

Setting up a countdown timer can be helpful in a number of situations, particularly in situations that have a time limit or deadline. Here are two methods for creating and stopping countdown timers. To set the scene, place a dynamic textfield on stage and have it listen for the variable _root.timeLeft . Next draw a simple box stage, select it and convert it to a MovieClip by pressing the f8 key. Give your movieclip the name stopButton. Remember to also give your instance the name stopButton by clicking back to the Stage, selecting your box and naming it in the properties palette.

Counting Frames Method

First let’s go over the more basic, but ultimately more complex method. Since movieclips can execute commands every frame using an onEnterFrame event handler (a specially named function) if we know the framerate, we can count the frames and divide to find the number of seconds past.

Declare a new variable timeLeft and give it a value of 10 (our counter will count down from 10). Create a new Movieclip called tenSecondTimer and assign it properties for frameRate, and counter. We’ll use the counter to count how many frames have passed.

var timeLeft:Number = 10;
createEmptyMovieClip("tenSecondTimer", getNextHighestDepth());
tenSecondTimer.frameRate = 24; // this movie runs at 24 fps
tensecondTimer.counter = 0;

Now create an onEnterFrame event handler, which will be executed with every frame, that increases the counter, compares it to the framerate, and if they match (a second has passed) reduce the timeLeft by one. for this function we’ll use the modulo operator (%), the increment operator(++) and the decrement operator (–). The modulo operator (%divides two numbers and returns the remainder. if the remainder is 0 then the first number is evenly divisible by the second. The increment operator (++) increases the value by one. x++ is the same as x = x + 1. The decrement operator (–) reduces the value by 1. x– is the same as x = x – 1.

tenSecondTimer.onEnterFrame = funtion(){
    this.counter++;
    if (this.counter % this.frameRate == 0){
        _root.timeLeft--;
    }
}

In addition to decreasing the timeLeft after every second, we want it to do something when the time is up. Then remove the timer.

tenSecondTimer.onEnterFrame = funtion(){
    this.counter++;
    if (this.counter % this.frameRate == 0){
        _root.timeLeft--;
    }
    if (timeLeft <= 0){
        trace("TIME'S UP");
        this.removeMovieClip();
    }
}

We also have the button which we want to stop the clock, so we can define an onRelease event handler for it.

stopButton.onRelease = funtion(){
    trace("TIMER STOPPED");
    _root.tenSecondTimer.removeMovieClip();
}

setInterval Method

The second method for creating a countdown timer uses the setInterval command. setInterval creates a timer that will execute a function after a certain number of milliseconds. Otherwise the method is similar. This simplifies things a bit because now we don’t have to count frames to determine if a second has passed, flash will do that for us.

Setup the stage the same way as above, with the textfield and the stopButton.

Declare timeLeft, but this time we don’t need a counter or framerate, so all se need is to make a setInterval.

var timeLeft:Number = 10;

// execute the function countdown every 1000 miliseconds (1 second);
tenSecondTimer = setInterval(countDown, 1000);

now we need to define a function CountDown to decrease the limeLeft every second, and to do something once timeleft is 0.

function countDown(){
    timeLeft--;
    if (timeLeft <= 0){
        trace("TIME'S UP");
        clearInterval(tenSecondTimer);
    }
}

Be sure to clear the interval when time is up and when the stop button is clicked or else you will get “TIME’s UP” messages every second for the rest of your movie!

stopButton.onRelease = funtion(){
    trace("TIMER STOPPED");
    clearInterval(_root.tenSecondTimer);
}

There you have it. Two different methods to display a countdown timer and to stop the countdown with a stop button.

About the author: Patrick Gunderson is a web developer and designer at TWBA\Tequila in Los Angeles.

Tutorial: Drag and throw an object on stage

In this tutorial we will build a movie that contains a simple movieclip that allows the user to click and drag the clip, and when released exhibits some inertia and continues to move and bounce off walls like an air hockey puck.

[kml_flashembed movie="http://www.theorigin.net/tutorialFiles/HockeyPuck/hockeypuck.swf" height="400" width="550" /]

To setup the stage, create a movieclip that contains a square aligned at 0,0. Place an instance on the main stage and give it a name of “puck”.

First we need to enable a click and drag on the puck. To do this we’ll use the onPress Event handler to create an onEnterFrame function that keeps the puck aligned with our mouse.

puck.onPress = function(){
	this.onEnterFrame = function(){
        this._x = _root._xmouse;
        this._y = _root._ymouse;
    }
}

This script is OK, but rather than smoothly picking up the puck where the mouse touched it, the puck snaps its top corner to our mouse. To alleviate this we need to subtract the mouse position relative to the puck from the mouse position relative to the stage by setting an anchor when the mouse is pressed. We won’t worry about garbage collecting this onEnterFrame because we are going to overwrite it when the mouse releases.

Note: in general you shouldn’t just leave open onEnterFrame functions running. When you get a number of onEnterFrame functions going at the same time the performance of your movie can suffer greatly or even crash. For this reason you should terminate your onEnterFrame functions when they have finished their purpose. This is called garbage collection.

puck.onPress = function(){
     anchorX = this._xmouse;
	anchorY = this._ymouse;
	this.onEnterFrame = function(){
        this._x = _root._xmouse - anchorX;
        this._y = _root._ymouse - anchorY;
    }
}

Now we need a way to determine which way the mouse was moving when it released the puck. For this we can record _xmouse and _ymouse values every frame that the mouse is down and store them for use in the onEnterFrame we are going to create onRelease.

puck.onPress = function(){
    anchorX = this._xmouse;
	anchorY = this._ymouse;
	this.onEnterFrame = function(){
        lastXMouse = _root._xmouse;
        lastYMouse = _root._ymouse;

        this._x = _root._xmouse - anchorX;
        this._y = _root._ymouse - anchorY;
    }
}

To make the calculation as to which direction to send the puck after release, we only need the mouse position one frame back, but if we were to record more frames, we could get an average direction just prior to release or even find a curve for the puck to follow. Here though we’ll just send the puck in a straight line.

The math to determine which direction the mouse was moving is a simple slope equation using two points (our current and previous mouse points) We’ll define this function for onRelease and onReleaseOutside just in case your mouse is a bit quicker than your movie.

puck.onRelease = puck.onReleaseOutside = function(){
    xDirection = (_root._xmouse - lastXMouse);
    yDirection  = (_root._yMouse - lastYMouse);
}

We use the direction data to create a new movieclip that moves the puck around.

puck.onRelease = puck.onReleaseOutside = function(){
    xDirection = (_root._xmouse - lastXMouse);
    yDirection  = (_root._yMouse - lastYMouse);
    this.onEnterFrame = function(){
	    this._x += xDirection;
	    this._y += yDirection;
    }
}

In order to make the puck bounce off the walls we need to check to see whether or not it has reached the edge of the stage, and have it reverse direction if it has.

puck.onRelease = puck.onReleaseOutside = function(){
    xDirection = (_root._xmouse - lastXMouse);
    yDirection  = (_root._yMouse - lastYMouse);
    this.onEnterFrame = function(){

	// Bounce off the Walls
	if (this._x < 0){
			xDirection *= -1;
			this._x = 0;
		}
		if (this._x + this._width > Stage.width){
			xDirection *= -1;
			this._x = Stage.width - this._width;
		}
		if (this._y < 0){
			yDirection *= -1;
			this._y = 0;
		}

		if (this._y + this._height > Stage.height){
			yDirection *= -1;
			this._y = Stage.height - this._height;
		}

        // Set New Position
        this._x += xDirection;
	    this._y += yDirection;
     }
}

Finally we want the puck to slow down and eventually stop over time so we’ll add a decay function to the x and Y directions that reduce them by 10% every frame.

Additionally once our puck has stopped, we need to terminate and garbage collect the onEnterFrame function.

puck.onRelease = puck.onReleaseOutside = function(){
    xDirection = (_root._xmouse - lastXMouse);
    yDirection  = (_root._yMouse - lastYMouse);
	this.onEnterFrame = function(){

		// decay x
		if (Math.abs(xDirection) > 0.5){
			xDirection *= .9;
		} else {
			xDirection = 0;
		}

		// decay y
		if (Math.abs(yDirection) > 0.5){
			yDirection *= .9;
		} else {
			yDirection = 0;
		}

		//Garbage Collection
		if (xDirection == 0 && yDirection==0){
			this.onEnterFrame = null;
		}

		//Bounce off the walls
		if (this._x < 0){
			xDirection *= -1;
			this._x = 0;
		}
		if (this._x + this._width > Stage.width){
			xDirection *= -1;
			this._x = Stage.width - this._width;
		}
		if (this._y < 0){
			yDirection *= -1;
			this._y = 0;
		}

		if (this._y + this._height > Stage.height){
			yDirection *= -1;
			this._y = Stage.height - this._height;
		}

		//Position
		this._x += xDirection;
		this._y += yDirection;

	}
}

Download Source

Patrick Gunderson is a Flash Designer and Developer at TBWA\Tequila\ in Los Angeles.

Tutorial: Create an XML Driven, Cross-fading Slideshow

Note: For simplicity’s sake, this tutorial uses the excellent XML2Object Class written and distributed by Alessandro Crugnola from Sephiroth.it. Additionally this tutorial makes use of mx.transitions.Tween which are included with flash.

This tutorial will teach you how to create a simple timed, cross-fading photo album. The basic principles here can be used to expand this project into something far more impressive, but my goal is just to introduce some of the concepts and leverage a bit of their power.

[kml_flashembed movie="http://www.theorigin.net/tutorialFiles/XMLSlideshow/SlideShow.swf" height="400" width="550" /]

To begin this tutorial you’ll need to create a new flash document sized to 300px x 250px so the example images provided to you fill the screen.

Open up the Actions panel. Since most of you are beginner to intermediate flash users, lets discuss best practices for developing an actionscript file or frame. Using proper formation or even a structured formation to your actionscript will make your and peoples you work with lives much easier. Using a uniform structure helps when you need to make edits or when you want to re-use code (which should be often).

I like to structure my actionscript into three main sections: import and include statements, variables and properties, and functions. Each section can be further split up in to subsections, when you get into creating custom classes, but this should be fine for our purposes.

Place the following code inside your first frame to denote the sections we’ll be working with:

/****************************************************************/
// EXTERNALS
/****************************************************************/

/****************************************************************/
// VARIABLES
/****************************************************************/

/****************************************************************/
// FUNCTIONS
/****************************************************************/

For this project I also recommend setting apart a special section for dealing with the XML:

/****************************************************************/
//  XML HANDLING
/****************************************************************/

Lets use a very basic XML file (images.xml) to define where our images live. For this tutorial, I’ve decided to keep everything within the same directory, but this could work just as well with the images at a different path, just add the path to the XML. Remember to form your XML well and include a container tag. Here, mine is .


<?xml version="1.0"?>
<contents>
	<image id="1">image1.jpg</image>
	<image id="2">image2.jpg</image>
	<image id="3">image3.jpg</image>
	<image id="4">image4.jpg</image>
</contents>

Now to get the XML into the flash create an XML object and a variable that defines the location of your XML file, then load your XML:

/****************************************************************/
// VARIABLES
/****************************************************************/

var xmlFile:String = "images.xml";
/****************************************************************/
// XML HANDLING
/****************************************************************/

myXML = new XML();
myXML.load(xmlFile);

Additionally, we want to do something afther the XML is fully loaded so define an onLoad Event Handler for myXML

myXML.onLoad = function(){
	trace("XML loaded");
}

Once the XML is loaded we want to use XML2Object to parse the XML data into a serial object that is easier to deal with. Add the following code to import the XML2Object Functionality to your Movie:

/****************************************************************/
// EXTERNALS
/****************************************************************/

import it.sephiroth.XML2Object;

Create an object where we can place our serialized XML data and place it in the Variables Section, And within the onLoad event handler we just created , add the code to make XML2Object work it’s Magic.

/****************************************************************/
// VARIABLES
/****************************************************************/

var xmlFile:String = "images.xml";
var serialObject:Object = new Object();
/****************************************************************/
// XML HANDLING
/****************************************************************/

myXML = new XML();
myXML.load(xmlFile);
myXML.onLoad = function(){
	trace("XML loaded");
	var xmlParser:XML2Object = new XML2Object();
	serialObject = xmlParser.parseXML(this);
}

The serialObject will contain all the data from the XML file, reachable via dot syntax. Where ther eare multiple nodes with the same name, there will be an array with the name of the nodes, indexed from 0.

Now that we’ve got all our data in place, it’s time to do something with it, Namely, load some images. Create a loadImage() function. With this function we want to load an image into a placeholder MovieClip so we can take advantage of all the cool methods and properties MovieClips have. Since the image will effectively be a child of our placeholder, it will have inherit all the properties of it’s host. We’re going to concentrate on the _alpha property, but more on that later. First lets load an image into our movie:

/****************************************************************/
// FUNCTIONS
/****************************************************************/

function loadImage(f_imageURL:String):Void{

	var myMCL:MovieClipLoader = new MovieClipLoader();
	createEmptyMovieClip("imageHolder", getNextHighestDepth());
	myMCL.loadClip(f_imageURL, this.imageHolder);
}

Here I’ve defined a function that will load create an empty MovieClip called imageHolder and loads an image who’s location is passed to it when called. This is the meat of the process in its simplest form. It doesn’t return a value when called so it’s data type is set to Void. I promised some crossfading so lets fancy this up a bit.

We are going to be loading multiple images and to make garbage collection a bit easier, lets setup an index value that keeps track of where we’re at in the process of things.

/****************************************************************/
// VARIABLES
/****************************************************************/

var xmlFile:String = "images.xml";
var serialObject:Object = new Object();
var imageIndex:Number = 0;

Since we’re setting up a cross fade we need to make our load script a bit more dynamic. The way it is, each image will automatically replace then last when it loads in so each image needs it’s own unique container. To do this we pass the index value to loadImage() and create new imageHolders based on that value.

/****************************************************************/
// FUNCTIONS
/****************************************************************/

function loadImage(f_imageURL:String, f_index:Number):Void{

	var myMCL:MovieClipLoader = new MovieClipLoader();

	createEmptyMovieClip("imageHolder" + f_index, getNextHighestDepth());
	myMCL.loadClip(f_imageURL, this["imageHolder" + f_index]);
}

the this[] syntax let us create new variables and objects on-the-fly without knowing the specific name of the variable or object , but rather setting up a naming convention.

Next we need to create a way to quickly and easily load images in sequence so we create a new function nextImage().

/****************************************************************/

function nextImage():Void{
	loadImage(serialObject.contents.image[imageIndex].data, imageIndex);
	imageIndex++;
}

/****************************************************************/

nextImage() calls loadImage and passes it a value from the searialObject we created from XML using the imageIndex to find the correct image in sequence. It also passes imageIndex along to LoadImage to be used as a unique ID when creating new imageHolder clips. After it starts the image loading process, it increments the imageIndex so next time nextImage() is called it will provide data for the next image in the sequence.

Now to add the fading part. For this we’ll use the Tween class that ships with flash. To do so, we need to add a couple lines to the externals section of the script.

/****************************************************************/
// EXTERNALS
/****************************************************************/

import it.sephiroth.XML2Object;
import mx.transitions.Tween;
import mx.transitions.easing.Regular;

These two lines setup the use of the tween class for use as our fading mechanizm.

In order to get the fades to work in sequence though, we need to add an event listener to the MovieClipLoader we created in loadImage() and give it an event handler that is triggered once the image is fully loaded in our movie.

/****************************************************************/
// FUNCTIONS
/****************************************************************/

function loadImage(f_imageURL:String, f_index:Number):Void{

	var myMCL:MovieClipLoader = new MovieClipLoader();
	var MCLListener:Object = new Object();
	myMCL.addListener(MCLListener);

	MCLListener.onLoadInit = function(targetMC){

	}

	createEmptyMovieClip("imageHolder" + f_index, getNextHighestDepth());
	myMCL.loadClip(f_imageURL, this["imageHolder" + f_index]);
}

Now to get the loaded inage to fade up from nothing over the top of the previous image, we need to set it’s imageHolder’s initial _alpha to 0, then use the Tween object to gradually bring it up to 100 after it has fully loaded. So set the created movieClip’s alpha to 0 then within the onLoadInit event handler create the tween object.

When creating a new tween Object you must pass it a lot of information to make it work. The Tween object syntax is as follows: new Tween(Object, “_propertyToTween”, method, startValue, endValue, duration, isDurationInSeconds);

We can also create an event handler onMotionFinished to execute once the tween reaches it’s end value. Here, we’ll use it for some garbage collection to keep the elements on screen to a minimum. After an image is faded up completely, we’ll remove the image behind it using a new function removeLastImage().

/****************************************************************/
// FUNCTIONS
/****************************************************************/

function loadImage(f_imageURL:String, f_index:Number):Void{

	var myMCL:MovieClipLoader = new MovieClipLoader();
	var MCLListener:Object = new Object();
	myMCL.addListener(MCLListener);

	MCLListener.onLoadInit = function(targetMC){
		var alphaTween:Tween = new Tween(targetMC, "_alpha", Regular.easeOut, 0, 100, 1, true);
		alphaTween.onMotionFinished = function(){
			removeLastImage();
		}
	}

	createEmptyMovieClip("imageHolder" + f_index, getNextHighestDepth());
	this["imageHolder" + f_index]._alpha = 0;
	myMCL.loadClip(f_imageURL, this["imageHolder" + f_index]);
}

We want to actually look at each image we need to create a timer that will wait a specified amount of time before moving on to the next image. We do this with setinterval. Since setinterval will continue to run at the devined amount of time over and over again we need to clear the last interval before creating a new one. So, our Final loadImage() function looks like:

/****************************************************************/
// FUNCTIONS
/****************************************************************/

function loadImage(f_imageURL:String, f_index:Number):Void{

	var myMCL:MovieClipLoader = new MovieClipLoader();
	var MCLListener:Object = new Object();
	myMCL.addListener(MCLListener);

	MCLListener.onLoadInit = function(targetMC){
		var alphaTween:Tween = new Tween(targetMC, "_alpha", Regular.easeOut, 0, 100, 1, true);
		alphaTween.onMotionFinished = function(){
			removeLastImage();
		}
		clearInterval(_root.imageTimer);
		_root.imageTimer = setInterval(nextImage, 3*1000);
	}

	createEmptyMovieClip("imageHolder" + f_index, getNextHighestDepth());
	this["imageHolder" + f_index]._alpha = 0;
	myMCL.loadClip(f_imageURL, this["imageHolder" + f_index]);
}

Since nextImage() moves on to the next index when it loads the current image we need to remove the image 2 index units back, removing the image one index unit back would be removing the current image. So the removeLastImage function is:

/****************************************************************/

function removeLastImage():Void{
	this["imageHolder" + (imageIndex - 2)].removeMovieClip();
}

/****************************************************************/

Finally to make sure the whole sequence gets started we need to add a call to get nextImage() just after the XML data has been loaded and parsed:

/****************************************************************/
//  XML HANDLING
/****************************************************************/

myXML  = new XML();
myXML.load(xmlFile);
myXML.onLoad  = function(){
    trace("XML  loaded");
    var  xmlParser:XML2Object = new XML2Object();
    serialObject  = xmlParser.parseXML(this);
    nextImage();
}

Put it all together and you get a sequential, cross-fading, XML driven slideshow.

Download the source files

Tutorial: Rounding to a Multiple

Rounding to the nearest multiple (ie, 2:{4, 6, 8…} or 5:{10, 15, 20…})  of a number is a pretty simple  procedure. My solution is to use a similar process to finding the absolute value of a number, by applying a process, then applying the inverse.

To find the nearest multiple of 5, take a number, divide by 5, round then multiply by 5.

var myVariable = 8.6;
myVariable = Math.round(myVariable/5) * 5;
trace("Rounded to: "+ myVariable); // Outputs "Rounded to: 10"