Flash, Actionscript, Design, Games and Programming.
One of the things that makes the Flash community so strong, is the willingness of coders to share their work. I learned actionscript from people sharing code, and that’s what’s inspired me to start sharing some of the things I’ve been working on too. So I thought a good starting point would be to draw peoples attention to a few of the great Classes and Functions that I’ve found on blogs and messageboards, which I regularly use in my projects.
One brillaint function I’ve used in practically all of my projects since finding it, is Joel Gillman’s Map Function.
Joel’s Map function “Re-maps a number from one range to another“, which might sound like quite obscure functionality, but I use it for all sorts of different things. Let’s say you want a movieclip’s alpha to vary based on the user’s X mouse position and its rotation to vary based on the Y mouse position. Instead of writing lots of math, you can wrap it up in the map function.
Let’s take a look at the code -
function map(v:Number, a:Number, b:Number, x:Number = 0, y:Number = 1):Number { return (v == a) ? x : (v - a) * (y - x) / (b - a) + x; } |
Now that might look pretty confusing – but it’s usage is actually really simple. The map parameters are structured like this – map(value, low1, high1, low2, high2);
So you feed in the value you’re altering (for example mouseX), the lowest that value can be, the highest that value can be, the lowest return value you want, and the highest return value.
Right, let’s take a look at this simple example –
[kml_flashembed fversion="9.0.0" movie="flash-content/MapClass/UsingMapCircleBlog.swf" targetclass="flashmovie" publishmethod="static" width="400" height="300"]
[/kml_flashembed]
And the code that made it -
var SW:Number = stage.stageWidth; var SH:Number = stage.stageHeight; var c:MovieClip = new MovieClip(); c.graphics.beginFill(0xff0000,1); c.graphics.drawCircle(0,50,50); c.graphics.endFill(); c.x = SW/2; c.y = SH/2; c.addEventListener(Event.ENTER_FRAME, circleEvents); addChild(c); function circleEvents(e:Event):void{ trace(mouseX) e.currentTarget.alpha = map(mouseX, 0, SW, 0, 1); e.currentTarget.rotation = map(mouseY, 0, SH, 0, 360); } function map(v:Number, a:Number, b:Number, x:Number = 0, y:Number = 1):Number { return (v == a) ? x : (v - a) * (y - x) / (b - a) + x; } |
So in that swf, the circle’s alpha varies between 0 and 1, based on the mouse’s X position, between 0 and the width of the stage. So, every frame I calculate the alpha using the map function. To set that up, I use the line -
e.currentTarget.alpha = map(mouseX, 0, SW, 0, 1); |
I’m monitoring the mouse’s X position, with a minimum value of 0, a maximum value of the stage width, and I want it to return a value between 0 and 1. Simple.
Similarly, the circle’s rotation ranges from 0 to 360, based on the mouse’s Y value – which ranges from 0 to the height of the stage. So -
e.currentTarget.rotation = map(mouseY, 0, SH, 0, 360); |
I hope you find this great function as useful as I did.
Cheers.
This is the blog of Lawrie Cape, an interactive developer from Leeds, England.
16 Responses to AS3 – Amazing Map Function.
Joel
May 10th, 2009 at 1:28 am
Glad you’ve enjoyed it!
Freelance Flash Games
May 15th, 2009 at 1:34 am
Nice website Lawrie. I code in as2, but your tutorials look great.
Mapping seems like it could be useful. Was it used in your Super Letter Game?
Lawrie
May 15th, 2009 at 9:04 am
Thanks, glad you like the site!
I didn’t use mapping in Super Letter Game, but only as I made it quite a while ago and it’s in AS2.
I could use it for setting the properties of the letters – relative to their perceived depth, something like –
MichaelJW
May 17th, 2009 at 2:53 pm
Wow, this is brilliant! So simple, and yet so powerful. Thanks for sharing it :)
Henner
May 25th, 2009 at 10:05 pm
Nice function! Thanks for sharing!
LnddMiles
July 21st, 2009 at 9:44 pm
Great post! I’ll subscribe right now wth my feedreader software!
JB
July 24th, 2009 at 11:42 pm
Saw the example on wonderfl. Thats going to come in handy. Nice one!
ps
If you have the time, post an example on the PV3D fourm.
cheers
Lawrie
July 27th, 2009 at 12:16 pm
Glad you like it John, it’s a great time saver. Hopefully I’ll get the time to write up a PV3d example tonight.
Rodrigo
October 28th, 2009 at 12:48 pm
Thanks! works perfect :)
Davo
October 31st, 2010 at 6:20 am
Amazing indeed. Really helpful and timesaver.
Best from Argentina!
Anonymous
September 26th, 2011 at 4:13 pm
I’m trying to map mouseY to -100 and 100. Doesn’t work.
The first value is ok: -100 when mouseY is 0.
But is 588.4 when mouseY is 550 (the stageHeight)?
Any ideas?
Lawrie
September 26th, 2011 at 4:20 pm
It works for me, using the following demo AS –
this.addEventListener(Event.ENTER_FRAME, mapMouse);
function mapMouse(e:Event):void{
trace(map(mouseY,0,stage.stageHeight,-100,100));
}
function map(v:Number, a:Number, b:Number, x:Number = 0, y:Number = 1):Number {
return (v == a) ? x : (v – a) * (y – x) / (b – a) + x;
}
Are you sure 550 is your stage height? It’s the default flash stage width which might be throwing you off?
Anonymous
September 26th, 2011 at 9:41 pm
Yeah, the 550 is the default. I’ve changed it for a ‘bigger’ project.
I can get it to work in a clean fla. But not in the project I’m working on.
Basically I’m moving a navigation based on the mouseY, and I’m using the script in attempt to add a bit of top- and bottom margin to the navigation. So I’m calling:
private function navigationHandler(event:Event):void
{
trace(mouseY, map(mouseY, 0, stage.stageHeight, -100, 100));
var _offstage = height / stage.stageHeight;
var _ypos = -((_offstage * stage.mouseY) – (stage.mouseY – (map(mouseY, 0, stage.stageHeight, -100, 100))));
TweenLite.to(this, .5, {y: _ypos});
}
private function map(v:Number, a1:Number, b1:Number, a2:Number = 0, b2:Number = 1):Number
{
return (v == a1) ? a2 : (v – a1) * (b2 – a2) / (b1 – a1) + a2;
}
But it simply return an odd value. And by the way it’s 500, not 550 as stated. But that seems not to be of any point; as it should return 100.
Anonymous
September 26th, 2011 at 9:50 pm
It’s a Gaia project, and I can see now that I’m getting the mouseY based on the child, and not the stage as I thought i was.
Have to figure out how to get the mouseY from the stage and not the child. So there’s a reason it »didn’t work«.
Anonymous
September 26th, 2011 at 9:57 pm
Yeah, had to do this first:
var mc:MovieClip = MovieClip(this.parent);
trace(map(mc.mouseY, 0, stage.stageHeight, -100, 100));
Working great, thanks.
Lawrie
September 26th, 2011 at 10:05 pm
Glad you got it working :)