0

Hi, Experts
I really need to do following animation:
Arrows moving on some path (to be determined by a function). Let's this path to be circle. I want several arrows (number of arrows must be determined dynamically so that arrows cover whole circle) to move on the circle and their speed to be controllable (all arrows will have same speed).

But my knowledge in Flash is very-very little (I'm familiar with Java/C++ and other Computer Science stuffs, so you can give your advices accordingly).

What I was able to achieve after 3 days of effort:
Just one arrow moving along the circle. I've tried every possiblity (I saw), but still no success.

This problem should be straigthforward for flash gurus, could someone please advice how to solve this. Any kind of help is appreciated. Most probably I'm calling "attachMovieClip" in wrong place.

3
Contributors
6
Replies
7
Views
9 Years
Discussion Span
Last Post by iamthwee
0

More Info:

I'm using Micromedia Flash MX Professional 2004 (version 7.0.1)
ActionScript 2

1) I created a movie clip ("arrow") and added following code to the movie clip.

onClipEvent (load) {
var angle:Number = 0;
var radX:Number = 300;
var radY:Number = 70;
var centerX:Number =  500;
var centerY:Number = 200;
var orbitSpeed:Number =.03;
this._rotation = 270;
this._x = centerX + radX;
this._y = centerY; //centerY;
// trace(this._name+" is created");
}
 
onClipEvent (enterFrame) {
this._x = centerX+Math.cos(angle)*radX;
this._y = centerY+Math.sin(angle)*radY;
angle -= orbitSpeed;
this._rotation -= (180* orbitSpeed)/Math.PI;
//trace(_name+" x: "+_x+" y: +"+_y);
}

2) After adding above code I've converted it to movie clip ("moving_arrow");
So after these I have an arrow moving in a circular path.

My Problems:
1) I can't create several "moving_arrows" dynamically. Number of arrows must be determined dynamically, so that arrows follow each other and cover whole cicular path. It's simulating water stream in the lake.
2) I can't change speed dynamically. How should I acess it? this.moving_arrow_instance.arrow_instance.orbitSpeed is not working.


What is ideally wanted is something like this:
http://www.pyngl.ucar.edu/Examples/Images/vector_pop.5.png

But as a first stage I'm trying to make arrow just move along the circle. Then I'll try to make it as in the picture.
Any kind of advice is appreciated.
Thanks in advance,

0

OK, I've not had time to look into this too far, and it's been a while since I've done any AS2...But here goes.

To be able to dynamically use movieclips in your actionscript you first need to ensure that the clip has the appropriate linkage settings.
After creating your GFX/movieclip, locate it in the library, right click on it and select "linkage..." ensure that the "export for actionscript" and "Export in first frame" items are checked.
In the identifier field of the dialog, put in the name you want to use to refer to your clip in your actionscript (by default it will have the same name as the asset in the library)

For this example, I created a simple graphic of an arrow on the stage, converted it into a movieclip called mArrow (which automatically bungs it into the library) and then deleted the movieclip from the stage (but keeping it in the library!).

Then in the linkage dialog, I've checked the relevant boxes and left it's name as the default (mArrow). So any time I want to add an instance of the arrow to the stage I can do so using attachMovie(mArrow, "instance_name_mc", getNextHighestDepth()); .

Ok, so that's the first part out of the way, now we have an asset which we can dynamically add to the stage, now for the code part of it.

In the first frame of the main movieclip I've put the following actionscript which should create 10 instances of the arrow movieclip, giving them instance names arrow0 to arrow9 and animating them:
NOTE: I have kept many of your original variable names, but altered some of the values slightly!

stop();

// number of arrows to use
var numArrows:Number=10;

// angle between each arrow
var angleDifference:Number= (2*Math.PI) / numArrows;

// general global vars
var radX:Number=100;
var radY:Number=70;
var centreX:Number = 125;
var centreY:Number = 100;
var orbitSpeed:Number = 0.3;

// array of arrow movieclips
var arrows:Array = new Array();	

// array of angles
var angles:Array = new Array();

