AS2 Slot Machine Number Scroll Class

An AS2 class that allows you to easily create and animate a slot machine style number scroller with two simple function calls.

Here is an AS2 class that allows you to easily create and animate a slot machine style number scroller with two simple function calls. You can scroll numbers up or down by any increment, stopping and starting on any number. It contains many options using an optional greensock-style vars object. You can fine-tune animation speeds and heights individually for each character, or set a delay or onComplete function. Requires the GreenSock tweening engine.

Here’s an example. Note you can style or move the characters around on the stage virtually any way you’d like.

Download class file and FLA. Note: the SWF will work, but you will need to download greensock for the FLA to publish correctly.

And here is the class itself, comments and everything.

/**

* VERSION: 1.0

* DATE: 2011-01-18

* AS2

* AUTHOR: Kalin Ringkvist

**/

import com.greensock.TweenLite;

import com.greensock.easing.Sine;

import mx.utils.Delegate;

import com.greensock.plugins.TweenPlugin;

import com.greensock.plugins.BlurFilterPlugin;

/**

* 	NumberScroll is a class designed to conveniently scroll a series of numbers up and down, as in a slot machine or price countdown animation

*

*

* 	To use this class, first create several movieClips, one for each digit in the number you wish to animate, each containing a textField named 'txt'.

*	If you want to scroll from 1 up to 999, or from 200 down to 10, you would place three movieClips on the stage. These movieClips can be identical or

*	different from each other, and can contain other content, just as long as they contain a textField named 'txt'. Be sure the textFields also have the

*	font properly embedded to show numbers.

*

*	Next, create the NumberScroll object, passing in an array containing your movieClips, and an optional vars object to set options.

*	Then, call startScroll(), along with the same optional vars object to begin the number scrolling

*

*	<b>EXAMPLE:</b><br /><br /><code>

*	import com.NumberScroll;

*

*	//create the NumberScroll object, passing in an array of movieClips that each contain a textField named 'txt'. In this case, the movieClips are all inside a movieClip called 'numbers'.

*	//the second paramater (1), sets the starting value

*	var ns = new NumberScroll([numbers.txt1, numbers.txt2, numbers.txt3, numbers.txt4, numbers.txt5], 1);

*

*	//start the scrolling. The object parameter is optional, but in this example, we use it to set the end value to 40, delay 2 seconds before beginning, set background textFields to %30 opacity,

*	//set delay of .4 of a second between each iteration, call scroll99() upon animation completion, count by 1,

*	//set animation height for each individual clip to 80, 80, 60, 40 and 20 pixels, and set the animation duration to 2 seconds, 1 second, 1 second, .8 of a second and .4 of a second

*	ns.startScroll({endNum:40, delay:2, backgroundTextAlpha:30, incrementDelay:.4, onComplete:scroll99, increment:1, animHeight:[80, 80, 60, 40, 20], animDuration:[2, 1, 1, .8, .4]});

*

*

*

*</code>

**/

