Flash AS3: The Only Math You’ll Ever Need

i write this post at the risk of being laughed out of the industry by eggheads … but one of our goals is to help Flash game developers produce the very best content possible. So if this post helps you, we’re happy to be of service. So let the eggheads laugh.

Nerd

Go ahead and laugh, Poindexter. i’m not afraid of you.

It’th a Total Mathacre

Are you like me? Are you terrified of numbers? Does the thought of performing a simple math equation give you dry mouth and sweaty palms? Do fractions give you restless leg syndrome? And have you been afraid to really dive into programming because you’re worried about the amount of math it requires?

If you’ve even dipped so much as a toe in programmatic waters, i hope you’ve discovered that programming is more about logic than it is about math. You can create quite sophisticated games with branching storylines and interactivity without ever touching a floating point number (whatever that is).

i’ll level with you here: math scares the Hell out of me. But somehow, i’ve been building Flash games professionally for nearly ten years, and my arithmophobia hasn’t stopped me. What i’ve noticed in all my years of game development is that there’s one simple piece of math from back in grade school that i’ve used over and over again. I’ve probably used it in every single game i’ve ever written. But i remember a time when i couldn’t wrap my mind around what i was trying to do, because i hadn’t committed those certain math operations to memory.

So i’ll share them with you today, and i’ll share the cases where the math comes in handy.

The bit of math i’m talking about is just simple ratio stuff. A ratio is a relationship between numbers. Let’s jump into a real-world example right away.

Health Bar – Timeline

You have a game character, and he has a health bar. In code, the character’s health is expressed as a percentage: your character is at 70% health, let’s say.

You’ve built a graphic to depict this on the screen to your player. Here’s the absolute easiest way to go about displaying the health properly:

  1. Make sure your health bar MovieClip has exactly 101 frames

    101 Frames

    (image truncated to fit on-screen)

  2. Inside the health bar, create a rectangle. This will be your character’s health indicator.

    bar

  3. Press F8 and turn the rectangle into a MovieClip symbol.

    symbolize the bar

    Use that little grid to put the registration point at the left edge of the bar

  4. Select frame 101 and press F6 to add a keyframe there on the bar’s layer.

    keyframe on frame 101

  5. On frame 1, set the width of the bar to 0.1. On frame 101, stretch the bar out to its full width. (note: you may need to turn on the snap tool and move the white registration dot in the middle of the bar to its left edge on both keyframes)
  6. Right-click frame 1 and select “Create Motion Tween’ in CS3 or “Create Classic Tween” in CS4

    create motion tween

  7. When you need to display the character’s health, tell the bar to gotoAndStop(health + 1). So if health is 0, the bar goes to the first frame. If health is 100%, the bar goes to the 101st frame. If health is 50%, the bar goes to the middle. (note: MovieClips don’t have a frame zero, which is why we’ve offset everything by 1 frame)

So that’s the old-school way of doing it. And if you’re starting out, it’s still a very viable way of doing things. Don’t let the eggheads laugh at you because you are using timeline animation.

FutureSplash

There was a time, long long ago, when the timeline meant something

But what about cases where you want to do everything with code?

Health Bar – Cheaterpants Mathless Method

What we’re trying to do is to change the width of the health bar using Actionscript 3 code, so that it matches the player’s health value. Here’s the easiest way to do that:

  1. Make sure your graphical health bar, at full health, is 100 pixels wide
  2. When you want to update the player’s health, set the width property of the bar to the health value. At 50%, it’s 50 pixels wide. At 100%, it’s 100 pixels wide.

Sounds great, yeah? We dodged the math bullet for another day.

Dodge a bullet

i’m pretty conviced that, like the Matrix, math is meant to distract us from realizing that we’re all leading sedentary lives getting our essence sucked out of us

Health Bar – Still No Math Required

But wait … what if a 100 pixel-wide health bar won’t fit in your interface? What if it’s too big or two small?

