Welcome Guest [Log In] [Register]
Welcome to Brackenwood. We hope you enjoy your visit.


You're currently viewing our forum as a guest. This means you are limited to certain areas of the board and there are some features you can't use. If you join our community, you'll be able to access member-only sections, and use many member-only features such as customizing your profile, sending personal messages, and voting in polls. Registration is simple, fast, and completely free.


Join our community!


If you're already a member please log in to your account to access all of our features:

Username:   Password:
Add Reply
Particle Tutorial; You know you want to.
Topic Started: Jan 6 2006, 04:00 PM (608 Views)
Mr. Jiggmin
Member Avatar
made of tulips
Welcome to the super and amazing particle effect tutorial! This tutorial assumes you have some general knowledge of actionscript. (loops, if statements, that kind of stuff) If you're saying "ActioningScripter wha??", then maybe here is a good place to start.

This'll work on Flash MX 2004 and up. (If you work around the "getNextHighestDepth()'s" then I think It'll work on MX as well.)


Step 1 - Drawing a rather small thing in a movie clip.

1.1 - Make a new movie clip and name it whatever you want.
Posted Image

1.2 - Draw your particle! Yay! Particle! Make sure that the crosshair is at the center of your particle!
Posted Image

1.3 - Right click on the move clip in your library, click linkage, then check the Export for ActionScript and Export in First Frame options. Enter "fireBall_mc" for the Identifier.
Posted Image

Step 2 - Programmig.

2.1 - Put this code onto the first frame of the root timeline.

Quote:
 
particleArray = new Array();
rotSpeed = 10;
moveSpeed = 4;
maxParticles = 50;
pressed = false;
DEG_RAD = (Math.PI/180);
RAD_DEG = (180/Math.PI);
onMouseDown = function () {
pressed = true;
};
onMouseUp = function () {
pressed = false;
};
this.onEnterFrame = function() {
//add remove the dudes
if (pressed) {
  if (particleArray.length<maxParticles) {
  var m = _root.attachMovie("fireBall_mc", "particle"+_root.getNextHighestDepth(), _root.getNextHighestDepth());
  m._x = _xmouse;
  m._y = _ymouse;
  m._rotation = Math.random()*360-180;
  particleArray.push(m);
  }
} else {
  if (particleArray.length>=0) {
  var dead_mc = particleArray.shift();
  removeMovieClip(dead_mc);
  }
}
/////////////////////////////////////////////////////////////////////////////////////////////
for (j=particleArray.length-1; j>=0; j--) {
  //rotation
  var fBall = particleArray[j];
  var deg = Math.atan2(fBall._y-_ymouse, fBall._x-_xmouse)*RAD_DEG;
  var rotDist = deg-fBall._rotation;
  if (rotDist>180) {
  rotDist = 180-rotDist;
  }
  if (rotDist<-180) {
  rotDist = -180-rotDist;
  }
  if (rotDist>0) {
  fBall._rotation += rotSpeed;
  } else {
  fBall._rotation -= rotSpeed;
  }
  //move
  var rad = fBall._rotation*DEG_RAD;
  fBall._x -= Math.cos(rad)*moveSpeed;
  fBall._y -= Math.sin(rad)*moveSpeed;
}
};


Step 3 - Explaining the programming.

3.1 - This line of code makes a new array that will store the name of all of the particles later on.
Quote:
 
particleArray = new Array();


3.2 - rotSpeed is how fast the particles turn towards the mouse, move speed is how fast the particles move in the direction they're facing, and maxParticles is the maximum number of particles that can be on stage at one time.
Quote:
 
rotSpeed = 10;
moveSpeed = 4;
maxParticles = 50;


3.3 - The pressed variable keeps track of weather or not the mouse is pressed. False for up, and true for down.
Quote:
 
pressed = false;


3.4 - These handy variables are the numbers that convert radians to degrees and visa versa.
Quote:
 
DEG_RAD = (Math.PI/180);
RAD_DEG = (180/Math.PI);


3.5 - When the mouse button goes up, pressed becomes false. When the mouse button goes down, pressed becomes true. This bit of code makes it so.
Quote:
 
onMouseDown = function () {
pressed = true;
};
onMouseUp = function () {
pressed = false;
};


3.6 - Everything inside the onEnterFrame runs every frame, which in mine is 30 times per second.
Quote:
 
this.onEnterFrame = function() {
//all that other code
}


3.7 - If the mouse is pressed and there are less than the maximum amount of particles on the screen, it makes a new particle via attachMovie(). The name of that movie clip is then stored in the variable "m". The x and y positions of the particle are set to the position of the mouse, and the particles rotation is set to a random number between -180 and 180. Finally, the particles name is added to the end of particleArray.
Quote:
 
if (pressed) {
  if (particleArray.length<maxParticles) {
  var m = _root.attachMovie("fireBall_mc","particle"+_root.getNextHighestDepth(), _root.getNextHighestDepth());
  m._x = _xmouse;
  m._y = _ymouse;
  m._rotation = Math.random()*360-180;
  particleArray.push(m);
  }
}