class com.NumberScroll{

private var textBGArray:Array;//the textFields that sit in the background

private var textArray:Array;//first set of moving textfields

private var text2Array:Array;//second set of moving texfields

private var parentMC:MovieClip;//the parent of the movieClips that are passed in

private var startNum:Number;

private var endNum:Number = 0;

private var curNum:Number;

private var curNumString:String;

private var numDigits:Number;//the number of digits in the current number

private var digitSpaces:String = "";//the string we add to the beginning of curNumString to insure it has the proper number of digits

private var delay:Number = 0;//delay before the main animation starts

private var incrementDelay:Number = 200;//delay between each increment, converted to milliseconds

private var increment:Number = -1;//the amount to count by, defaults to decrementing by one

private var backgroundTextAlpha:Number = 0;//the transparency of the background digits

private var animHeight:Array = new Array();//array of heights for the new number animation; must have one item for each textField movieClip

private var animDuration:Array = new Array();//array of animation duration values for each textField moviClip

private var onComplete:Function;//the function to call when the final number is done animating in

private var origYArr:Array;//the Y values for each of our passed in textField movieClips

private var readyToComplete:Boolean = false;//tells the tween complete listener whether we are ready to fire the onComplete function

private var countInt:Number;//the AS2 interval we use to call the animations

private var goingDown:Boolean = true;//whether or not we are incrementing or decrementing

private var arrLength:Number;//the number of textField movieClips in our animation

private var varList = new Array("endNum", "delay", "incrementDelay", "increment", "onComplete", "animHeight", "animDuration", "backgroundTextAlpha");

/**

* Constructor <br /><br />

*

* <b>SPECIAL PROPERTIES</b><br />

* The following special properties may be passed in via the constructor's or startScroll()'s vars parameter, like

* <code>new NumberScroll({endNum:100, onComplete:myFunction, increment:-5, animDuration:[2, 1, .5, .2, .1]})</code>

*

* 	<ul>

* 	<li><b> endNum : Number</b>					The number you want the animation to end on</li>

*

*  <li><b> delay : Number</b> 					The number of seconds to wait before beginning the animation</li>

*

*  <li><b> incrementDelay : Number</b> 		The delay in seconds between each count iteration</li>

*

*  <li><b> increment : Number</b> 				The amount to add on each increment (use negative numbers to count down)</li>

*

*  <li><b> onComplete : Function</b> 			The function that will be called when the animation completes</li>

*

*  <li><b> animHeight : Array</b> 				An array of numbers, one for each digit, to define the animation height for each individual character</li>

*

*  <li><b> animDuration : Array</b> 			An array of numbers, one for each digit, to define the animation duration for each individual character</li>

*

*  <li><b> backgroundTextAlpha : Number</b> 	Sets the alpha of the digit that sits in the background</li>

*

*

* 	</ul>

*

* @param vars optionally pass in special properties like

*/

public function NumberScroll(_textArray:Array, _startNum:Number, vars:Object){

TweenPlugin.activate([BlurFilterPlugin]);

textBGArray = _textArray;//setup our new variables

text2Array = new Array();

textArray = new Array();

origYArr = new Array();

parentMC = textBGArray[0]._parent;

startNum = _startNum;

curNum = _startNum;

curNumString = _startNum.toString();

numDigits = textBGArray.length;

var adjustLength:Number = numDigits - curNumString.length;//if we're counting up, see if the start value has fewer digits than the end value

for(var i=0; i < adjustLength; i++){//loop once for every digit difference and add a space each time

digitSpaces = digitSpaces + " ";

}

curNumString = digitSpaces + curNumString;

arrLength = textBGArray.length;

parseVars(vars);//convert any optional passed in vars to be saved till a startScroll() call

for(var i=0; i<arrLength; i++){

duplicateMovieClip(textBGArray[i], "scrollMC_" + i, parentMC.getNextHighestDepth());

textArray[i] = parentMC["scrollMC_" + i];//add the first animation copy to our list

duplicateMovieClip(textBGArray[i], "scrollMC2_" + i, parentMC.getNextHighestDepth());

text2Array[i] = parentMC["scrollMC2_" + i];//add the second animation copy to our list

text2Array[i]._alpha = 0;

textBGArray[i].txt.text = curNumString.substr(i, 1);//set the BG array to correct number

textBGArray[i]._alpha = 0;//we don't actually need this until the animation starts so we hide it in case we don't want it at all

textArray[i].txt.text = curNumString.substr(i, 1);//set the main array to correct number

textArray[i].isCurrent = true;//tells which copy is the one currently visible so we know which to animate out and which to animate in

text2Array[i].isCurrent = false;

origYArr[i] = textArray[i]._y;//record the original Y positions of the numbers

if(animHeight[i] == undefined){//set animation height and duration defaults if we didn't get a proper value passed through the vars object

animHeight[i] = 20;

}

if(animDuration[i] == undefined){

animDuration[i] = .2;

}

}

}

/**

* main function that starts the animation

*

* @param vars object containing any of the optional variables listed for constructor function

*/

public function startScroll(vars:Object){

if(vars.delay || delay){//if we have a delay, delay the beginning of the animation

delay = vars.delay;

TweenLite.delayedCall(delay, Delegate.create(this, startInterval), [vars]);

}else{

startInterval(vars);

}

}

private function parseVars(vars:Object){//loops through our list of allowed vars and sets the ones that have been passed in

for(var i=0; i<varList.length; i++){

if(vars[varList[i]] != undefined){

this[varList[i]] = vars[varList[i]];

}

}

}

/**

* @private

* begins the animation process after the initial delay

*

*/

private function startInterval(vars){

parseVars(vars);

if(endNum > curNum){//determine if we're going up or down

goingDown = false;

}

countInt = setInterval(this, "updateNumber", incrementDelay*1000);//begin the interval

}

/**

* @private

* function that runs once per number increment

*

*/

private function updateNumber(){

curNum += increment;//increment our number

if(curNum <= endNum == goingDown){//if curNum is equal to or moved beyond endNum

curNum = endNum;//make it match

readyToComplete = true;//tell the final tween we're ready to fire the onComplete func

clearInterval(countInt);//and delete the interval so this iteration is our last

}

curNumString = curNum.toString();

matchDigits();

for(var i=0; i<arrLength; i++){//loop once for every textField movieclip

var newMC:MovieClip = text2Array[i];

var curMC:MovieClip = textArray[i];

if(newMC.isCurrent){//figure out which clip is the current one and which is the new one, since they alternate roles

newMC = textArray[i];

curMC = text2Array[i];

}

if(curMC.txt.text != curNumString.substr(i, 1)){

newMC.txt.text = curNumString.substr(i, 1);//set the new clip to the correct text

textBGArray[i].txt.text = curNumString.substr(i, 1);//set background to correct text

textBGArray[i]._alpha = backgroundTextAlpha;

setupClipPair(curMC, newMC, i);//setup starting values and engage animation

}

}

}

/**

* @private

* adjusts curNumString to have the correct number of digits in case number drops a digit, e.g. when it goes from 100 to 99

*

*/

private function matchDigits(){

if(goingDown){

if(curNumString.length + digitSpaces.length < numDigits){

digitSpaces = digitSpaces + " ";

}

}else{//if we're moving up, we may need to strip a space instead of add one

if(curNumString.length + digitSpaces.length > numDigits){

digitSpaces = digitSpaces.substr(0, digitSpaces.length - 1);

}

}

curNumString = digitSpaces + curNumString;

}

/**

* @private

* sets up the pair of animation clips and engages the animation. runs after its been determined which is new and which is current

*

* @param curMC the movieClip that is currently sitting, displaying the current number that is about to be replaced

* @param newMC the movieClip that will be animated in to replace curMC

* @param index the index of these clips in their clip arrays so we can reference matching values for animHeigh, origY, etc

*/

private function setupClipPair(curMC:MovieClip, newMC:MovieClip, index:Number){//checks if it's necessary, then sets up the pair of animation clips  and engages the animation. runs after its been determined which is new and which is current

newMC._y = origYArr[index] - animHeight[index];//return new clip to its top, invisible position

newMC._alpha = 0;

TweenLite.to(newMC, 0, {blurFilter:{blurX:10, blurY:50}});//instantly blur so its ready to fade in

//now we actually animate the new number in

TweenLite.to(newMC, animDuration[index], {_alpha:100, _y:origYArr[index], ease:Sine.easeInOut, blurFilter:{blurX:0, blurY:0}, onComplete:Delegate.create(this, tweenComplete)});

//animate the old one out

TweenLite.to(curMC, animDuration[index], {_alpha:0, _y:origYArr[index] + animHeight[index], ease:Sine.easeInOut, blurFilter:{blurX:10, blurY:50}});

curMC.isCurrent = false;

newMC.isCurrent = true;

}

private function tweenComplete(){

if(readyToComplete){

readyToComplete = false;

onComplete();

}

}

}

 