// Now create several arrow movieclips on the stage and animate them....
for(loop=0;loop<numArrows;++loop)
{
	// create arrow clips with instance names arrow0 to arrow9
	var arrowName:String = "arrow" + loop;
	attachMovie("mArrow", arrowName, getNextHighestDepth());
	
        // now find the clip we just added (using eval) and set it's initial properties
	var target:MovieClip = eval(arrowName);
	
	// push initial angle onto angle array, 
	// calculate initial xy position..
	// TODO: Calculate initial rotation
	angles.push(angleDifference*loop);
	target._x = centreX + (Math.sin(angles[loop])*radX);//centerX + radX;
	target._y = centreY + (Math.cos(angles[loop])*radY);//centreY;
	//target._rotation = ;
	
	// set the onEnterFrame function for the movieclip
	target.onEnterFrame = arrowEnterFrame;
		
	// add the clip to the array of clips...
	arrows.push(target);
}

// enter frame event for the arrow movieclips.
function arrowEnterFrame()
{
	var idx:Number = Number (this._name.substr(-1,1) );
	_x = centreX+(Math.sin(angles[idx])*radX);
	_y = centreY+(Math.cos(angles[idx])*radY);
	angles[idx]+=orbitSpeed;
	this._rotation -= (180*orbitSpeed)/Math.PI;
}