3.8 - If the mouse is not pressed and there are still particles on the stage, it removes a particle from the beginning of particleArray.
Quote:
 
else {
  if (particleArray.length>=0) {
  var dead_mc = particleArray.shift();
  removeMovieClip(dead_mc);
  }
}


3.9 - This is a loop that moves all of the particles each frame. The first line sets the loop up to go through every name in particleArray, so all of this code is run once for every particle. The first thing the loop does is name fBall what ever the name in particleArray is, because it's a pain to type "particleArray[j]" all the time. Then it figures out the angle between the mouse and the particle, and turns the particle towards the mouse. Finally, the particle is moved forward in the direction it's facing by converting it's rotation into radians and multiplying the cos and sin of that by the moveSpeed you entered up at the top.
Quote:
 
for (j=particleArray.length-1; j>=0; j--) {
  //rotation
  var fBall = particleArray[j];
  var deg = Math.atan2(fBall._y-_ymouse, fBall._x-_xmouse)*RAD_DEG;
  var rotDist = deg-fBall._rotation;
  //fixes the 180 to -180 thing
  if (rotDist>180) {
  rotDist = 180-rotDist;
  }
  if (rotDist<-180) {
  rotDist = -180-rotDist;
  }
  //turns towards the mouse
  if (rotDist>0) {
  fBall._rotation += rotSpeed;
  } else {
  fBall._rotation -= rotSpeed;
  }
  //move
  var rad = fBall._rotation*DEG_RAD;
  fBall._x -= Math.cos(rad)*moveSpeed;
  fBall._y -= Math.sin(rad)*moveSpeed;
}


Test it, and hopefully it will work. This is pretty bare bones, you can add some pizzazz if you're feeling it.

Here's the finished product: (click and drag)



Tell me what I need to explain more or could do better… I suck at explaining/teaching, and that’s something that I'm trying to overcome.
Offline Profile Quote Post Goto Top
 
ItsaMystery
Member Avatar
Brackenwood Lightweight
Wow, thanks! I'll definetely try this one out :D
Offline Profile Quote Post Goto Top
 
TheEYE
Member Avatar
Lurys Fey Daemyt
Admin
Awesome tut Jiggs! Thanks for taking the time to do it man! :D
Offline Profile Quote Post Goto Top
 
-hashbrown-
Member Avatar
Brackenwood Lightweight
thats really nice
Offline Profile Quote Post Goto Top
 
mechablob
Member Avatar
What'cha doing?
wow.

sexy tip jiggman. :D

I'll use this one for a signature maybe... :)
Offline Profile Quote Post Goto Top
 
juggleballz
Member Avatar
I'm loose, full of juice and ready for use!
wow jacob that tut is cool man. i think it wud be cool for a flash game, where u click on ur charatcer and it charges up a particle fire ball, once fully charges drag the cursor towards the enemy, and using hit tests u cud make them act like mini fire balls. i dunno, just a suggetion.

As for explaining, i think ya did okay man. still complicated in areas. what do u mean by RADIANS? , like the radius but plural? :huh:

thanks for the tut. ill post mine up when i get a chance to make one. Im studying for a big dirty Javascript and XML exam at moment. :yfok:
Offline Profile Quote Post Goto Top
 
Vector
Member Avatar
Resident Actionscript Guru ♂
Admin
Degrees and radians are two different methods for measuring rotation.
The following image is a diagram of the values of radians, starting at the right and going anti-clockwise.

Posted Image

Basically, the only reason we do radians conversion is in order to use Math.sin and Math.cos (because they work in radians, not degrees.)
Offline Profile Quote Post Goto Top
 
Mr. Jiggmin
Member Avatar
made of tulips
Ungg... Once upon a time I had all of those things on the outside of the circle memorized. My Pre-cal teacher was insane about those. He was insane about a lot of things, but he was by far the funniest person I have ever known.

Quote:
 
wow jacob that tut is cool man. i think it wud be cool for a flash game, where u click on ur charatcer and it charges up a particle fire ball, once fully charges drag the cursor towards the enemy, and using hit tests u cud make them act like mini fire balls. i dunno, just a suggetion.

Not a bad idea... Smells like a Kimblis the Blue II spell to me. :D

Anywho, Hopefully this'll help a few people with the AS competition.
Offline Profile Quote Post Goto Top
 
Vector
Member Avatar
Resident Actionscript Guru ♂
Admin
Nice.

The values aren't really that hard to remember, and are actually quite easy to figure out.

Half way around the circle (from right to left, anti-clockwise) is PI. So directly up is half of that (PI / 2), Half of that is PI / 4 which is 45 degrees, etc.

It's just a matter of figuring out where ya neeed to get to.

If you were referring to the root 3 on 2, etc, we have to know those for General maths, Maths methods and Specialist maths, they crop up all the time.
Offline Profile Quote Post Goto Top
 
1 user reading this topic (1 Guest and 0 Anonymous)
« Previous Topic · Actionscript · Next Topic »
Add Reply