Game Landing Page

This is a landing page I built with JQuery and CSS for Big Fish Games.

Here’s a link to a landing page I built with JQuery and CSS for Big Fish Games. Click on the large buttons to select a game to load over the video in the main Flash div. The list of related games at the bottom as well as the ‘try it’ link will update accordingly. I used JQuery’s animation function for the opening drawer, browser scrolling, and the animated glow.

Below is one of the many Flash banner ads I built using the AS2 GreenSock tweening engine that linked to this landing page.

http://kalinflash.com/wordpress/wp-content/uploads/2011/06/landing/300x250_francis.swf

Catch the Water Droplets (Flash Game)

In 2010 I built a set of interactive banner ads for the clean water charity, Tap Project, using a little piece of transparent video.

In 2010 I built a set of interactive banner ads for the clean water charity, Tap Project, using a little piece of transparent video. Hover to control the cup.

I also made a number of other sizes, like 300×250, 728×90, 160×600. Here is the 130×400:

 

 

Mini Bar, Big Bill (Mini Flash Game)

In 2009, working for Publicis Seattle, I built a fun little banner ad that allowed viewers to roll over objects in a mini bar, producing randomized animations and tallying a ridiculously high hotel bill, ultimately advertising a company called HomeAway.

In 2009, working for Publicis Seattle, I built a fun little banner ad that allowed viewers to roll over objects in a mini bar, producing randomized animations and tallying a ridiculously high hotel bill, ultimately advertising a company called HomeAway. I used greensock entirely for the animations, allowing everything to be randomized. There is no timeline animation.

EZShow Studio Gig, 2007

