Advertisement
  1. Code
  2. Effects

Create a Pinball-Style Rolling Score Counter Class

Scroll to top
Read Time: 12 min

Twice a month, we revisit some of our readers’ favorite posts from throughout the history of Activetuts+. This tutorial was first published in February, 2010.

In this tutorial you'll create a reusable Score class that counts up to the new total when points are added (instead of jumping up to the new score). We'll cover graphics creation as well as code.


Final Result Preview

In some games when you gain points, you'll see your score immediately jump to the new total. I think it's much cooler if the score counts up one by one, so the player can "rack up points". That's what we'll be making here.

Here's an example of the score class in action:

The main idea behind this tutorial is to teach you how to program the "counting up" functionality, but I'll also show you how to create the cool LED display seen in the preview. We'll start by designing the numbers:


Step 1: Set up Your Flash File

Create a new Flash file (ActionScript 3.0). Your movie settings will vary depending on your game. For this demo I'm setting up my movie as 500x300, black background, and 30 fps.

Flash file setupFlash file setupFlash file setup

Step 2: Create the Digit Symbol

Create a new Movie Clip symbol (Insert > New Symbol). Give this symbol the name "digit".

TKTKTK

Step 3: Create the Digit Text Field

Inside the digit movie clip use the Text tool to add a number 0 to the symbol. I'm using a font called Digital Readout, but any LED-style font should work.

