Here is another look at the code:
addEventListener(Event.ENTER_FRAME, rotateTriangle, false, 0, true);
function rotateTriangle(e:Event) {
var angle:Number = Math.atan2(mouseY - triangle.y, mouseX - triangle.x);
triangle.rotation = angle * (180 / Math.PI);
}
If you notice, every time the frame changes, the Event Listener calls a function named "rotateTriangle". In that function, there is another function. It is the mathematical function known as Math.atan2 (). What does it do? Taking the distance between the x and y coordinates of two points, it triangulates the angle of a line from the second point to the first point.
In our case, the second point is the center of our triangle. The first point is our mouse pointer. Enter this code. Make sure that the names highlighted in blue match the name of the triangle instance that we created earlier.
How to work it in Adobe Flash CS5 Professional
This is a companion blog created by me in order to air some of my discoveries and beginnings since purchasing Adobe Flash CS Professional in April of 2010.
1.4.15
27.3.15
Point at Pointer 2
Now that you're on the main stage with your new symbol instance, create a new layer. This layer will hold our Actionscript 3.0 code, from the Actions panel. Flash doesn't allow Actionscript to be on a layer that has display objects in it, so we have to create a new black layer. You can name the layer if you wish. In this new layer, on frame one, select f9 to go into the actions panel. Here is the code that you must enter:
addEventListener(Event.ENTER_FRAME, rotateTriangle, false, 0, true);
function rotateTriangle(e:Event) {
var angle:Number = Math.atan2(mouseY - triangle.y, mouseX - triangle.x);
triangle.rotation = angle * (180 / Math.PI);
}
Okay, this is the code that runs the mouse follow program. In order for this program to work, the program has to know what to do and when. In this case, we're answering the second question first, with our Event Listener. As the name suggest, an Event Listener waits for something to happen and then does something. There are many things that it can listen for. In our case, we need to wait for the mouse to move, because that's what we're following. But how do we do this? Logically, you would say that we need to write a function that says that whenever the mouse moves, the triangle should change direction.
If you look at the part highlighted in red, our Event Listener is actually going to do something every time that an event called "Enter_Frame" happens. What is ENTER_FRAME? It is the frame rate. Basically, every time a frame passes in Flash, an ENTER_FRAME event is sent out. So if your Flash movie is set at the default 24 frames per second, ENTER_FRAME happens 24 times every second.
I know what you're thinking: "But we don't need to track the rotation of the triangle every frame of the animation. It only needs to be moved when the mouse moves." While it is true that we would save some memory if the computer only had to keep track of the triangle's rotation when the mouse actually moved, it would take more work than it was worth to implement such functionality. And besides, if there is a constant stream of events, happening every frame, we won't have to worry about input lag.
Input lag is the amount of time that it takes for a machine to respond to your input. It might be one millisecond, but it's still detectable. If we were to rotate the triangle only when the mouse moved, we would have to wait for the computer to see the mouse move, load up the program and execute the function. By having our function run with the frame rate, however, we keep the computer on its toes so that it doesn't get caught napping. If there is any slowdown as a result of over-use, it will be spread out across 24 frames, instead of being concentrated at the initial frame, when the computer first detected the movement of the mouse.
addEventListener(Event.ENTER_FRAME, rotateTriangle, false, 0, true);
function rotateTriangle(e:Event) {
var angle:Number = Math.atan2(mouseY - triangle.y, mouseX - triangle.x);
triangle.rotation = angle * (180 / Math.PI);
}
Okay, this is the code that runs the mouse follow program. In order for this program to work, the program has to know what to do and when. In this case, we're answering the second question first, with our Event Listener. As the name suggest, an Event Listener waits for something to happen and then does something. There are many things that it can listen for. In our case, we need to wait for the mouse to move, because that's what we're following. But how do we do this? Logically, you would say that we need to write a function that says that whenever the mouse moves, the triangle should change direction.
If you look at the part highlighted in red, our Event Listener is actually going to do something every time that an event called "Enter_Frame" happens. What is ENTER_FRAME? It is the frame rate. Basically, every time a frame passes in Flash, an ENTER_FRAME event is sent out. So if your Flash movie is set at the default 24 frames per second, ENTER_FRAME happens 24 times every second.
I know what you're thinking: "But we don't need to track the rotation of the triangle every frame of the animation. It only needs to be moved when the mouse moves." While it is true that we would save some memory if the computer only had to keep track of the triangle's rotation when the mouse actually moved, it would take more work than it was worth to implement such functionality. And besides, if there is a constant stream of events, happening every frame, we won't have to worry about input lag.
Input lag is the amount of time that it takes for a machine to respond to your input. It might be one millisecond, but it's still detectable. If we were to rotate the triangle only when the mouse moved, we would have to wait for the computer to see the mouse move, load up the program and execute the function. By having our function run with the frame rate, however, we keep the computer on its toes so that it doesn't get caught napping. If there is any slowdown as a result of over-use, it will be spread out across 24 frames, instead of being concentrated at the initial frame, when the computer first detected the movement of the mouse.
Point at Pointer 1
Okay, Here's something I haven't done before. Have you ever wanted to figure out how to add a function into a game that points an object at another object? Like if you have a space ship shooter and you want the enemy turrets to point at you and fire, or if you're making a Missile Command style game and you want to have the missile launcher point where your pointer is pointing? Here's how you do it. To start off, create a new Actionscript 3.0 Flash File.
Before you do anything else, make sure that Object Mode is selected at the bottom of the tool box (it's a circle inside of a square).Go into the tool box and press and hold on the Rectangle Tool. A pop-up menu should come. Go down to the Polystar tool at the bottom. In the Tool Settings at the bottom of the menu, click on options. Another pop-up menu should show up. In the Number of Sides field, put 3 (make sure the style field is set to polygon and not star). When you're done click okay.
Now, drag out a triangle onto the field. By default it will be equilateral. Make sure that when you draw it that the top of the Triangle is at a zero degree angle, or pointing perfectly to the right. It might seem logical to have the top pointing up, but it won't work right if we don't point it at zero degrees.
Double-click the triangle and enter inside of it's layers (do not lock the original layer). Create a new layer on top of the original layer and create a new, smaller triangle of a different color than the original. Make sure that it is also pointed at zero degrees, perfectly to the right. It doesn't have to light up perfectly at this time. Now select both triangles and go to the Align menu. Check the box at the the bottom which says "Align to Stage," because we want the symbol's contents to be aligned to the center. Then select the options to align to the middle vertically and horizontally.
Finished? Okay, now exit the shape and go back to the stage. Select the triangle that is pointing to the right, ninety degrees from the Y axis, and select the modify menu and then select Convert to Symbol. Name your new symbol "ThreeSided" with no spaces. Make sure that the registration for the symbol, the symbol's rotation point, is in the exact middle of the shape so that it rotates around its center. Finish making the symbol, then go to your Library panel. Select ThreeSided from the Library and drag it out onto the stage. Click on the object and go to the properties panel.
In the properties panel there is a field called "instance name." Click in this field and type in the name "triangle." Now you have an instance of the ThreeSided class named triangle.
Before you do anything else, make sure that Object Mode is selected at the bottom of the tool box (it's a circle inside of a square).Go into the tool box and press and hold on the Rectangle Tool. A pop-up menu should come. Go down to the Polystar tool at the bottom. In the Tool Settings at the bottom of the menu, click on options. Another pop-up menu should show up. In the Number of Sides field, put 3 (make sure the style field is set to polygon and not star). When you're done click okay.
Now, drag out a triangle onto the field. By default it will be equilateral. Make sure that when you draw it that the top of the Triangle is at a zero degree angle, or pointing perfectly to the right. It might seem logical to have the top pointing up, but it won't work right if we don't point it at zero degrees.
Double-click the triangle and enter inside of it's layers (do not lock the original layer). Create a new layer on top of the original layer and create a new, smaller triangle of a different color than the original. Make sure that it is also pointed at zero degrees, perfectly to the right. It doesn't have to light up perfectly at this time. Now select both triangles and go to the Align menu. Check the box at the the bottom which says "Align to Stage," because we want the symbol's contents to be aligned to the center. Then select the options to align to the middle vertically and horizontally.
Finished? Okay, now exit the shape and go back to the stage. Select the triangle that is pointing to the right, ninety degrees from the Y axis, and select the modify menu and then select Convert to Symbol. Name your new symbol "ThreeSided" with no spaces. Make sure that the registration for the symbol, the symbol's rotation point, is in the exact middle of the shape so that it rotates around its center. Finish making the symbol, then go to your Library panel. Select ThreeSided from the Library and drag it out onto the stage. Click on the object and go to the properties panel.
In the properties panel there is a field called "instance name." Click in this field and type in the name "triangle." Now you have an instance of the ThreeSided class named triangle.
19.3.15
Draw a Circle - Final
Test the program out now. If there are only two or three dots showing up on the screen, change the scaling number to 1 in the actions panel and then test it again. Here you have it. The program picks out the first spot, when angle is zero, and then from there it adds one degree every tenth of a second until it gets to 30 degrees. You can see the slight curve in the line, which indicates that if continued, the program will make a complete circle. I should've had you do this in the beginning, but I wanted the program to move faster:
timer= new Timer(100, 30);
timer.addEventListener(TimerEvent.TIMER, createCircle);
timer.addEventListener(TimerEvent.TIMER_COMPLETE, createCircleStop);
timer.start()
Go to the timer declaration and change the number of iterations from 30 to 360. That should give us a full circle.
And you're done.
Oh, and one more thing. It appears that we have introduced a new error when changing the amount added to angle. Take a look at this (at the top):
var cirqy:Number = 220;
var cirqx:Number = 250;
var angle:uint = 0;
var scaling:uint = 1;
This code initializes the variable angle as a uint. What is a uint? An unsigned integer. What's that?
An unsigned integer is a whole number (no fractions allowed) that does not have a sign, meaning that it can never be negative. In previous iterations of the program, we could use a uint because we were just adding three every time. No negatives; no decimal numbers. Now we are dividing pi by 180, which means all of our numbers will not be whole numbers. So we need to change this variable type from uint to Number, much like cirqy and cirqx above it.
There. Now we're done xD
timer= new Timer(100, 30);
timer.addEventListener(TimerEvent.TIMER, createCircle);
timer.addEventListener(TimerEvent.TIMER_COMPLETE, createCircleStop);
timer.start()
Go to the timer declaration and change the number of iterations from 30 to 360. That should give us a full circle.
And you're done.
Oh, and one more thing. It appears that we have introduced a new error when changing the amount added to angle. Take a look at this (at the top):
var cirqy:Number = 220;
var cirqx:Number = 250;
var angle:uint = 0;
var scaling:uint = 1;
This code initializes the variable angle as a uint. What is a uint? An unsigned integer. What's that?
An unsigned integer is a whole number (no fractions allowed) that does not have a sign, meaning that it can never be negative. In previous iterations of the program, we could use a uint because we were just adding three every time. No negatives; no decimal numbers. Now we are dividing pi by 180, which means all of our numbers will not be whole numbers. So we need to change this variable type from uint to Number, much like cirqy and cirqx above it.
There. Now we're done xD
Draw a Circle 9
Ladies and gentlemen. When you pass a parameter to Math.sin() or the Math.cos() function, the language assumes that you are using Radians, not degrees. As you saw, there was no discernible pattern, so unless you had started with three there was no way for you to figure out why it didn't work right. What is a Radian? Well, assuming that there are to rays pointing out from the center of a circle, making an angle P at the center, and assuming that the length of the arc facing angle P is equal to the radius of the circle, one radian is equal to the measure of angle P.
About how many degrees is that? 57.
What times 57 equals 180 degrees? Pi.
It takes some getting used to, but here's how it works. We know what it takes to get 180 degrees
(Pi x 1 radian), but we want to add one degree at a time, so (Pi x 1 radian) divided by 180 equals the amount we need to add every time we want to go one degree around the circle to place the next dot.
The following code is what we need:
cirqx = cirqx + (Math.cos(angle) *scaling);
cirqy = cirqy - (Math.sin(angle) *scaling);
angle += Math.PI/180;
About how many degrees is that? 57.
What times 57 equals 180 degrees? Pi.
It takes some getting used to, but here's how it works. We know what it takes to get 180 degrees
(Pi x 1 radian), but we want to add one degree at a time, so (Pi x 1 radian) divided by 180 equals the amount we need to add every time we want to go one degree around the circle to place the next dot.
The following code is what we need:
cirqx = cirqx + (Math.cos(angle) *scaling);
cirqy = cirqy - (Math.sin(angle) *scaling);
angle += Math.PI/180;
Draw a Circle 8
I want you to do something. Go to the bottom of the program and look at this statement:
angle = angle + 3
Now so far, the dots are coming up over 180 degrees for every 3 that we add to angle, right. Try this. Change the 3 to a 1.4 and test the program.
Did you do it. Notice that the program goes crazy. Dots just appear at random on the screen and the position of the circle is off. The distance between dots is also irregular, but the dots still form a circle. So if half the amount doesn't give me half the degrees, what kind of units am I working with? You saw how it looked when we changed the amount added to the angle. There is no pattern to make sense of. So what is really going on.
You can try adding other numbers to angle, but what you will notice is that nothing comes closer to making the program do what it was designed to do than three. When I first made this program, I picked three at random for my first number. It was the only number that could've worked in this situation why? What is it that, when multiplied by three, moves 180 degrees? I'll wait.
angle = angle + 3
Now so far, the dots are coming up over 180 degrees for every 3 that we add to angle, right. Try this. Change the 3 to a 1.4 and test the program.
Did you do it. Notice that the program goes crazy. Dots just appear at random on the screen and the position of the circle is off. The distance between dots is also irregular, but the dots still form a circle. So if half the amount doesn't give me half the degrees, what kind of units am I working with? You saw how it looked when we changed the amount added to the angle. There is no pattern to make sense of. So what is really going on.
You can try adding other numbers to angle, but what you will notice is that nothing comes closer to making the program do what it was designed to do than three. When I first made this program, I picked three at random for my first number. It was the only number that could've worked in this situation why? What is it that, when multiplied by three, moves 180 degrees? I'll wait.
Draw a Circle 7
Okay. Here is our code so far. If you look at the top, you can see that I have added a new variable (scaling) to the list. The purpose of this is to take two separate amounts and tie them into one variable, ostensibly so that if I want to change both values, I won't have to do it twice - only once. The change is highlighted in blue:
import flash.utils.Timer;
import flash.events.TimerEvent;
var timer:Timer;
var cirqy:Number = 220;
var cirqx:Number = 250;
var angle:uint = 0;
var scaling:uint = 200;
timer = new Timer(100, 30);
timer.addEventListener(TimerEvent.TIMER, createCircle);
timer.addEventListener(TimerEvent.TIMER_COMPLETE, stopCreatingCircles);
timer.start()
function createCircle(event:TimerEvent):void {
var circle:Sprite = new Sprite();
circle.graphics.lineStyle(.5, 1);
circle.graphics.beginFill(0xBC51F8);
circle.graphics.drawCircle(cirqx, cirqy, 5);
graphics.endFill();
addChild (circle);
cirqx = cirqx + (Math.sin(angle) * scaling) ;
cirqy = cirqy - (Math.cos(angle) * scaling) ;
angle = angle + 3;
}
function stopCreatingCircles(event:TimerEvent):void {
}
You should recognize the number 200. That's the amount that we multiplied by the sine and cosine of angle to give us a visible amplitude for our circle drawing. Put this code in your actions panel (Alt+F9) and then run it by clicking Control -> Test Movie -> Test. When you run this code, you should notice something. The program draws a circle on the screen, but there is something unusual. The program is supposed to draw one dot at a time, in a circle, from zero degrees upward, but it doesn't. Instead, it draws one dot; then, it goes more than 180 degrees in a circle and draws another dot. But we're only adding 3 degrees each iteration, so why is the program adding 180+ degrees with every iteration? I'll tell you why in the next post.
import flash.utils.Timer;
import flash.events.TimerEvent;
var timer:Timer;
var cirqy:Number = 220;
var cirqx:Number = 250;
var angle:uint = 0;
var scaling:uint = 200;
timer = new Timer(100, 30);
timer.addEventListener(TimerEvent.TIMER, createCircle);
timer.addEventListener(TimerEvent.TIMER_COMPLETE, stopCreatingCircles);
timer.start()
function createCircle(event:TimerEvent):void {
var circle:Sprite = new Sprite();
circle.graphics.lineStyle(.5, 1);
circle.graphics.beginFill(0xBC51F8);
circle.graphics.drawCircle(cirqx, cirqy, 5);
graphics.endFill();
addChild (circle);
cirqx = cirqx + (Math.sin(angle) * scaling) ;
cirqy = cirqy - (Math.cos(angle) * scaling) ;
angle = angle + 3;
}
function stopCreatingCircles(event:TimerEvent):void {
}
You should recognize the number 200. That's the amount that we multiplied by the sine and cosine of angle to give us a visible amplitude for our circle drawing. Put this code in your actions panel (Alt+F9) and then run it by clicking Control -> Test Movie -> Test. When you run this code, you should notice something. The program draws a circle on the screen, but there is something unusual. The program is supposed to draw one dot at a time, in a circle, from zero degrees upward, but it doesn't. Instead, it draws one dot; then, it goes more than 180 degrees in a circle and draws another dot. But we're only adding 3 degrees each iteration, so why is the program adding 180+ degrees with every iteration? I'll tell you why in the next post.
Subscribe to:
Posts (Atom)