Building a Better Bitmap Button in AS3
Building a button from a bitmap can be bothersome. If you’re using the Flash IDE, you can create a mask to determine which pixels are part of the button and which aren’t, but in any other workflow, the entire rectangle containing the bitmap – including any transparent pixels – will be clickable. In this tutorial, you’ll learn how to automatically make all transparent pixels unclickable, with just a few lines of code.
Final Result Preview
Let’s take a look at the final result we will be working towards:
Notice that the hand cursor only appears when hovering over the actual image; even the gaps in the hair don’t cause it to appear. And it’s not just for show: the button presses only register when clicking on these areas.
Introduction: What’s So Special?
At a first glance, the SWF above appears extremely simple. But look closer! Notice how in the demo above, a button press is only counted if you click somewhere on the actual image. This isn’t what would normally happen. Since a bitmap image is always a rectangle, clicking anywhere inside its rectangle normally would count as a button press. Take a look at the example below, where I have outlined the boundary rectangle of our image. Here, you can click anywhere inside the rectangle, including the transparent areas.
As you can see, this is not what we want! For starters, a user could accidentally click the button when he doesn’t mean to. In addition, it looks strange when a hand cursor appears over blank space. In this tutorial, you’ll learn how to easily correct these problems.
If you aren’t already familiar with Object-Oriented Programming or FlashDevelop, I recommend checking out the provided links before starting this tutorial.
Step 1: Getting Started
Open up FlashDevelop and create a new AS3 project (Project > New Project) and call it something like BitmapButtonProj. On the right, open up the src folder and double-click Main.as to open it. Add a new class to your project (right-click /src/ > Add > New Class) called BitmapButton
Step 2: Embedding an Image
We now need an image to work with. Here is the one I’m using:

To use a bitmap image (such as a .jpeg file or a .png file) in Actionscript 3, we have to embed it. FlashDevelop makes this easy. After saving the above image somewhere, right-click the lib folder on the right, mouse over Add, and select the Library Asset option.