Resist the math at all costs! Just do this:

  1. Scale your health bar. Even if you squish the MovieClip, the width of the bar inside is relative. It’ll still be 100px wide at full health, but it’s inside a clip that’s getting squished or stretched to make it look like it’s shorter or longer than it actually is. This will work out very well if your bar is a vector graphic, because you won’t get any jaggies when you scale it.

Um … Ryan? My health bar isn’t vector.

OR

Let’s just cut to the chase and use some of that ratio math, huh?

Biting the Math Bullet

Alright – we’ve done everything we can to avoid using math to solve this problem. Let’s take a look at the math that we need.

First, let’s gather some information. Let’s identify what we know, and what we don’t know.

What do we know?

  1. We know that our character’s health is 70%
  2. We know that 70% is a number out of 100. If we write it as a fraction, seventy percent is 70/100 (or “70 over 100″, or even “seventy one-hundredths”)
  3. We know how wide our health meter can be (let’s say 360 pixels)

What don’t we know?

  1. We don’t know how wide the bar inside the health meter is supposed to be

So that leaves three knowns, and one unknown. In algebra, our unknown value is often written as x.

Finding x

Ah, x. My old nemesis. How you’ve plagued me with nightmares over the years. But this time, i have nothing to fear, because i’m armed with knowledge, and i’ve been drinking Scotch all afternoon.

A ratio is a relationship between numbers. Do you see the relationship between the number 70 seated inside the number 100, and the width of your health bar seated inside the maximum possible width of the health bar? 70/100 is the same thing as something/360. (remember: 360 is the maximum width our health meter can be.)

So to put that a more mathy way, 70/100 = x/360.

Or, to express it as something you’d see in a grade 5 math textbook:

Equation

Freaked out yet?

Oh teh noes! We’re in Math Land now! Everyone hold on to the rope, and don’t stray off the path. We’re gonna get through this thing.

Ninja Moves, Bitches

There’s a bunch of stuff that we can and need to do to this math thing … this statement … in order to figure out what x is. Anything we do to this statement is called an operation. You can think of operations as ninja moves. Let’s learn the punches, kicks, and spine cracks we need to extract the info we need – x.

Let’s see if we can beat the crap out of the other numbers to isolate x. We want x on one side of the statement, and every other number on the other side. Then we’ll wind up with a statement that says “x = some number“. That’s the number we want!

Ninja Move #1: In an equality statement like this, we’re saying that the thing on the left is the same as the thing on the right. So we can swap sides any time we like. Let’s swap sides now.

Equation Swap

Heee-YAH!!

Ninja Move #2: Just the same, we can flip the fractions upside down, as long as we do it to both sides at the same time. Let’s do it!!

Equation Flip

WICHIKAAAAPOW!!!

Ninja Move #2.5 Ok, that kinda sucks. It’s easier if x stays on top of the fraction. Let’s reverse that last ninja move!

Equation Flip

ZAMMYFLAMM!

Ninja Move #3 It looks like we can do anything we want to one side, as long as we do it to the other. x/360 is another way of saying “x divided by 360″. If you take a number and divide it by something, and then you multiply it by the same something, you wind up with your original number. Let’s see that in action with some easy math:

6 / 3 * 3 = 6;

(Six divided by three equals two. Two times three equals six – the same number we started with.)

And again:

2 / 4 * 4 = 2;

(Two times four equals zero-point-five. Zero-point-five times four equals two – the same number we started with.)

So at the moment, our math equation says x/360. If we multiply x by 360, we’ll get x all on its own. It’s like we’ve made that /360 part disappear.

Multiply by 360

WAPAPOW!

BUT REMEMBER: This is an equality statement. If we kick one side in the face, we have to kick the other side equally in the face. We multiplied the left side by 360 to get rid of the divided-by-360 part, so we need to multiply the other side by 360 as well. Here we go:

Multiply by 360

HAPOOO!!

How awesome is that? x is all alone on one side of the equals sign. Now we just do the math on the other side, and we have our answer.

x = 70 /100 * 360
x = 0.7 * 360
x = 252

So there’s our answer! If the character’s health is at 70%, and the maximum width of our health bar is 360 pixels, we need to change the width of the health bar to 252 pixels to make it look right.