Set the text size to 40 pt and make it a light amber/orange color (#F4C28B). Set the Paragraph Format to centered.

TKTKTK

Step 4: Add Glows

Add two separate glow filters to your text field. Set the color to red (#FF0000) for both and set the Strength of both to 200%.

Check the Inner Glow checkbox for one and set the Blur to 2px. Leave the other at 5px Blur.

TKTKTK

You can use a different color if you want (blue or green would both look cool). The trick in getting it to look realistic is to make the text color a little washed out and set the glows to a more saturated color. This makes it look like it's emitting light.


Step 5: Add More Numbers

Create keyframes on frames 1-10 of the digit movie clip. An easy way to do this is to select frames 1-10 (click frame 1, then Shift-click frame 10) and press F6.

You should now have 10 frames, each with a keyframe with your glowing 0 text field. Go through each frame and change the numbers so you have the digits 0-9. Frame 1 will have "0", frame 2 will have "1", frame 3 will have "2", etc.

TKTKTK

Name this layer "numbers".


Step 6: Add the LED Background

We'll now add an "off" state for the LED numbers, so you'll be able to see the unlit segments of the LED display.

Copy your 8 digit (in frame 9). Create a new layer named "background". With the new layer selected use Paste in Place (Edit > Paste in Place) to paste the 8 digit in the exact position as the one we copied.

Remove the glows from the new 8 digit and change its color to dark grey (#333333). Add a blur filter with the Blur set to 3px. Move this layer underneath the "numbers" layer.

TKTKTK

Now you can scrub through the frames and see how the unlit segments of the LED show behind each number.


Step 7: Add the Stop Action

Create another new layer named "actions". Open the Actions Panel and add a stop() action on frame 1.

TKTKTK

This will keep the display showing '0' until we tell it otherwise.


Step 8: Why Frames?

Why are we manually putting each digit on its own frame instead of using a dynamic text field? Good question.

The main reason is that doing so makes it more flexible for updating the graphics later. If you wanted to change the design and use bitmaps for the numbers, or have each digit displayed in a different font or color this makes it easy to do that.

Also, if designers and developers are working together on a project it's best to create things in a way that gives designers easy access to as much of the graphics as possible.
I feel this setup does that more than using dynamic text.


Step 9: Create the Score Movie Clip

Create a new movie clip named "Score". Check 'Export for ActionScript' and set the class name to "Score" also.

TKTKTK

Drag the digit movie clip from the Library into the Score movie clip. Duplicate the digit clip (Edit > Duplicate) six times (so you have seven digits) and space them evenly.

Since we only have seven digits the maximum score we'll be able to display is 9,999,999. If your game will need to accommodate higher scores add more digits accordingly.

Add a bit more space between every third digit to allow for comma separators.

TK

Step 10: Name the Digit Clips

Select the leftmost digit movie clip and give it the instance name "digit1". Name the next one to the right "digit2", then "digit3" and so on.

TK

Step 11: Add Commas

Create a new layer called "commas".

The easiest way to get the commas to look exactly like the numbers is to go into one of the digit clips and copy one of the number text fields.
Back inside the Score movie clip, paste the text field into the commas layer, and change the number to a comma. Duplicate it and move it as many times as you need.

TK

Step 12: Add a Background

For the Score background we'll just add a simple rounded rectangle.

Create a new layer called "background" and place it behind the numbers and commas layers. Select the Rectangle Tool and Option-click (Alt-click) the stage. Make a rectangle 200px x 40px with 3px corners (make yours longer if you have more digits). Make the fill black and the stroke 1px grey (#666666).

TK

For some reason Flash always distorts strokes on rounded rectangles. To get around this, select the stroke and choose Modify > Shape > Convert Lines to Fills. This converts the stroke from a line to a filled shape and it will no longer distort.

TKTKTK

If you think this is a total hack of a workaround for basic functionality that should have been fixed years ago, I urge you to contact Adobe and let them know.


Step 13: Add Shine

What graphic would be complete without some iPhone-esque shine?

Create a new layer above everything else called "shine". Add a new rounded rectangle, slightly smaller than the background one. This time give it no stroke and fill it with a white gradient from 20% Alpha to 0% Alpha.

TKTKTK

Step 14: Create the Score Class

Create a new Actionscript file named "Score.as". Save it in the same directory as your main Flash file. Since the name of this class and the Export Class name of our Score movie clip are the same, Flash will automatically link them.

Add this code to the Score.as file:

1
2
package {
3
4
	import flash.display.MovieClip;
5
	import flash.events.Event;
6
7
	public class Score extends MovieClip {
8
9
		// CONSTRUCTOR

10
		public function Score() {
11
12
		}
13
		
14
	}
15
}

This is just an empty shell of a class for now. We have to extend the MovieClip class since this class is linked to a movie clip in the library, so we also have to import the MovieClip class. We'll be using the ENTER_FRAME event, so we import the Event class as well.


Step 15: Add Variables and Constants

Add these two lines to the Score class just above the constructor function.

1
2
private const SPEED:int = 1; // how fast to count

3
private const NUM_DIGITS:int = 7; // how many digits there are in the score

These are two constants - kind of like settings for the class.

  • The first, SPEED, controls how fast the score counts. I have it set to count one by one, but if your game uses higher scores this might be too slow. You can change this to 5 or 10 or 50 to count up by those increments.
  • The second constant, NUM_DIGITS, defines how many digits we have in our Score movie clip. If you added more (or less) than 7 digits you'll need to change this.

Now let's add a couple of variables. Put these just below the constants:

1
2
private var _totalScore:int = 0;
3
private var _displayScore:int= 0;

These variables will hold the two different versions of our score. "_totalScore" will be the actual score. "_displayScore" will be the number that is currently
being shown on the LED display. If I add 50 to the score, the _totalScore will immediately be 50, but the _displayScore will be 1, then 2, then 3, until it reaches 50.

If you ever need to know the actual score (like to send to your high score boards) you'll use _totalScore since _displayScore might not be accurate.

I'm using underscores at the beginning of the variable names to denote that these are private variables.


Step 16: Add the totalScore Accessor Method

So if _totalScore is a private variable, how will we access from outside the Score class? We'll use an "accessor" or "getter" method.

Add this method below the constructor function:

1
2
// public accessor for totalScore

3
public function get totalScore():int {
4
	return _totalScore;
5
}

This method simply returns the value of the _totalScore variable. It gives us a way to access that value without having to expose it as a public variable.


Step 17: Add the add Method

We'll need a way to add points to the score. Add this method:

1
2
// add an amount to the score

3
public function add(amount:int):void {
4
	_totalScore += amount;
5
	addEventListener(Event.ENTER_FRAME, updateScoreDisplay); // start the display counting up

6
}

This method accepts an integer "amount" which it adds to the _totalScore variable. The second line starts an ENTER_FRAME event that calls a method called updateScoreDisplay every frame. We'll add that next.


Step 18: Add the updateScoreDisplay Method

Now add a the updateScoreDisplay method. This is where all of the cool counting-up functionality will happen. It needs to accept an Event since it's getting called from an ENTER_FRAME event.

1
2
// this runs every frame to update the score

3
private function updateScoreDisplay(e:Event):void {
4
	
5
}

Now let's add some functionality. The first thing this method will do is to increment the _displayScore variable by the amount we set in our SPEED constant:

1
2
// increment the display score by the speed amount

3
_displayScore += SPEED;

There's a potential problem here though. What if our speed is set to 10 and we try to add 5 to the score? The displayScore will be higher than the totalScore. Let's add a couple lines to fix that:

1
2
// make sure the display score is not higher than the actual score

3
if(_displayScore > _totalScore){
4
	_displayScore = _totalScore;
5
}

That checks if the displayScore is higher than the totalScore and if so, sets the displayScore to be equal to the totalScore.

Next we need to add the leading zeros to the score. We'll do this by converting the displayScore to a String and adding zeros until the length equals the number of digits defined by the NUM_DIGITS constant:

1
2
var scoreStr:String = String(_displayScore); // cast displayScore as a String

3
4
// add leading zeros

5
while(scoreStr.length < NUM_DIGITS){
6
	scoreStr = "0" + scoreStr;
7
}

Now to actually display the score we're going to loop through each of our digit clips (remember we named then "digit1", "digit2", etc.) and use the corresponding number from the score string to set the frame number of the clip:

1
2
// loop through and update each digit

3
for (var i:int = 0; i < NUM_DIGITS; i++) {
4
	var num = int(scoreStr.charAt(i));
5
	this["digit"+(i+1)].gotoAndStop(num+1);// set the digit mc to the right frame

6
}

The charAt method retrieves the character from a String at the specified position. This lets us go character by character through the score string.

The brackets in the next line allow us to dynamically create the clip name. The code, this["digit"+(i+1)] accesses the clip with the name "digit1" or "digit2", etc., depending on the value of i.

We're using "num+1" as the frame number because the frame numbers are offset by 1 from the digits they contain (frame 1 shows 0, frame 2 shows 1, etc.)

The last thing we need to do in this method is check to see if the displayScore and the totalScore are equal. If so, we can remove the listener and stop calling this method for now.

1
2
// if the display score is equal to the total score remove the enterframe event

3
if(_totalScore == _displayScore){
4
	removeEventListener(Event.ENTER_FRAME, updateScoreDisplay);
5
}

If you got lost anywhere in that step you can check out the source files to see the completed class.


Step 19: The Score Class in Use

To use this class drag the Score movie clip from the Library onto the Stage and give it the instance name "myScore". You can add points to your score by using this line in your Document Class:

1
2
myScore.add(50);

You can see an example of this in the source files. I'm adding to the score when the bumper buttons are clicked, but you'll more likely be calling add() when events in your game occur.

If you need to know the player's score you can get the totalScore by using:

1
2
myScore.totalScore

This will call the accessor method and return the value of _totalScore.


Conclusion

You now have a reusable counting Score class that you can use in any of your games.

I think the LED look is cool, but you should definitely alter the design to fit the look of your game. Here are a couple ideas for different designs to get you started:

TKTKTK

Thanks for reading this tutorial. Let me know what you think!

Advertisement
Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.