Vector Field

 

Using ActionScript, we want to program a little Flash application with a graphical layout that consists of a field of arrows, where each of those arrows will change its orientation according to the position of the mouse cursor – just like compass needles. The following ActionScript steps will be considered:

1.) The implementation of a MovieClip object

2.) The duplication of MovieClips

3.) The interactive response on a mouse event

 

 

 

First of all, we need to build a little graphic that contains the shape of an arrow (using Photoshop, for instance). I used an image with a square base (with a side length of 25 pixels) and saved it as PNG-24 with a transparent background. The arrow in this basic image points to the north.

 

1.) The implementation of a MovieClip object

First, we will import this image to the Flash editor and place it at an arbitrary position on the stage of the first frame in the first layer (the spatial extensions of the window are chosen as 400 x 300 pixels, I use a frame rate of 60 fps and changed the name of the layer to Preparation). Next, we have to convert the image into a MovieClip object (Convert Symbol to... MovieClip) and apply an instance name to it: Arrow. It is very important to ensure that the rotation center of the MovieClip is at the center of the clip. If this is not already the case, one has to adjust the rotation center manually: A double click with the left mouse button on the MovieClip will open the object in the edit mode. Here, one has to move the MovieClip relative to the original rotation center of the object that is indicated by a subtle static cross symbol.

 

2.) The duplication of MovieClips

With the next step we will start the programming that will take place on another layer (add a new layer with the name Stage). First, we want to duplicate the MovieClip that contains the arrow image. This duplication step will result in a matrix of 17 x 13 arrows that will cover the entire screen of the Flash application. This will be performed by the use of two nested for-loops:

 


for(i = 0;i < 17; i++)
{

	for(j = 0;j < 13;j++)
	{
		duplicateMovieClip(Arrow,"Arrow"+(i*13+j),(i*13+j));
		setProperty("Arrow" + (i*13+j),_x,i*25);
		setProperty("Arrow" + (i*13+j),_y,j*25);
		
	}
}

 

The duplication of the original MovieClip Arrow will be done by the built-in method duplicateMovieClip() that requires three arguments: First, we need to pass the name of the original MovieClip that we want to duplicate (Arrow). Second, we have to define the instance name of the resulting copy of the MovieClip. Here, I simply use the same name, i.e, Arrow, as I used for the original MovieClip and append a numerical index to each of those copies. The third argument defines the depth layer of each MovieClip copy. For the numerical index of the instance name, as well as for the depth layer of each copy, I use the same value, depending on the values i and j that I use as indices for the two loops: (i*13+j). As a result we will have exactly 221 copies of our original MovieClip object with the instance names Arrow0, Arrow1, ..., Arrow220.

With the next two code lines we will apply the x- and y-position, respectively, to each of these 221 MovieClips in the window of our Flash application. Using the built-in method setProperty(), we have to specify the instance name of the MovieClip object, as well as the property we want to apply (_x, or ;_y, respectively) and, of course, the value of this property (the pixel position within the screen).

 

3.) The interactive response on a mouse event

After these steps we already filled up the entire screen of our Flash application with arrows. However, these arrows all still point to the north. Hence, as a next step some interactivity needs to come into play: We will program a new function that will assign the orientation to each of our 221 arrows, depending on the current position of the mouse cursor on the screen:

 


function adjustOrientation(xm:Number,ym:Number):Void
{
	for(i = 0;i < 221;i++)
	{
		var x:Number = getProperty("Arrow"+i,_x);
		var y:Number = getProperty("Arrow"+i,_y);
		var a:Number = xm - x;
		var b:Number = ym - y;
		var alpha:Number = 180*Math.atan(a/b)/Math.PI;
		
		if(ym < y)
			setProperty("Arrow"+i,_rotation,-alpha);
		else
			setProperty("Arrow"+i,_rotation,180-alpha);
	}
}

 

