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.
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:
- Make sure your health bar MovieClip has exactly 101 frames
(image truncated to fit on-screen)
- Inside the health bar, create a rectangle. This will be your character’s health indicator.
- Press F8 and turn the rectangle into a MovieClip symbol.
Use that little grid to put the registration point at the left edge of the bar
- Select frame 101 and press F6 to add a keyframe there on the bar’s layer.
- 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)
- Right-click frame 1 and select “Create Motion Tween’ in CS3 or “Create Classic Tween” in CS4
- 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.
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:
- Make sure your graphical health bar, at full health, is 100 pixels wide
- 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.
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:
- 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.
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?
- We know that our character’s health is 70%
- 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”)
- We know how wide our health meter can be (let’s say 360 pixels)
What don’t we know?
- 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.
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:
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.
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!!
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!
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.)
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.
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:
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:
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.
(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.
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.
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.
For more Flash AS3 Tutorials and a pile of other useful stuff, check out our Flash and Actionscript 911 feature.