If you want to use your own image, be sure to select one with transparency.
The image you selected will now appear in the lib folder in FlashDevelop. Right-click the image and select Generate Embed Code.
public class Main extends Sprite
{
[Embed(source = "../lib/face.png")]
private var ButtonImg:Class;
This code embeds the image in to our project. Whenever you embed an image, you need to define on the next line a class that represents the image you embedded. In this case, our class is called ButtonImg.
Step 3: Adding a TextField
Next, we’ll add a TextField to display how many times we have clicked the button (which will be added next). Add this to Main():
clicksTextField = new TextField(); clicksTextField.width = stage.stageWidth; clicksTextField.defaultTextFormat = new TextFormat(null, 14, 0, true, false, false, null, null, TextFormatAlign.CENTER); clicksTextField.text = "Button Presses: " + numClicks; clicksTextField.mouseEnabled = false; addChild(clicksTextField);
The code above simply formats the text to display at the top center of our project. Don’t miss how we declared our TextField in line 15.
Step 4: Adding the Button
This code should also go in Main():
var button:BitmapButton = new BitmapButton(ButtonImg); button.x = stage.stageWidth / 2 - button.width / 2; button.y = stage.stageHeight / 2 - button.height / 2; addChild(button); button.addEventListener(MouseEvent.CLICK,onButtonClick);
When we instantiate our BitmapButton in line 36, we pass our embedded image class as a parameter. This will be used by the BitmapButton class. After this, we can simply treat our BitmapButton instance like any other DisplayObject: we can position it and add a MouseEvent.CLICK listener as we normally would.
Step 5: Making the Button Do Something
Add this event handler function to Main.as:
private function onButtonClick(e:MouseEvent):void
{
numClicks++;
clicksTextField.text = "Button Presses: " + numClicks;
}
The final piece of code in our Main class is the event listener for button clicks. In it, we simply add one to the number of clicks, numClicks, and update the text in clicksTextField.
Step 6: The BitmapButton Constructor
Flip over to BitmapButton.as. First, import these classes:
import flash.display.Bitmap; import flash.display.BitmapData; import flash.display.Sprite; import flash.events.MouseEvent;
Then, declare these:
private var bitmapData:BitmapData; private const THRESHOLD:Number = 0;
You must make sure that the BitmapButton class extends Sprite, since a Bitmap by itself cannot have any mouse interactivity. (The Bitmap class doesn’t extend InteractiveObject.)
public function BitmapButton(ImageData:Class)
{
var image:Bitmap = new ImageData();
addChild(image);
bitmapData = image.bitmapData;
addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
addEventListener(MouseEvent.CLICK, onClick);
}
In our BitmapButton constructor, we accomplish a couple of important things.
- First, we create a new
Bitmap, calledimage, from the image class passed as a parameter to the constructor. - We then add this
Bitmapas a child of ourSprite. - Next, we set the value of
bitmapDatato equal thebitmapDataof our image. - Finally, we add
CLICKandMOUSE_MOVEevent listeners.
Step 7: The MOUSE_MOVE Event Listener
private function onMouseMove(e:MouseEvent):void
{
var pixel:uint = bitmapData.getPixel32(mouseX, mouseY);
useHandCursor = buttonMode = ((pixel >>>24) > THRESHOLD);
}
Our simple looking MOUSE_MOVE event listener is the real brains behind our class. Its main purpose is to determine whether the mouse cursor is over a transparent pixel or not. Let’s look at how it does this.
The getPixel32() Function
The first line gets the color and transparency of the pixel that the cursor is currently over. To do this, we use the getPixel32() method of the variable bitmapData (which, remember, is the bitmap data representation of our image).
We must pass an x- and y-coordinate to getPixel32(), so naturally we use the mouse’s position.
The call then returns a uint representing the color and transparency of the pixel at the location we supplied.
Colors in Flash are normally treated as a hexadecimal uint in the format RRGGBB. The first two digits represent the amount of red in the color, the next two, green, and the final two, blue. However, getPixel32() provides us with a special uint representing our pixel in the format AARRGGBB. Here, the first two digits represent the alpha, or the amount of transparency, from 00 (clear) to FF (opaque).
So, for example, FF980000 would represent a fully opaque red color, while 00980000 would represent a fully transparent red color. You’ll typically see these represented as 0xFF980000 or 0x0098000: the “0x” lets you (and Flash!) know that the number is in hexidecimal (0-f), rather than decimal (0-9).
The Bitwise Unsigned Right Shift Operator
At this point, we have a uint called pixel which is holding the color and alpha of the pixel beneath our mouse in the AARRGGBB format. Unfortunately, this is too much information. All we care about is the transparency of this pixel, or the AA part.
You could write a mathematical expression to obtain this section – in fact, int(pixel/Math.pow(16,6)) would work. This is a somewhat awkward statement, though, and slower performance-wise than another option we have: the bitwise unsigned right shift operator, >>>.
Our variable pixel is just a binary number to Flash. We normally write it in hexadecimal just to make it more readable. Without going into too much detail, every digit of a hexadecimal number can be represented by a string of four binary digits, each one either a 0 or a 1. (So, hexadecimal uses digits 0-f, decimal uses 0-9, and binary uses 0-1.)
Say we have a hexadecimal number, D4. In binary, this would be represented as 11010100. Notice how we use eight binary digits for the binary representation: four times as many as in hexadecimal.
With this is mind, let’s examine what the >>> operator actually does. Lets use our previous example, the hexadecimal number D4, or 0xD4 for clarity. Now let’s use >>> as so:
0xD4 >>> 4
Notice that 4 is a normal decimal representation of a number (there’s no “0x” at the start). This expression essentially shifts every binary digit in D4 four places to the right, and forgets about any digit that would go off the end of the number.
0xD4, in binary, is 11010100. Apply four shifts, and it becomes 1101. In hexadecimal, this is 0xD.
If you’re having trouble understanding this, imagine the binary digits as blocks sitting at the right side of a table. The >>> operator is just like pushing the blocks to the right. Here’s our original binary number:

Now here’s our new number, after we do 0xD4 >>> 4 :

Notice how after we shifted 0xD4 by 4 bits, we ended up with just 0xD? That’s not a coincidence. As said before, each hexadecimal digit is made up of 4 binary digits – so, each time we shift it to the right by 4, we essentially knock one hexadecimal digit off the end. You can probably see where we are going with this!
Back to our pixel, in 0xAARRGGBB format. If we shift it by 24, we are actually shifting by 6 hexadecimal digits. This means the RRGGBB portion gets knocked off, and we end up with just the 0xAA part left, which is our alpha component.
A quick numerical example: Say our pixel is equal to FF980000. In binary, this is 1111 1111 1001 1000 0000 0000 0000 0000. (Each group of 4 digits represents one hexadecimal digit.) When we shift this by 24, we simply end up with 1111 1111, or FF, our two transparency digits.
Take a look at it again:
useHandCursor = buttonMode = ((pixel >>> 24) > THRESHOLD);
Okay, the (pixel >>> 24) part makes sense now, but what about the rest?
It’s easy. We check whether our alpha component (the result of pixel >>> 24) is greater than the value of THRESHOLD (which is currently set to 0). If it is, useHandCursor and buttonMode are set to true, which will make the cursor change to a hand. This makes our image seem like a button.
If our alpha component is less than or equal to THRESHOLD, the cursor will remain normal, since the mouse is over a (semi-)transparent pixel. Since we have it set to 0, only fully transparent pixels will not be included as part of our button, but you could set this to, say, 0×80, and then it would display the hand cursor for anything that’s more than half transparent.
Step 8: The CLICK Event Listener
private function onClick(e:MouseEvent):void
{
if (!useHandCursor)
{
e.stopImmediatePropagation();
}
}
The final part of our BitmapButton class is the MouseEvent.CLICK event listener. This function will be called every time our image is clicked, no matter whether that pixel is transparent or not. (Changing the mouse cursor as we did before will not affect the actual MouseEvent.)
So, every time there is a click, we check the useHandCursor property. If it is true, this means the mouse is over a normal pixel in our image, and we don’t need to do anything. This makes sense – the event will then continue on to the event listener we added in Main.as. However, if useHandCursor is false, we have to do something to stop the event from continuing on to other event listeners.
For this, we use the stopImmediatePropagation() method that all Event objects have. Simply put, this stops the flow of the event, and no more event listeners will receive it. So, our event listener function in Main.as will never be called.
Warning: this could have a nasty side effect – any global event listener will not get the event either. If you are worried about this, you can try adding the line parent.dispatchEvent(e.clone()); after e.stopImmediatePropogation(). While this is beyond the scope of the tutorial, I recommend reading more about the event system here.
Conclusion
This wraps up our tutorial! Thanks for reading, and I hope you have learned something new.
A note of caution when using our BitmapButton class – other MouseEvents will still work as normal, since we only dealt with MouseEvent.CLICK. If you wanted, you could use the same technique we used for MouseEvent.CLICK and apply it to other events, such as MouseEvent.MOUSE_DOWN.
Our BitmapButton class allows us to quickly and easily make great buttons from bitmap images with transparency, as we did in this demo. If you have any questions, I’ll be glad to answer them, just leave a comment below.
View full post on Activetuts+

Building a button from a bitmap can be bothersome. If you’re using the Flash IDE, you can create a mask to determine which pixels are part of the button and which aren’t, but in any other workflow, the entire rectangle containing the bitmap – including any transparent pixels – will be clickable. In this tutorial, you’ll learn how to automatically make all transparent pixels unclickable, with just a few lines of code.
Final Result Preview
Let’s take a look at the final result we will be working towards:
Notice that the hand cursor only appears when hovering over the actual image; even the gaps in the hair don’t cause it to appear. And it’s not just for show: the button presses only register when clicking on these areas.
Introduction: What’s So Special?
At a first glance, the SWF above appears extremely simple. But look closer! Notice how in the demo above, a button press is only counted if you click somewhere on the actual image. This isn’t what would normally happen. Since a bitmap image is always a rectangle, clicking anywhere inside its rectangle normally would count as a button press. Take a look at the example below, where I have outlined the boundary rectangle of our image. Here, you can click anywhere inside the rectangle, including the transparent areas.
As you can see, this is not what we want! For starters, a user could accidentally click the button when he doesn’t mean to. In addition, it looks strange when a hand cursor appears over blank space. In this tutorial, you’ll learn how to easily correct these problems.
If you aren’t already familiar with Object-Oriented Programming or FlashDevelop, I recommend checking out the provided links before starting this tutorial.
Step 1: Getting Started
Open up FlashDevelop and create a new AS3 project (Project > New Project) and call it something like
BitmapButtonProj. On the right, open up the src folder and double-clickMain.asto open it. Add a new class to your project (right-click /src/ > Add > New Class) calledBitmapButtonStep 2: Embedding an Image
We now need an image to work with. Here is the one I’m using:
To use a bitmap image (such as a .jpeg file or a .png file) in Actionscript 3, we have to embed it. FlashDevelop makes this easy. After saving the above image somewhere, right-click the lib folder on the right, mouse over Add, and select the Library Asset option.
If you want to use your own image, be sure to select one with transparency.
The image you selected will now appear in the lib folder in FlashDevelop. Right-click the image and select Generate Embed Code.
public class Main extends Sprite { [Embed(source = "../lib/face.png")] private var ButtonImg:Class;This code
embedsthe image in to our project. Whenever you embed an image, you need to define on the next line a class that represents the image you embedded. In this case, our class is calledButtonImg.Step 3: Adding a TextField
Next, we’ll add a
TextFieldto display how many times we have clicked the button (which will be added next). Add this toMain():The code above simply formats the text to display at the top center of our project. Don’t miss how we declared our
TextFieldin line 15.Step 4: Adding the Button
This code should also go in
Main():When we instantiate our
BitmapButtonin line 36, we pass our embedded image class as a parameter. This will be used by theBitmapButtonclass. After this, we can simply treat ourBitmapButtoninstance like any otherDisplayObject: we can position it and add aMouseEvent.CLICKlistener as we normally would.Step 5: Making the Button Do Something
Add this event handler function to
Main.as:private function onButtonClick(e:MouseEvent):void { numClicks++; clicksTextField.text = "Button Presses: " + numClicks; }The final piece of code in our
Mainclass is the event listener for button clicks. In it, we simply add one to the number of clicks,numClicks,and update the text inclicksTextField.Step 6: The BitmapButton Constructor
Flip over to
BitmapButton.as. First, import these classes:Then, declare these:
You must make sure that the
BitmapButtonclass extendsSprite, since aBitmapby itself cannot have any mouse interactivity. (TheBitmapclass doesn’t extend InteractiveObject.)public function BitmapButton(ImageData:Class) { var image:Bitmap = new ImageData(); addChild(image); bitmapData = image.bitmapData; addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove); addEventListener(MouseEvent.CLICK, onClick); }In our
BitmapButtonconstructor, we accomplish a couple of important things.Bitmap, calledimage, from the image class passed as a parameter to the constructor.Bitmapas a child of ourSprite.bitmapDatato equal thebitmapDataof our image.CLICKandMOUSE_MOVEevent listeners.Step 7: The MOUSE_MOVE Event Listener
private function onMouseMove(e:MouseEvent):void { var pixel:uint = bitmapData.getPixel32(mouseX, mouseY); useHandCursor = buttonMode = ((pixel >>>24) > THRESHOLD); }Our simple looking
MOUSE_MOVEevent listener is the real brains behind our class. Its main purpose is to determine whether the mouse cursor is over a transparent pixel or not. Let’s look at how it does this.The getPixel32() Function
The first line gets the color and transparency of the pixel that the cursor is currently over. To do this, we use the
getPixel32()method of the variablebitmapData(which, remember, is the bitmap data representation of our image).We must pass an x- and y-coordinate to
getPixel32(), so naturally we use the mouse’s position.The call then returns a
uintrepresenting the color and transparency of the pixel at the location we supplied.Colors in Flash are normally treated as a hexadecimal
uintin the format RRGGBB. The first two digits represent the amount of red in the color, the next two, green, and the final two, blue. However,getPixel32()provides us with a specialuintrepresenting our pixel in the format AARRGGBB. Here, the first two digits represent the alpha, or the amount of transparency, from 00 (clear) to FF (opaque).So, for example,
FF980000would represent a fully opaque red color, while00980000would represent a fully transparent red color. You’ll typically see these represented as0xFF980000or0x0098000: the “0x” lets you (and Flash!) know that the number is in hexidecimal (0-f), rather than decimal (0-9).The Bitwise Unsigned Right Shift Operator
At this point, we have a
uintcalledpixelwhich is holding the color and alpha of the pixel beneath our mouse in the AARRGGBB format. Unfortunately, this is too much information. All we care about is the transparency of this pixel, or the AA part.You could write a mathematical expression to obtain this section – in fact,
int(pixel/Math.pow(16,6))would work. This is a somewhat awkward statement, though, and slower performance-wise than another option we have: the bitwise unsigned right shift operator,>>>.Our variable
pixelis just a binary number to Flash. We normally write it in hexadecimal just to make it more readable. Without going into too much detail, every digit of a hexadecimal number can be represented by a string of four binary digits, each one either a 0 or a 1. (So, hexadecimal uses digits 0-f, decimal uses 0-9, and binary uses 0-1.)Say we have a hexadecimal number, D4. In binary, this would be represented as 11010100. Notice how we use eight binary digits for the binary representation: four times as many as in hexadecimal.
With this is mind, let’s examine what the
>>>operator actually does. Lets use our previous example, the hexadecimal number D4, or0xD4for clarity. Now let’s use>>>as so:Notice that 4 is a normal decimal representation of a number (there’s no “0x” at the start). This expression essentially shifts every binary digit in D4 four places to the right, and forgets about any digit that would go off the end of the number.
0xD4, in binary, is 11010100. Apply four shifts, and it becomes 1101. In hexadecimal, this is 0xD.
If you’re having trouble understanding this, imagine the binary digits as blocks sitting at the right side of a table. The
>>>operator is just like pushing the blocks to the right. Here’s our original binary number:Now here’s our new number, after we do
0xD4 >>> 4:Notice how after we shifted 0xD4 by 4 bits, we ended up with just 0xD? That’s not a coincidence. As said before, each hexadecimal digit is made up of 4 binary digits – so, each time we shift it to the right by 4, we essentially knock one hexadecimal digit off the end. You can probably see where we are going with this!
Back to our pixel, in 0xAARRGGBB format. If we shift it by 24, we are actually shifting by 6 hexadecimal digits. This means the RRGGBB portion gets knocked off, and we end up with just the 0xAA part left, which is our alpha component.
A quick numerical example: Say our pixel is equal to FF980000. In binary, this is 1111 1111 1001 1000 0000 0000 0000 0000. (Each group of 4 digits represents one hexadecimal digit.) When we shift this by 24, we simply end up with 1111 1111, or FF, our two transparency digits.
Take a look at it again:
Okay, the
(pixel >>> 24)part makes sense now, but what about the rest?It’s easy. We check whether our alpha component (the result of
pixel >>> 24) is greater than the value ofTHRESHOLD(which is currently set to 0). If it is,useHandCursorandbuttonModeare set to true, which will make the cursor change to a hand. This makes our image seem like a button.If our alpha component is less than or equal to
THRESHOLD, the cursor will remain normal, since the mouse is over a (semi-)transparent pixel. Since we have it set to 0, only fully transparent pixels will not be included as part of our button, but you could set this to, say, 0×80, and then it would display the hand cursor for anything that’s more than half transparent.Step 8: The CLICK Event Listener
private function onClick(e:MouseEvent):void { if (!useHandCursor) { e.stopImmediatePropagation(); } }The final part of our
BitmapButtonclass is theMouseEvent.CLICKevent listener. This function will be called every time our image is clicked, no matter whether that pixel is transparent or not. (Changing the mouse cursor as we did before will not affect the actualMouseEvent.)So, every time there is a click, we check the
useHandCursorproperty. If it istrue, this means the mouse is over a normal pixel in our image, and we don’t need to do anything. This makes sense – the event will then continue on to the event listener we added inMain.as. However, ifuseHandCursoris false, we have to do something to stop the event from continuing on to other event listeners.For this, we use the
stopImmediatePropagation()method that allEventobjects have. Simply put, this stops the flow of the event, and no more event listeners will receive it. So, our event listener function inMain.aswill never be called.Warning: this could have a nasty side effect – any global event listener will not get the event either. If you are worried about this, you can try adding the line
parent.dispatchEvent(e.clone());aftere.stopImmediatePropogation(). While this is beyond the scope of the tutorial, I recommend reading more about the event system here.Conclusion
This wraps up our tutorial! Thanks for reading, and I hope you have learned something new.
A note of caution when using our
BitmapButtonclass – otherMouseEventswill still work as normal, since we only dealt withMouseEvent.CLICK. If you wanted, you could use the same technique we used forMouseEvent.CLICKand apply it to other events, such asMouseEvent.MOUSE_DOWN.Our
BitmapButtonclass allows us to quickly and easily make great buttons from bitmap images with transparency, as we did in this demo. If you have any questions, I’ll be glad to answer them, just leave a comment below.Are you looking to start your new year with a fresh set of prints to help promote your design business? Today, our friends at UPrinting are kicking off 2012 by giving away business cards, posters, or postcards to 36 lucky Tuts+ readers. To enter, all you have to do is submit your entry using the form below and select which prize you would prefer.
If you are a frequent reader of our site, chances are, you are already familiar with UPrinting. They are an online printer that offers business cards, poster printing, postcard printing, and much more. UPrinting is a frequent sponsor of this site and we are very excited to partner with them on another giveaway.
Submit Your Entry
Up for Grabs
Today, UPrinting is giving you several options to choose from. You can enter to win 500 standard business cards, 100 postcards, or 1 poster print. The choice is yours! More details can be found below.
500 Standard Business Cards
2" x 3.5" US Standard, 2" x 2" Square, 1.75" x 3.5" Slim
14pt Cardstock Gloss / Matte, 13pt Cardstock Uncoated
Front and Back Printing
3 Business Days Turnaround time
1 Poster Print
18" x 24"
Semi Gloss / High Gloss
1 Business day print turnaround time
100 Postcards
5" x 7"
14pt Cardstock Gloss
Front Only Printing
2 Business days print turnaround time
Rules
We covered collision detection between an infinite line and circle in our previous Quick Tip. However, the issue that arose was that the line extends further than the visible line segment; in fact, it extends into a hyperplane. In this Quick Tip, we shall limit our collision detection to that of a line segment only.
Final Result Preview
We shall work toward this result:
Click the Restart button to reposition the circles at the top of the stage.
Step 1: Two Approaches
There are numerous approaches to limit collision detection to within a line segment. We shall look at two approaches this time. The first approach is a little more rigorous mathematically than the second one, but these are concepts which, if you grasp successfully, will surely benefit you in the future. Both approaches manipulate the dot product’s characteristic of being a measure of how parallel two given vectors are.
Let’s have a look at the first approach. Suppose A and B are vectors. If A and B are parallel – or at least pointing in the same direction – the dot product between A and B will produce a positive number. If A and B are pointing directly opposite each other – or at least pointing in opposing directions – the dot product between A and B will produce a negative number. If A and B are orthogonal (forming 90° to each other) then the dot product will produce 0.
The diagram below summarises this description.
Step 2: Relate Dot Product to Conditions
We’ll need to form vectors B and C from both ends of the line segment so that their dot product with the line segment’s vector, A, can determine whether the circle is within the segment.
Observe the diagram below. If the circle is within the segment, then the value of the dot product between A and B is positive and that between A and C is negative.
The diagram below shows how the dot product changes depending on whether the circle is beyond or within the line segment. Note the differences in the value of the dot product.
Also note that “within the line segment” does not mean that the circle is necessarily intersecting the line segment, just that it falls within the two thin lines on the diagram above.
So when collision occurs between line and circle, as we have seen in the previous Quick Tip, we have to further investigate whether the circle is positioned within the line segment. If it is, then we know for sure that there is a genuine intersection.
Step 3: Implementation
Step 2 explained the concept we use to restrict collision detection to be within the line segment. However, there’s still a flaw in the precision. You see, the area defined is a little tilted; we should aim to use the area defined according to the diagram below.
This is easy: we simply calculate D as the horizontal projection of A. Then, instead of using A, we use D to dot product with B and C. All the conditions as explained in Step 2 still stand, but instead of a tilted segment, we have defined a vertical area.
This correction can be visually appreciated if the circle is large; if the circle were small, its center would be so close to the line that this visual flaw would be hard to detect, so we could get away with using that slightly tilted area and save ourselves some processing power.
Nevertheless, I’ll try to do things the correct way. You can pick your approach by modifying the condition slightly.
Step 4: Implementation
The first Actionscript snippet here sets up vector D (
v_line_onX)Note: We’re using classes from my previous tutorials here. Vector2D was introduced in Gravity in Action, but you don’t need to read that to use the class, it’s included in the source download.
The second Actionscript snippet here sets up B (
c1_circle) and C (c2_circle) and checks for the collision and whether the circle is inside the segment or not.private function refresh(e:Event):void { for (var i:int = 0; i < circles.length; i++) { //calculating line's perpendicular distance to ball var c1_circle:Vector2D = new Vector2D(circles[i].x - x1, circles[i].y - y1); var c1_circle_onNormal:Number = c1_circle.projectionOn(leftNormal); //Att2: get vector from c2 to circle var c2_circle:Vector2D = new Vector2D(circles[i].x - x2, circles[i].y - y2); circles[i].y += 2; if ( c1_circle_onNormal <= circles[i].radius && v_line_onX.dotProduct(c1_circle) > 0 && v_line_onX.dotProduct(c2_circle) < 0 ){ //if collision happened, undo movement circles[i].y -= 2; } } }Step 5: The Result
Here’s the result for the first approach. Click on the button to reset positions of all circles to the top of stage.
Step 6: Second Approach
The second approach is much simpler. I’ll try to work backwards from the end this time around.
Observe the diagram below. The line segment is from c1 to c2. It’s clear that
collide1andcollide3are both outside the line segment, and that onlycollide2is within the line segment.Let v1, v2 and v3 be vectors from c1 to respective circles. Only v2 and v3 are parallel – or at least pointing in similar directions to the line vector (c1 to c2). By checking for a positive value in the dot product between the line vector and each of those vectors from c1 to the corresponding circle centers (v1, v2, v3), we can easily determine that collide1 is beyond the line segment. In other words,
c1 . v1 < 0.Next, we shall devise a method to determine that collide3 is outside of the line segment. This should be easy. It's obvious that v3's projection along the line vector will exceed the length of line segment. We shall use this characteristic to weed off collide3.
So let me summarise the second approach:
Step 7: Implementation
Here's the ActionScript implementation of the above:
private function refresh(e:Event):void { for (var i:int = 0; i < circles.length; i++) { //calculating line's perpendicular distance to ball var c1_circle:Vector2D = new Vector2D(circles[i].x - x1, circles[i].y - y1); var c1_circle_onNormal:Number = c1_circle.projectionOn(leftNormal); //Att2: getting the relevant vectors var c1_circle_onLine:Number = c1_circle.projectionOn(line); circles[i].y += 2; if ( Math.abs(c1_circle_onNormal) <= circles[i].radius && line.dotProduct(c1_circle) > 0 && c1_circle_onLine < line.getMagnitude() ){ //if collision happened, undo movement circles[i].y -= 2; } } }Step 8: The Result
Essentially, it will produce the same result as the previous but since there is a few lines of code shorter in the second approach, I guess its better.
Conclusion
Hope this has helped. Thanks for reading. Next up, we'll look at collision reaction.
Flash Player 10 introduced new low-level APIs for manipulating audio with AS3. In this tutorial, exclusive to Tuts+ Premium members, you’ll learn about these APIs and how they work, and use them to create a simple app that can play MP3s in reverse.
Premium Preview
Click to view the demo
Click here to view a preview of the SWF we’ll be building in this tutorial. Click on the “Play” button to play the sound. You can’t really tell by looking at or listening to it, but this isn’t just an MP3 loaded and then played normally; the MP3 is being used as a sound source and samples are fed dynamically to the Sound engine. To help prove it, the “Reverse” button will play the same sound, just in reverse. There is no sleight of hand here: there is only one MP3 loaded and the reversal effect is computed on the fly.
If you’re not yet a Premium member, you can still read the first few steps of the tutorial. Members can, of course, access the full thing right away!
Tuts+ Premium Membership
We run a Premium membership system which periodically gives members access to extra tutorials, like this one! You’ll also get access to Psd Premium, Vector Premium, Audio Premium, Net Premium, Ae Premium, Cg Premium, Photo Premium, and the new Mobile Premium too. If you’re a Premium member, you can log in and download the tutorial. If you’re not a member, you can of course join today!
Also, don’t forget to follow @envatoactive on twitter, circle us on Google+, like us on Facebook, and grab the Activetuts+ RSS Feed to stay up to date with the latest tutorials and articles.
Stop using static menus! Most players immediately base their initial impression of a Flash game on the menu that they see when they load it. Stand out from the crowd with an active menu!
This tutorial was first posted in December 2011, but has since been updated with extra steps that explain how to make the code more flexible!
Final Result Preview
Introduction: Static vs Active
The word “static” essentially means lacking in change. The majority of menus we see throughout web games are lacking in change, you simply press Play and the game starts. Menus like that are overused and show little creativity or innovation.
To make a menu “active” we must continuously cause change. So in this tutorial that is exactly what we are going to accomplish: a menu that continuously changes.
Step 1: Setting Up
The first thing we are going to need to create is a new Flash File (ActionScript 3.0). Set its width to 650px, its height to 350px, and the frames per second to 30. The background color can be left as white.
Now save the file; you can name it whatever you please, but I named mine
menuSlides.fla.In the next section we will create the nine MovieClips used in the menu. For reference, here is a list of all the colors used throughout the tutorial:
Step 2: Creating the Slide MovieClips
To start with we will create the slides used in the transitions, but before we begin let’s turn on some very useful Flash features.
Right-Click the stage and select Grid > Show Grid. By default it will create a 10px by 10px grid across the stage. Next, right-click the stage again and this time select Snapping > Snap to Grid.
Now we can begin drawing! Select the Rectangle Tool and draw a Light Gold rectangle, 650px wide and 350px tall (you can Alt-click on the stage to make this easier). Now change the color to Gold and draw groups of three squares, each 20x20px, to form the shape of an L in each corner,:
Select the whole stage, right-click and choose Convert to Symbol. Name the MovieClip
goldSlideand make sure that the type is MovieClip and the registration is top-left.To save time and make things a whole lot easier, right-click the
goldSlideMovieClip in the Library and select Duplicate Symbol three times to make three more copies. Change the colors in the new MovieClips to blue, green and red, then rename the MovieClips toblueSlide,greenSlideandredSlide.Before we continue we should add some text to each slide. On goldSlide write PLAY, on blueSlide write INSTRUCTIONS, on greenSlide write OPTIONS and on redSlide write CREDITS.
Now that we have the text in place we can break it apart by right-clicking on it and selecting Break Apart twice; this will break the text down to a fill which will transition more smoothly. Plus as a bonus there will be no need to embed a font if you are just using it for the menu!
The Buttons
Now that we have drawn the 4 slides we can focus on the
sideButtonMovieClip that is used to move the slides either left or right.First, draw a rectangle 30x60px with only a stroke (no fill), then draw diagonal lines 45 degrees from the top-right and bottom-right corners until they snap together in the middle of the opposite side. Now apply a Matte Grey fill to the triangle:
Next, delete the lines, then right-click the triangle and select Convert to Symbol. Name it
sideButton, set the type to Button and make sure the registration is in the top-left corner.Now insert 3 keyframes in the timeline by right-clicking the timeline and selecting Insert Keyframe. On the Up frame, select the fill of the triangle, go to the Windows tab and select Color. Change the Alpha to 50%. On the Over Frame repeat the same process, but this time set the alpha to 75%.
Now we can begin on the four numbered circle buttons, for jumping directly to a particular slide.
To start draw a white 30px circle with no stroke. Convert it to a symbol, name it
circleOne, and set its type to Button and its registration point to the center. Insert three keyframes like we did before and then go to the Up frame.Draw a black 25px circle with no stroke and center it to the middle through the coordinates or by using the Align menu. Next deselect the black circle, then reselect it and delete it. You should now have a white ring remaining. Now grab the text tool and put a white “1″ in the center of the ring. Then break this number apart until it is a fill.
Go to the Over frame and draw a black “1″. Center it and break it apart until it becomes a fill. Now deselect and reselect the fill, then delete it. Select everything on the frame and copy it, then go to the Down frame, select everything on it and hit delete. Paste in what we have copied.
Now create three more circle MovieClips, following the same process, for the numbers 2, 3 and 4.
Step 3: Positioning the MovieClips
Okay, we’re almost half-way done! First drag all of the slides onto the stage and position them with the following coordinates:
Now drag and drop two copies of the sideButton. The first copy should be positioned at (10,145); before we can position the second copy we must first flip it!
Select the second copy and press Ctrl-T. Change the left-right to -100% and leave the up-down at 100%. Now move the second copy to (640,145).
Finally drag and drop the four circle MovieClips and position them as so:
Your stage should now look like this:
The blue, green and red slides are hidden just off to the right of the stage. Now select everything on the stage and convert to a symbol. Name it
menuSlidesMC, set the type to MovieClip and the registration to the top-left corner, and export it for ActionScript asMenuSlidesMC.Before we finish we must give each of the MovieClips inside
menuSlidesMCan instance name. Select each slide in the order they appear from the left and name themslide1,slide2,slide3andslide4respectively. Name the circle buttonsone,two,threeandfour, and finally name the side buttonsleftandright.Step 4: Setting Up the Classes
Now that all of our MovieClips have been created we can start setting up the two classes we are going to use.
First go to your Flash file’s Properties and set its class to
menuSlides; then, create a new ActionScript 3.0 file and save it asmenuSlides.as.Now copy the following code into it; I will explain it after:
package{ import flash.display.MovieClip; import flash.events.Event; import flash.events.MouseEvent; public class menuSlides extends MovieClip{ public var menuSlidesMC:MenuSlidesMC = new MenuSlidesMC(); public function menuSlides(){ addChild(menuSlidesMC); } } }Pretty basic – it’s a document class, into which we imported the MovieClips and Events we will use. Then we created an instance of
MenuSlidesMC, and added it to the stage.Now create a new ActionScript 3.0 file for the
menuSlidesMCinstance. Save it asMenuSlidesMC.asand copy the following code into it:package{ import flash.display.MovieClip; import flash.events.Event; import flash.events.MouseEvent; public class MenuSlidesMC extends MovieClip{ public var speed:Number = new Number(); public var activeSlide:Number = new Number(); public function MenuSlidesMC(){ speed = 10; activeSlide = 1; addEventListener(MouseEvent.CLICK, slidesClick); addEventListener(Event.ENTER_FRAME, slidesMove); } } }Just like last time, we imported what we are going to need, but we created two number variables. The first variable,
speed, is actually how many pixels the slides are moved by each frame. (Note: this number has to evenly divide into your stage’s width to give a smooth transition). The second variable,activeSlide, tells us which slide is currently set to be on screen.We also added two event listeners for functions we are going to create; one of them is called on a mouse click, and the other is called at the beginning of every frame.
Step 5: Creating the Event Handler Functions
To begin we will get the mouse click function out of the way. Start by creating a public function named
slidesClick():public function slidesClick(event:MouseEvent):void { }Next we will create some if-statements regarding the
event.target.name. Basically, this property stores the name of the object that was targeted by the mouse click. We can use this to check which button is pressed:if(event.target.name == "left"){ if(activeSlide>1){ activeSlide-=1; } }else if(event.target.name == "right"){ if(activeSlide<4){ activeSlide+=1; } } if(event.target.name == "one"){ activeSlide=1; }else if(event.target.name == "two"){ activeSlide=2; }if(event.target.name == "three"){ activeSlide=3; }else if(event.target.name == "four"){ activeSlide=4; }The code above goes in the
slidesClick()function. The first set of if-statements are for the left and right side buttons; they increase or decrease the value ofactiveSlide, but never allow the value to become less than 1 or greater than 4 (since we only have four slides). The second set of if-statements are for the circle buttons; instead of just incrementing or decrementing the value ofactiveSlidethey set it to the selected value.Now let’s begin with the
ENTER_FRAMEhandler function:public function slidesMove(event:Event):void { }Add the
slidesMove()function below yourslidesClick()function and we’ll start adding some code to it. First, we’ll use aswitchto check which slide should be on the screen, based on the value ofactiveSlide:switch (activeSlide){ case 1: break; case 2: break; case 3: break; case 4: break; }Now in each case we will create an if/else block that will check that slide’s current x-position, and move all of the slides either left, right, or not at all, depending on where the desired slide currently sits.
The first case looks like this:
if(slide1.x<0){ slide1.x+=speed; slide2.x+=speed; slide3.x+=speed; slide4.x+=speed; }else if(slide1.x>0){ slide1.x-=speed; slide2.x-=speed; slide3.x-=speed; slide4.x-=speed; }Now all we have to do is repeat the same process for the other cases! After you are done your swtich should look like this:
switch (activeSlide){ case 1: if(slide1.x<0){ slide1.x+=speed; slide2.x+=speed; slide3.x+=speed; slide4.x+=speed; }else if(slide1.x>0){ slide1.x-=speed; slide2.x-=speed; slide3.x-=speed; slide4.x-=speed; } break; case 2: if(slide2.x<0){ slide1.x+=speed; slide2.x+=speed; slide3.x+=speed; slide4.x+=speed; }else if(slide2.x>0){ slide1.x-=speed; slide2.x-=speed; slide3.x-=speed; slide4.x-=speed; } break; case 3: if(slide3.x<0){ slide1.x+=speed; slide2.x+=speed; slide3.x+=speed; slide4.x+=speed; }else if(slide3.x>0){ slide1.x-=speed; slide2.x-=speed; slide3.x-=speed; slide4.x-=speed; } break; case 4: if(slide4.x<0){ slide1.x+=speed; slide2.x+=speed; slide3.x+=speed; slide4.x+=speed; }else if(slide4.x>0){ slide1.x-=speed; slide2.x-=speed; slide3.x-=speed; slide4.x-=speed; } break; }And that’s it! We are all finished with the code and the menu should be working great right now.
…But wait, what if we want to add more slides or take some away?
Step 6: Adding Slides to an Array
At the moment our code isn’t very flexible due to all of those hard-coded
ifstatements. So let’s do something bold: delete all of the code in the slidesMove() function because we will no longer be needing it, and also delete the if-statements for the circle buttons as we are going to optimize those as well.Now declare a new variable (underneath
speedandactiveSlides):The first variable,
slidesArray, will be an array that contains all of our slides, which will allow us to access them by referencing an item in the array (so we can useslidesArray[2]instead ofslide3).One thing to note is that the first item in an array is given an index of
0, so we will have to make some changes to our instance names.Select each slide in the order they appear from the left and name them
slide0,slide1,slide2andslide3, respectively. And to help us cut down on the number of lines of code we use, select each circle button in the order they appear from the left and name themcircle0,circle1,circle2andcircle3, respectively.If you are going to add more slides and buttons, now is the time to do so. Just position the extra slides at the end of the row of slides, then give them instance names following the same order. Then do the same for the circle buttons.
Now that we have the instance names correct we must add the slides to the array. Do so by adding the following code to your constructor:
Now the slides are in the array and can be accessed by their index in the array. For example,
slidesArray[0]is equivalent toslide0because that is the first item in the list.Next, inside the “right” else-if statement, change the condition to:
if(activeSlide < slidesArray.length-1){The value of
slidesArray.lengthis equal to the number of elements in the array, so this new condition will now allow us to press the button and shift the slides over as long as the active slide is not the final slide.Step 7: Handling Circle Button Presses
Now, when a circle button is clicked, we need to figure out which one it is (and which slide it refers to).
Create an array to hold all the circle buttons. First, define it, beneath the slide array:
Then, add the circle buttons to the array in the constructor:
Now, move to the
slidesClick()function, underneath the whole if-else block. We’re going to check whether the button clicked is in the circle buttons array:if (circlesArray.indexOf(event.target) != -1) { }The array’s indexOf() function checks to see whether an object is in the array; if it’s not, it returns
-1. So, we’re checking to see whether it’s not equal to-1, which will check to see whether it is in the array.Assuming it is, then the
indexOf()function will return the index of the button within the circle buttons array – so, ifcircle3was clicked,circlesArray.indexOf(event.target)will be equal to3. This means we can just setactiveSlideto 3, and we’re done!if (circlesArray.indexOf(event.target) != -1) { activeSlide = circlesArray.indexOf(event.target); }Step 8: Moving the Slides
The only thing left to do is move all of the slides. Begin by adding the same loop as we had before, in the
slidesMove()function:for(var i:int = 0; i < slidesArray.length; i++){ }An if-else statement needs to be added now; this will use the variable
activeSlideto select a slide out of the array and check where its x-position is, just like before.if(slidesArray[activeSlide].x<0){ }else if(slidesArray[activeSlide].x>0){ }Since
activeSlideis a number,slidesArray[activeSlide]refers to one specific slide, soslidesArray[activeSlide].xis equal to that slide’s x-position.In the first case we will add a
forloop to move all of the movie clips to the right, and in the second case we will add aforloop to move all of the movie clips to the left.Right:
for(var j:int = 0; j < slidesArray.length; j++){ slidesArray[j].x+=speed; }Left:
for(var k:int = 0; k < slidesArray.length; k++){ slidesArray[k].x-=speed; }If you test this now, you will notice that our optimised code has lead to a much zippier interface!
Step 9: Taking It Further
If you wanted to take this even further, you could use a
forloop to position the slides and the circles, rather than needing to drag and drop them in the Flash IDE. For example, to position the slides, we’d first positionslide0in the constructor:Then, we’d loop through all the other slides, starting at
slide1:slidesArray = [slide0, slide1, slide2, slide3, slide4, slide5]; slidesArray[0].x = 0; slidesArray[0].y = 0; for (var i:int = 1; i < slidesArray.length; i++) { }We can give all the slides an y-position of 0:
slidesArray = [slide0, slide1, slide2, slide3, slide4, slide5]; slidesArray[0].x = 0; slidesArray[0].y = 0; for (var i:int = 1; i < slidesArray.length; i++) { slidesArray[i].y = 0; }…and then we can set each slide’s x-position to be 620px to the right of the slide before it:
slidesArray = [slide0, slide1, slide2, slide3, slide4, slide5]; slidesArray[0].x = 0; slidesArray[0].y = 0; for (var i:int = 1; i < slidesArray.length; i++) { slidesArray[i].x = slidesArray[i-1].x + 620; slidesArray[i].y = 0; }If your slides aren’t 620px wide, you can even detect their width automatically!
slidesArray = [slide0, slide1, slide2, slide3, slide4, slide5]; slidesArray[0].x = 0; slidesArray[0].y = 0; for (var i:int = 1; i < slidesArray.length; i++) { slidesArray[i].x = slidesArray[i-1].x + slidesArray[i-1].width; slidesArray[i].y = 0; }You can do the same thing with the circle buttons, but I’ll leave that up to you to experiment with.
The great thing about this is, you can add as many slides as you want to the menu; all you have to do is add them to the array, and they’ll be dealt with by this code.
(You can remove slides from the array, too, but they won’t be affected by any of the code, so you’ll probably need to reposition them in the Flash IDE.)
Conclusion
Thank you for taking the time to read through the tutorial, I hope it was helpful and that you learned a little something about active game menus.
In this mini-series, we’re creating a spaceship game where the main control is via the microphone: shout louder to make the ship fly higher. So far, we’ve created all the required graphical elements for the game. Now, it’s time to work on our code. We’ve got a lot to do, so let’s get started!
Final Result Preview
For the purposes of keeping the tutorial simple, we have done no error checking for the existence of a microphone. This means that, if you do not have a microphone plugged in, turned on, and set up for use with Flash, the game won’t work: you’ll get an Error #1009. Check the comments in
Player.asin the source files for information on how to deal with this.A Small Note:
For some reason Flash Builder isn’t working perfectly. In particular, it’s ignoring code hinting – but, nevertheless, one should be able to follow the tutorial.
Project Setup
Don’t like ads? Download the screencast, or subscribe to Activetuts+ screencasts via iTunes!
Creating the Player
Don’t like ads? Download the screencast, or subscribe to Activetuts+ screencasts via iTunes!
Creating Space Objects
Don’t like ads? Download the screencast, or subscribe to Activetuts+ screencasts via iTunes!
Player Animation and Collision Response
Don’t like ads? Download the screencast, or subscribe to Activetuts+ screencasts via iTunes!
Setting Up Scores and Lives
Don’t like ads? Download the screencast, or subscribe to Activetuts+ screencasts via iTunes!
Creating Our Background
Don’t like ads? Download the screencast, or subscribe to Activetuts+ screencasts via iTunes!
Cleaning Up Our Game
Don’t like ads? Download the screencast, or subscribe to Activetuts+ screencasts via iTunes!
Creating the Game Over Screen
Don’t like ads? Download the screencast, or subscribe to Activetuts+ screencasts via iTunes!
Conclusion
Thank you for watching. It’s been a huge tutorial, and afterwards I would have liked to do some things differently:
Nevertheless, I hope you enjoyed this tutorial, and most importantly learned something from it.
Interested in game design? This weekend, we feature an interesting look at game design in the NES game Megaman and its SNES sequel Megaman X, through a video by Egoraptor.
Watch the Video
Many games, particularly modern games aimed at a more casual audience, rely on tutorial missions and popups to teach you how to play the game; a few years ago, it was more common for games to be packed with a thick manual that explained all the controls and objectives. But there is a third option: letting the player learn through actually playing the game.
In this video, Egoraptor examines how Megaman did a great job of teaching through gameplay, and how Megaman X refined this even further.
Warning: there’s a lot of profanity in this, so it might not be safe for work.
Hat tip to Jesse Freeman for posting a link to this video on Google+!
If you’re interested in this subject, and would like to learn how to apply these lessons to app design, take a look at Dan Cook’s presentation, The Princess Rescuing Application.
In my previous Quick Tip, we looked at the idea of collision detection in general, and specifically at detecting collisions between a pair of circles. In this Quick Tip, we’ll look at detecting a collision between a circle and a line.
This is the result that we will work on. Click the Restart button to reposition all circles at the top of the stage and watch them fall down.
Note that the circles collide with the line even outside of the segment that is drawn. My next Quick Tip will show how to fix this.
Step 1: The General Idea
To check whether any circle has collided with a line, we have to check the perpendicular length from the line to circle. Observe the diagram below.
It is clear from the diagram above that cases 3 and 4 should detect a collision between the circle and the line. So we conclude that if the perpendicular length (marked in red) is equal or less than circle’s radius, a collision happened due to the circle touching or overlapping the line. Question is, how do we calculate this perpendicular length? Well, Vectors can help to simplify our problem.
Step 2: Line Normal
In order to draw a line on stage, we need two coordinates (c1 and c2). The line drawn from c1 to c2 will form a vector pointing to c2 (Note the direction of the arrow).
Next, we need to find the line’s normal. The line’s normal is another line that makes 90° with the original line, and intersects with it at a point. Despite the line’s normal being yet another line, the normal’s vector form can be further identified as the left or right normal relative to the line’s vector. The left normal is the line vector itself, rotated -90°. The right normal is the same but rotated 90°. Remember, the y-axis in Flash’s coordinate space is inverted compared to the y-axis on a typical graph – so positive rotation is clockwise and negative rotation is counter-clockwise.
Step 3: Projection on Left Normal
The left normal is used in our attempt to calculate the perpendicular length between the circle and the line. Details can be found in the diagram below. A refers to a vector pointing from c1 to the circle. The perpendicular length actually refers to vector A’s projection on the left normal. We derive this projection by using trigonometry: it is
|A| Cosine (theta), where|A|refers to the magnitude of the vector A.The simplest approach is to make use of vector operations, specifically the dot product. Starting from the equation of the dot product, we rearrange the terms so that we arrive at the second expression shown below. Note that the right side of the second equation is the projection that we wanted to calculate!
Also note the left and right side of the equation will ultimately produce the same result, although different in their approaches. So instead of using the right side of the equation, we can opt for the left side of equation. To easily arrive at the end result, it is favourable to use the left because variables can be easily resolved. If we insist on using the right of equation, we’d have to push ActionScript through rigourous Mathematical work in calculating the angle theta. We conclude with the diagram below.
(*Additional note: If the circle falls below line vector, the perpendicular length calculated from the formula in above diagram will produce a negative value.)
Step 4: Implementing Circle-Line Collision Detection
Now that we have understood the approach mathematically, let’s proceed to implement it in ActionScript. In this first section, note the line’s vector is being rotated -90° to form the left normal.
In this second section, I have highlighted the calculations mentioned and the condition to check for collision between circle and line.
private function refresh(e:Event):void { for (var i:int = 0; i < circles.length; i++) { //calculating line's perpendicular distance to ball var c1_circle:Vector2D = new Vector2D(circles[i].x - x1, circles[i].y - y1); var c1_circle_onNormal:Number = c1_circle.projectionOn(leftNormal); circles[i].y += 2; //if collision happened, undo movement if (Math.abs(c1_circle_onNormal) <= circles[i].radius){ circles[i].y -= 2; } } }For those who’d like to investigate further, the following are excerpts of methods used in
Vector.as/** * Method to obtain the projection of current vector on a given axis * @param axis An axis where vector is projected on * @return The projection length of current vector on given axis */ public function projectionOn(axis:Vector2D):Number { return this.dotProduct(axis.normalise()) }/** * Method to perform dot product with another vector * @param vector2 A vector to perform dot product with current vector * @return A scalar number of dot product */ public function dotProduct(vector2:Vector2D):Number { var componentX:Number = this._vecX * vector2.x; var componentY:Number = this._vecY * vector2.y; return componentX+componentY; }/** * Method to obtain vector unit of current vector * @return A copy of normalised vector */ public function normalise():Vector2D { return new Vector2D(this._vecX/this.getMagnitude(), this._vecY/this.getMagnitude()) }/** * Method to obtain current magnitude of vector * @return Magnitude of type Number */ public function getMagnitude():Number { return Math.sqrt(_vecX * _vecX + _vecY * _vecY); }Step 5: The Result
Press the Restart button to reposition all circles at the top of stage. Note that the collision is between the whole line (including the section not drawn) and the circles. In order to limit collision to line segment only, stay tuned for the next Quick Tip.
Conclusion
Thanks for reading. Stay tuned for the next tip.
Something a little different for you this week: a Flash slideshow framework. As well as finding it directly useful for any presentations you may give, Premium members can download the full source code, and take it apart to see how the Greensock tweening libraries were used to put it together.
Preview
There are three example slideshows created with the framework:
A simple image rotator (with keyboard control).
A grid slideshow (also with keyboard control).
A spread slideshow (the slides scale and rotate to come into focus).
The slideshows support images, SWFs, and FLV videos, and are all defined by a single simple XML file.
Download
All the files you need to actually use the slideshows are available in this free ZIP file.
If you’re a Premium member, you can download the source files as well; these use Greensock’s LoaderMax and TweenLite libraries, so make excellent examples. You could use these files as examples of how to use those libraries, or could extend them to add your own flair or new features.
Active Premium Membership
We run a Premium membership system which periodically gives members access to extra tutorials, like this one! You’ll also get access to Psd Premium, Vector Premium, Audio Premium, Net Premium, Ae Premium, Cg Premium, Photo Premium, and Mobile Premium. If you’re a Premium member, you can log in and download the tutorial. If you’re not a member, you can of course join today!
Each month, we bring together a selection of the best tutorials and articles from across the whole Tuts+ network. Whether you’d like to read the top posts from your favourite site, or would like to start learning something completely new, this is the best place to start!
Psdtuts+ — Photoshop Tutorials
Create a Festive Cocktail Using Photoshop’s 3D Capabilities
For many of our readers, this time of year is filled with family, friends, and celebration. In this tutorial, we will explain how to create a festive cocktail using Photoshop’s 3D capabilities just in time for your New Year’s celebrations. Let’s get started!
Visit Article
Create a Dark, Conceptual Photo Manipulation With Stock Photography
In this tutorial we will be teaching how to integrate elements from different sources to create a realistic photo manipulation with dark and conceptual elements. You will learn some lighting and blending techniques as well as some interesting post-production tips. Let’s get started!
Visit Article
Create High-End Action Figure Packaging – Tuts + Premium Tutorial
With collectables, the packaging of the product is often as important as the craftsmanship of the product itself. In this two-part Tuts+ Premium tutorial, author Tim Kyde will explain how to create packaging for a high-end 1/6 scale action figure. Part 1 of this tutorial will explain how to shoot your own photography and create a print-ready outer sleeve and inner packaging for our action figure. This tutorial is available exclusively to Tuts+ Premium Members — Join Now to get started!
Visit Article
Nettuts+ — Web Development Tutorials
Wrangling with the Facebook Graph API
Have you ever wanted to learn how to make your applications more social with Facebook? It’s much easier than you think!
Visit Article
From Idea to Market: How We Built Gradient
Retracing the steps you’ve taken is a helpful way to understand how well you’ve executed your vision – whatever that might be. What could you have done better? What should have been avoided? Today, I’ll share what we’ve learned (and are still learning) while crafting Gradient. It’s an experience that has changed everything for us.
Visit Article
Should You Learn CoffeeScript?
I’d imagine that I represent a large portion of the web development community. I’m very intrigued by CoffeeScript; I’ve even learned the syntax and used it in a few demos. However, I haven’t yet taken the plunge and used it in a real project. It comes down to this one question for me: is CoffeeScript something that is truly worth investing time and effort into learning?
Visit Article
Vectortuts+ — Illustrator Tutorials
Outstanding Tutorials, Quick Tips, Articles and Interviews from Vectortuts+ in 2011
As the year comes to an end and we pack up our vector tools for some well deserved rest and relaxation, let’s take a look back at some of the best and most inspiring Vectortuts+ articles and tutorials for 2011.
Visit Article
Community Project: 2012 Calendar Design Project
Vectortuts+ loves Illustration and discovering new talent, so today we are proud to be launching a new community project that combines both, the Vectortuts+ 2012 Calendar Design Project. The best thing is, you can be a part of it! Find out how to get involved, at the jump.
Visit Article
Quick Tip: How to Create a Watercolor Background Using Adobe Illustrator
In this tutorial we will learn how to create Watercolor Background using a Gradient Mesh, tools of deformation and Blending Modes. The techniques which are described here allow the creation of complex textural backgrounds in a simple and effective way.
Visit Article
Webdesigntuts+ — Web Design Tutorials
A Year in Web Design: How the Experts Saw 2011
“What did you find most memorable about the world of web design in 2011?” That’s the question I posed to some of our industry’s shining stars last week. One word cropped up more than any other (can you guess?) and everyone had plenty to say. See for yourself after the jump, and let us know what rocked your boat in 2011!
Visit Article
Get Into LESS: the Programmable Stylesheet Language
I don’t like CSS. Plain and simple. It makes the World go round on the web, yet the language is restrictive and hard to manage. It’s time to spruce up the language and make it more helpful by using dynamic CSS with the help of LESS.
Visit Article
Say Hello to the HTML Email Boilerplate
Figuring out html email will test the patience of any human being. A seemingly small formatting issue will inevitably arise and you think to yourself, “self, I’m a world class web developer type person schooled in the latest and greatest html5/css3/whatever, I can tackle this with plenty o’ keystrokes to spare.”
Visit Article
Phototuts+ — Photography Tutorials
Tips to Get Started with Still Life Photography
There arent many photographic practices that date back further than still life photography. When photography originated, it was necessary for exposures to be quite long, so photographing static objects was the ideal subject matter. However, as the technology developed, the fascination for capturing still life has remained and is still one of the most viable photographic professions today.
Visit Article
Is It Worth It? Some Gear Buying Advice
A lot people believe their photography will improve “if only…” With the holidays approaching, a lot of avid wanna-be photographers, amateurs, and professionals will be making wish lists for gear that they erroneously believe will make them better photographers. There are many forums, YouTube videos, and articles pandering how camera/lens/light/brand/voodoo doll will make your photos better. Today, we’ll examine that idea.
Visit Article
Superb Photos of Paths and Stairways
“Follow the Yellow Brick Road,” an infamous movie quote inspired by a pathway to a land of dreams. Wherever your paths take you and whatever amount of stairs you have to climb, its always worth it to see whats at the end, but more importantly to enjoy the journey. Today’s collection gathers dozens of images of paths and stairways, images that symbolize something different to every person.
Visit Article
Cgtuts+ — Computer Graphics Tutorials
Freebie: Epic 3D Character Model Of Pyro From Team Fortress 2
Today we’re super excited to bring you this amazingly detailed character model from Cgtuts+ regular Shaun Keenan. Shaun has re-created “Pyro” from Valve’s hit game Team Fortress 2 in glorious detail, and is making the model available to the Cgtuts+ community for free!
Visit Article
Digital Matte Painting And Projection Basics: From Photoshop To Maya To Nuke, Part 1 – Tuts+ Premium
This Tuts+ Premium tutorial series covers a variety of basic techniques for both creating and projecting matte paintings using Photoshop, Maya and Nuke. The first part of the tutorial will cover how to approach the creation of a matte painting, the research and background knowledge you need, the concept, and finally starting to create your matte painting in Photoshop. Log in or Join Now to get started!
Visit Article
Create A Flying Paper Animation In 3D Studio Max With Thinking Particles
In this tutorial by Cristian Pop, you’ll learn how to create a nice flying papers effect in 3d Studio Max using the power of Thinking Particles. We’ll start by creating the paper shapes and materials, then move into Thinking Particles to set up the rules and look at how we can combine them to create the flying paper effect.
Visit Article
Aetuts+ — After Effects Tutorials
How To Track Footage That Is Out Of Focus
In this tutorial we are going to take a look at a simple, but interesting idea. The main point will be to show you how to work with footage that is out of focus making if difficult to track. After we track it we are going to attach the camera interface elements and fake some depth of field to create the illusion that they are floating in space and shift in and out of focus like the rest of the scene.
Visit Article
DIY – Create A Camera Dolly Completely From Scratch
Ever wonder how to get smooth footage from your video camera? Today you will learn how to build a Camera Dolly that will help you acquire this type of footage. Get out those dusty power tools, buy some cheap supplies at your local hardware store, and you’ll be on your way to capturing some amazing footage in no time!.
Visit Article
How To Create A Dr. Who Time And Space Vortex – Tutsplus Premium
In this tutorial well be creating a Time & Space Vortex (like that used in Doctor Who) completely inside of After Effects. We will be using Trapcode Particular and Trapcode Shine to create the vortex. I will then teach a vital Expression that drives the camera and completes the Effect. Once you have mastered the effect, you can personalize it to create whatever Time-Tunnel you desire! All of Time and Space awaits you…
Visit Article
Audiotuts+ — Audio & Production Tutorials
Drum Compression: Get Your Attack and Release Times Correct
Compression can be a tricky one to get your head around, and even if you’ve got your head around the threshold and ratio settings without the attack and release times being set correctly it will always be difficult to get the desired effect. This quick tip will outline a really handy trick I learned from a friend a few years ago which allows you to get your attack and release times just right. It’s primarily designed to work on drums but the same principles will apply to any percussive sound.
Visit Article
Quick Tip: Punchier Drums with the New York Compression Trick
Ever have a mix where you wish the drums were bigger, more energetic, more in-your-face? I first heard about this technique in Bobby Owinksis, The Mixing Engineers Handbook, and it has since become a staple in my bag of tricks. The technique is a more aggressive take on parallel compression that can really add punch to your mix.
Visit Article
D Mixing Part 6: Depth
In this segment of our mix down tutorial, we are going to begin to look in depth into depth. Depth within any mix and listening situation is paramount to proper sonic understanding. Much like we see in 3D, we hear in 3D and taking out any one of these dimensions only serves to create a flat and unnatural sound. As such, the most common tools which give the illusion of depth (reverb and delay) become an important and necessary part of mixing.
Visit Article
Activetuts+ — Flash, Flex & ActionScript Tutorials
Getting Started With EaselJS: A Flash-Like Interface for the HTML5 Canvas
There’s been some resistance from Flash developers to our new HTML5 content. In this article – aimed at experienced AS3 coders – we’ll look at EaselJS, a JavaScript library that makes working with the HTML5 canvas very similar to working with the Flash display list.
Visit Article
AS3 Quick Tip: Hacking the Event Flow
Sometimes you may find yourself needing to modify the behavior of a component for a user input event. This article will explain how to do so by modifying the event object in-flight, before it’s processed by the component. That’s right, you can lie and cheat. In code.
Visit Article
in Flash and Web Apps: A Retrospective
With the year 2011 at a close, it is time to reflect upon some of the major industry events of the year. A lot happened… we’ll pick out some of the bits and pieces that will be most interesting to browser app and game developers from the world of industry, web, runtimes, operating systems, mobile, and more!
Visit Article
Wptuts+ — WordPress Tutorials
WordPress 3.3 “Sonny” Is Finally Here! What’s New?
The latest and greatest version of the WordPress software — 3.3, named ’Sonny” in honor of the great jazz saxophonist Sonny Stitt — is immediately available for download or update inside your WordPress dashboard. We’ll be covering lots of the new features of 3.3 this week, but for now, go and great the latest version! As we’ve mentioned before, it’s the best way to keep your WordPress site safe and stable.
Visit Article
Getting Loopy – Ajax Powered Loops with jQuery and WordPress
In this tutorial, we give you a starting point for creating AJAX interaction in your blog. We follow a step by step process, showing you how to load posts based on the viewers page scroll. The tutorial covers enqueueing scripts, setting up an AJAX handler, how to get a file outside of WordPress to use WordPress functions and access the database, and logic for loading posts on user page scroll.
Visit Article
Saintly” Practices that All WordPress Developers Should Strive For
Here on Wptuts+, we talk a lot about the ‘how’ and less about the ‘why.’ Of course, we are a tutorial site, so that’s the goal, right? Well, as a followup to last month’s article on the “Cardinal Sins of WordPress Plugin Development“, today we’re going to look at a few practices that, if every developer followed, would make the world a better place (well, at least our world!).
Visit Article
Mobiletuts+ — Mobile Development Tutorials
Getting Started With Kindle Fire Development
The Kindle Fire is the new touchscreen and e-book reader from Amazon. This device has generated a lot of buzz, and for good reason! It is currently the best selling Android tablet, with millions of units already sold. This tutorial will teach you how to begin making apps with the Android SDK specifically targeted for the Kindle Fire.
Visit Article
iOS 5 SDK: Storyboards
Storyboarding is one of the most exciting new features about the iOS 5 SDK. Take a look at the wealth of functionality offered by Storyboards in today’s iOS 5 SDK tutorial!
Visit Article
Titanium Mobile: Build an Image Uploader
This tutorial will demonstrate how to build a custom progress bar by creating an image uploader with Titanium Mobile. Specifically, the demo project will allow you to select an image from the device photo gallery and upload it to a remote server for storage. Both the Titanium Mobile code and the server-side code will be explained. Now, let’s get started!
Visit Article
Happy New Year!
We’d like to wish all our readers a very Happy New Year! Why not take a look at our Holiday Wishes post to see a video message from the Envato HQ team, and find out more about what you might have missed over the Christmas period.
We hope you’ve enjoyed everything that we’ve had to share this year, and look forward to publishing thousands more top-quality tutorials, articles, freebies, and resources in 2012.
Thanks for being part of the Tuts+ community!