Now this doesn't do exactly what you're expecting it to...I think the results of the calculations of _x and _y in the arrowFrameEvent function are calculated based on each arrow movieclips local coordinates rather than relative to the main movieclips coordinates....So there is some tweaking to be done....plus the rotation needs to be initialised for each clip on creation (I couldn't be arsed to work it out!)...But there are 10 animated arrows on the screen nevertheless!

I hope this is of some help...

Cheers for now,
Jas.

p.s. a .zip file is attached with a .fla and .swf in mx2004 format (created in flash 8, but saved as MX2004!)

1

My last post wasn't entirely successful. But using Flashdevelop and the latest version of the flex 3 SDK (both of which are FREE downloads, so google 'em and download 'em....Highly recommended!) I've knocked something together in AS3 which works pretty much as you wanted it to.....

First I knocked a little AS3 class together draw an arrow shape (derived from Sprite, a new AS3 class which is basically a MovieClip without a timeline...All animation is done through adding and removing event listeners....)
Anyway, without further ado here's Arrow.as:

/**
* Draws an arrow shape
* @author Jason Trunks
* @version 0.1
*/

package 
{
	import flash.display.Sprite;
	
	[SWF(backgroundColor="0xffffff", width="800", height="600", frameRate="25")]
	public class Arrow extends Sprite  
	{
		public function Arrow()
		{
			init();
		}
		
		public function init():void
		{
			graphics.lineStyle(1,0,1);
			graphics.beginFill(0xffff00);
			graphics.moveTo(-50,-25);
			graphics.lineTo(0,-25);
			graphics.lineTo(0,-50);
			graphics.lineTo(50,0);
			graphics.lineTo(0,50);
			graphics.lineTo(0,25);
			graphics.lineTo(-50,25);
			graphics.lineTo(-50,-25);
			graphics.endFill();
		}
	}
	
}

Then I knocked this little class together, which draws and animates 10 instances of the Arrow class and animates them in a circular um... well in a circle....so this isCircularArrow.as:

package 
{
	import flash.display.Sprite;
	import Arrow;
	import flash.events.Event;
	/**
	 * Draws a number of arrows onto the stage, arranged in a circle and animates them...
	 * @author Jason Trunks
	 */
	[SWF(backgroundColor="0xffffff", width="275", height="250", frameRate="25")]
	public class CircularArrows extends Sprite 
	{
		private var arrows:Array = new Array();
		private var angles:Array = new Array();
		
		private const numArrows:Number = 10;
		private var angleDifference:Number = (2 * Math.PI) / numArrows;
		
		private const radX:Number = 100;
		private const radY:Number = 70;
		private const centreX:Number = 125;
		private const centreY:Number = 100;
		private const orbitSpeed:Number = 0.03;
		
		public function CircularArrows()
		{
			for (var loop:Number = 0; loop < numArrows; ++loop )
			{
				var anArrow:Arrow = new Arrow();
				addChild(anArrow);
				
				angles.push(loop * angleDifference);
				anArrow.scaleX = anArrow.scaleY = 0.3;
				
				anArrow.x = centreX + (Math.sin(angles[loop]) * radX);
				anArrow.y = centreY + (Math.cos(angles[loop]) * radY);
				arrows.push(anArrow);
			}
			
			// now all arrows have their initial positions, lets calculate the initial rotation for each....
			// use atan2 so that previous arrow points to next arrow ....
			for (loop = 0; loop < numArrows; ++loop )
			{
				var dx:Number;
				var dy:Number;
				if (loop < numArrows - 1)
				{
					dx = arrows[loop + 1].x - arrows[loop].x;
					dy = arrows[loop + 1].y - arrows[loop].y;
				}
				else
				{
					dx = arrows[0].x - arrows[numArrows - 1].x;
					dy = arrows[0].y - arrows[numArrows - 1].y;
				}
					
				var radians:Number = Math.atan2(dy,dx);
				arrows[loop].rotation = radians * 180 / Math.PI;
			}

			addEventListener(Event.ENTER_FRAME, animateArrows);
		}
		
		private function animateArrows(event:Event):void
		{
			for (var loop:Number = 0; loop < numArrows; ++loop )
			{
				arrows[loop].x = centreX + (Math.sin(angles[loop]) * radX);
				arrows[loop].y = centreY + (Math.cos(angles[loop]) * radY);
				arrows[loop].rotation -= (180 * orbitSpeed) / Math.PI;
				angles[loop] += orbitSpeed;
			}
		}
	}
	
}

As you can see, this uses pretty much the same code as your original post and my previous post, but this time we don't have to do anything to get around the problem with the different coordinate systems..Everything uses the main movie's coordinate system.

I've also bunged in some rotation code so that each of the arrows in the array points to the next arrow in the array.

In case you were wondering:
[SWF(backgroundColor="0xffffff", width="800", height="600", frameRate="25")]
is a line which tells flashdevelop a bit about how we want the final flash file to look (size/colour). I haven't set up an AS3 project, I've just used the two .AS files. Basically with CircularArrows.as open I've used ctrl->F8 to compile the .swf.
(alternatively from the top menu 'Tools->flash tools->build current file' does the same thing!)

If you want to have a go at building this yourself, first you'll need to download and install the latest version of Flashdevelop (from flashdevelop.org) and then download and unzip the latest version of the flex3 SDK from Adobe...Did I say they're FREE??

Then once you've pressed ctrl-F8 in Flashdevelop; before the first compilation, Flashdevelop will ask you where the flex SDK has been installed/unzipped. Navigate to the appropriate directory and select OK. As long as you've selected the correct directory, the AS3 classpaths will be set up and the compiler should build the .swf for you...Simple as that!

If you can take the AS3 route, it would be far simpler than doing it in MX2004!

Anywhoo a .zip file is attached, containing the two AS3 files and a pre-compiled .swf.

Cheers for now,
Jas.

Votes + Comments
Really Helped
0

JasonHippy
Thank you very much for forwarding me to an easier way of doing it. I've installed flashdevelop and using it. Now I realized that AS3 is really programming language with all OO properties (class, polymorphism, inheritance) There are still some problems, but since I'm in correct way I will find solutions for them.
Any good (video) tutorials that you can suggest about AS3?
Thanks again.

0

JasonHippy
Thank you very much for forwarding me to an easier way of doing it. I've installed flashdevelop and using it. Now I realized that AS3 is really programming language with all OO properties (class, polymorphism, inheritance) There are still some problems, but since I'm in correct way I will find solutions for them.
Any good (video) tutorials that you can suggest about AS3?
Thanks again.

Hey Neo...
No probs, glad to help..Good to hear that you're getting on well with Flashdevelop! ;)

I've done quite a bit of FLV/video related stuff in the past using AS2, but I've not done anything with video and AS3 yet, so I'm afraid I can't help you there!

Cheers for now,
Jas.

This question has already been answered. Start a new discussion instead.
Have something to contribute to this discussion? Please be thoughtful, detailed and courteous, and be sure to adhere to our posting rules.