This is just one real-world example where ratio math comes in handy. Here are a few more examples where knowing the same ninja moves helps again and again and again:

Mini-Map!

You have a character on a big scrolling background, and you want to show a dot on a mini-map in the corner of the screen.

The character’s x position within the width of the background is the same as the x position of the dot within the width of the mini-map.

Ratio math helps with your mini-map

(the background extends past the viewable game area)

character.x/background.width == dot.x/miniMap.width; // dot.x is our unknown!

Ninja move! Flip sides!

dot.x/miniMap.width == character.x/background.width;

Ninja move! Isolate the unknown!

dot.x/miniMap.width*miniMap.width == character.x/background.width*miniMap.width; // multiply both sides by miniMap.width to get rid of it on the left side!

Ninja move! Dividing a number by something, and then multiplying by the same something is the same as doing nothing!

dot.x == (character.x / background.width) * miniMap.width;

Solve for x!

dot.x = 57; // (this is after substituting nubmers for character.x, background.width and miniMap.width)

Colour Slider Control Handle!

You have a colour slider bar. The player can crank it up and down to adjust a colour swatch from 0-255. You want to know the colour value out of 255 based on where the slider was cranked.

Ratio math helps with your color slider

The highest red value is 255

sliderTab.y/maximumSliderRange == x/255;
x/255 == sliderTab.y/maximumSliderRange; // swap sides
x = (sliderTab.y/maximumSliderRange)*255; // get rid of the fraction on the left side
x = 42; // (again, we dropped in the number values for sliderTab.y and maximumSliderRange to arrive at this number)

Flash Video Progress Bar!

You have a progress bar on your flv video player. You want to know how far along to position the progress marker based on how much of the video has played.

Ratio math helps with your video player

Play us out, Keyboard Cat

marker.x = movie.position / movie.duration * totalWidthOfTheProgressTrack;

Shooter Game Accuracy Rating!

You have a shooter game. The player scored 37 hits out of a possible 553 targets. You want to express that as a hit accuracy percentage when the level ends.

accuracy = 37 / 553 * 100;

See, Mr. Sprague? That’s How It’s Done

i was never really terrible at math – i just didn’t enjoy it. i didn’t like the fact that there was only one right answer, and that in early grades, we were timed. In the first grade, we had to compete “Minute Math” sheets – one minute to burn through a page full of sums. i appreciate the thinking behind this, but wtf? There was no such thing as “Minute English” (write the alphabet as fast as possible) or “Minute Art” (string together a painted macaroni necklace in under a minute or face failure).

In high school, i finally failed my first math course – grade 12 finite. One of the reasons i never really took to math – and it’s a big one – is that i never had a math teacher who taught it to me like it needed to be taught. If my high school math teacher had told me that by learning physics, i could make a video game character jump and react to gravity and push boxes around, or that by learning trigonometry i could code my own billiards game, i would have lapped it up. As it stands, i still struggle with my fear of numbers in my professional career – the fear of failure, the constant imagined tick of the clock while i try to figure something out.

Just talk about ninja moves and video games, and everything will be fine. Ratio equations may not, honestly, be the only math you’ll ever need, but if you have a bad history with numbers like i do, it’s a decent start.

LolCat Ninja

For more Flash AS3 Tutorials and a pile of other useful stuff, check out our Flash and Actionscript 911 feature.

9 thoughts on “Flash AS3: The Only Math You’ll Ever Need

  1. Rasmus Wriedt Larsen

    Hi there Ryan. Too bad about your fear for numbers, they are really not that bad. I’m actually kinda surprised that I read through the whole thing as I’m awsome at math :D anyway, I found an equation that might be misunderstood, thought you might wanted to change it from this:
    dot.x == character.x/background.width*miniMap.width;
    to this:
    dot.x == (character.x/background.width)*miniMap.width;
    Just to make everything clear.

    Reply
  2. Pingback: [Hilfe] Minimap - Flashforum

Leave a Reply

Your email address will not be published. Required fields are marked *