I called this function adjustOrientation() and it requires two arguments: xm and ym that represent the absolute x- and y-position of the mouse cursor on the screen. The code for the calculation of the new orientation of each arrow is embedded within a for-loop. Contrary to the first time where I used two nested for loops for the duplication of the MovieClip I just use a simple forloop here, since I defined the instance names of the copies that way that they resulted in an array from 0 to 220.

The mathmatics I used for the calculating the new orientations of the arrows is simple trigonometry which I will briefly explain: The variables x and y represent the x- and y-coordinates of each MovieClip. They will be determined by means of the built-in method getProperty(instance name, property). The variables a and b represent the horizontal (a) and the vertical (b) distance between each MovieClip and the position of the mouse cursor. Those values build up a right-angled triangle, the hypotenuse of this triangle corresponds to the line between the mouse cursor and the position of each MovieClip. Using these values one can calculate the angle between the mouse cursor and each MovieClip that is stored in the variable alpha. Next, one has to apply a case-by-case analysis for the direction of the rotation because the method I use to assign the new orientation to each MovieClip, setProperty(), will do a clockwise, or counter clockwise rotation, respectively, depending on the algebraic sign of the angle that is passed to the method as the third argument.

Next, we have to connect this function to a mouse event, since a change in the orientation of the arrows shall be performed each time the position of the mouse cursor is changed within the window of the Flash application. I found the following procedure the easiest one to do so: First I added another symbol (a square, for instance) to an arbitrary location on the layer Preparation and converted it into a MovieClip. You can assign many predefined mouse or key events to a MovieClip, i.e., each time a certain event happens (like a mouse move or the release of a key) the program records this event and calls a so-called “event handler” that is tied to this specific event. For our purposes we need the event of a mouse move: We click on the MovieClip that we just added to the layer Preparation and which I gave the instance name Empty, and then we select the option mouseMove from the selection field in the ActionScript interface of our Flash editor. Immediately, some code appears in the window: onClipEvent(mouseMove) { }. This function, in its raw and yet effectless form, needs to be filled up with some additional code now.

 


onClipEvent(mouseMove)
{
	var mx:Number = _level0._xmouse;
	var my:Number = _level0._ymouse;
	_level0.adjustOrientation(mx,my);
}

 

This code has a quite simple structure: First, I defined two variables that represent the x- and the y-coordinate, respectively, of the mouse cursor. The current position of the mouse cursor will be obtained by calling the property _xmouse, or _ymouse, respectively. Note that you have to call this property with a certain level specification (_level0.) that has to be put in front of the property, in order to obtain the global position of the mouse cursor within the window. Otherwise, one will obtain the position of the mouse cursor relative to the respective MovieClip object (Empty). Just try it out and omit this level specification or use the specification this. instead! Next, we will call our function adjustOrientation(mx,my) using these two values as its parameters. Again, we have to prefix this function with the level specification _level0. because otherwise the MovieClip object wouldn't even know this function.

After these steps the functionality of our Flash application is fully implemented. Just try it out, launch the program in the preview window and move the mouse cursor over the window. You will see that all arrows will point with their heads exactly to the position of the mouse cursor. However, we still have a blemish in our layout here: The original MovieClip Arrow as well as the object Empty are still visible on the screen. So, we have to remove them from the scene with a final code block in the ActionScript window of the layer Preparation:

 


	setProperty("Arrow",_visible,false);
	setProperty("Empty",_visible,false);

 

Once more, we use the method setProperty(instance name, property, value) for both MovieClip objects we want to hide: Just use the instance name of each MovieClip object (Arrow or Empty, respectively), then the property _visible and finally the value false. That's it!

 

 

© 2011 G. Wendt



Write a comment
Name: Note: Your email address will not be displayed on this site nor otherwise published!
Email:
Comment:
Anti-Spam:
Color & Font
Color tool

You have difficulties finding a balanced color combination and appropriate font formats for your website?


Use the tool Color & Font on this website in order to interactively create the color and font properties of your own site. The results of your settings can be easily included as CSS listing in your web project.

Archive
MTWTFSS
123456
78910111213
14151617181920
21222324252627
282930