In 2007, I went to work for someone I had met at JellyBarn, at a company called EZShow Studio. I worked with one other Flash developer building an online video editing system for advertisers, allowing them to cut together images, text, voice-overs, and video with a variety animations.

In 2007, I went to work for someone I had met at JellyBarn, at a company called EZShow Studio. I worked with one other Flash developer building an online video editing system for advertisers, allowing them to cut together images, text, voice-overs, and video with a variety animations. Like JellyBarn, however, the project ran out of funding, and the app was taken down, so I can’t show a working example.

JellyBarn and IBubble

My first Flash development job was with a company called JellyBarn, in 2005, located in Bellingham Washington. I worked with one other Flash developer, making things like a custom slideshow system, photo albums with dynamic flipping pages, a couple games, and an ECard creator.

My first Flash development job was with a company called JellyBarn, in 2005, located in Bellingham Washington, where I was line-cooking at the time. We were developing a product called GrapeBerry, which was a Flash-based photo-sharing system similar to Flickr. I worked with one other Flash developer, making things like a custom slideshow system, photo albums with dynamic flipping pages, a couple games, and an ECard creator.

The company ran out of funding around 2006, but revived itself a year or so later. I came back to find they had scrapped the idea of a photo sharing system, and instead I built for them something called IBubble, which was an ECard creator system that allowed you to upload your own photos or integrate with your Flickr account. Then you could apply a number of different themes to the photos to make them fit into a holiday card, then there was a large series of decorator objects, such as hats and sunglasses, that could be dragged and dropped onto the card, with the ability to adjust size and rotation. You could also add several types of customizable thought or speech bubbles.

Again, the company ran out of funding before we got the product launched, though this time we did have a solid, marketable application.

JellyBarn again revived itself a year or so later and I came back yet again to do a little Wal-Mart price calculator widget.

Axis and Allies Board Game

I built this not-quite-complete Axis and Allies game around 2006. I quit developing because I started working at a company called EZShow Studio and wanted to switch to AS3 development.

http://kalinflash.com/wordpress/wp-content/uploads/2011/05/axis/axisAndAllies.swf

You might need to have played the actual board game Axis and Allies in order to understand what is going on, as it’s a complex game. The very first screen you see is the purchase menu for Russia. Once you have selected your purchases, you can click and drag on the game board to move around and use the mouse scroll wheel to zoom in and out. Click on the appropriate military forces to select move or attack options (Russia goes first; try attacking one of the nearby German territories). You can move and attack with troops, planes, tanks, ships, etc. You can even load troops or tanks onto transport ships. Once you attack a neighboring territory, the battle menu appears and each country must roll dice for their attack and defense.

Black Market Rebellion – Flash Sci-Fi RPG

In 2004 I built a role playing game starring a tank in classic birds-eye view, with a variety of weapons, items, obstacles and abilities, fighting in a world users could design themselves with a built-in level editor. It has some simple database integration, utilizing PHP and mySQL.

In 2004 I started building a large-scale endeavor I called Black Market Rebellion. After three months of work while still line cooking for a living, I had a role-playing game starring a tank in old-school Legend Of Zelda style, with a variety of weapons, items, obstacles, and abilities, fighting in a world users could design themselves with a built-in level editor. It has some simple database integration, utilizing PHP and mySQL to hold user accounts, characters data, and their custom designed levels.

The game was still a long way from being finalized when I stopped working on it and started in on my first professional Flash gig at a place called JellyBarn in Bellingham Washington.

Unfortunately my old host went out of business suddenly and I have never had the time or energy to set up the whole system again, so I can’t show a complete working demo of the game.

AS2 Random Effect Component

This is a series of functions I developed around 2006 to randomly animate movie clips.

This is a series of functions I developed around 2006 to randomly animate movie clips.

The above animation is a minute and a half and 42 Kilobytes. Can’t do that on a timeline.

This is an example of my series of random effect classes, written in ActionScript 2. I originally built these into a component for distribution but with AS3, they are now a little obsolete.

In the app below you can select different effects to display over the crazy cat. Select with the dropdown at the top right, then adjust the different options below to create all kinds of effects.

Kalin’s Battle Grid – Strategy Board Game in Flash

A two-player chess-like board game that I invented with some role-playing elements, and a myriad of options and different ways to play.

This was my second major Flash project, early 2005, done in the evenings while I was still line cooking at the Village Inn Pub and Eatery. It’s a two-player chess-like board game that I invented with some role-playing elements, and a myriad of options and different ways to play.

It may be a bit confusing at first, since I was still getting the hang of good UI development, but there are some instructions you can access by selecting them in a dropdown menu and hitting the button next to it.