Subscribe to this Blog

Managing multiple ball collisions in Flash as2

By admin • Aug 20th, 2008 • Category: Tutorials

This was a tutorial I had created for another website some time ago. I thought its quite useful. The people who helped were tonypa, voidskipper and kazama_bee from Mochiforums.

I've used two symbols, 1 empty movieclip named blip and 1 movieclip called circle (which has the circle)

the code is like this

  1. stop();
  2. t = 0;
  3. _root.attachMovie("blip", "blip", _root.getNextHighestDepth(), {_x:1500, _y:200});
  4. _root.createEmptyMovieClip("container_movie", _root.getNextHighestDepth());
  5. blip.onEnterFrame = function() {
  6. if (Math.random()*1000<100 and t<50) {
  7. circle = container_movie.attachMovie("circle", "circle"+t, container_movie.getNextHighestDepth(), {_width:a, _height:b, _x:(20+Math.random()*300), _y:(20+Math.random()*300), _rotation:Math.random()*300});
  8. t++;
  9. circle.xspeed = Math.random()*9;
  10. circle.yspeed = Math.random()*9;
  11. circle.onEnterFrame = function() {
  12. this._x -= this.xspeed;
  13. this._y -= this.yspeed;
  14. if (this._x<10) {
  15. this._x=10;
  16. this.xspeed = -this.xspeed;
  17. }
  18. if (this._x>590) {
  19. this._x=590;
  20. this.xspeed = -this.xspeed;
  21. }
  22. if (this._y<10) {
  23. this._y=10;
  24. this.yspeed = -this.yspeed;
  25. }
  26. if (this._y>390) {
  27. this._y=390;
  28. this.yspeed = -this.yspeed;
  29. }
  30. };
  31. }
  32. for (i=0; i
  33. a = _root.container_movie["circle"+i];
  34. for (j=i+1; j
  35. b = _root.container_movie["circle"+j];
  36. var dx = b._x-a._x;
  37. var dy = b._y-a._y;
  38. var dist = Math.sqrt(dx*dx+dy*dy);
  39. if (dist<20) {
  40. _root.solveBalls(a, b);
  41. } else {
  42. }
  43. }
  44. }
  45. };
  46. function solveBalls(ballA, ballB) {
  47. var x1 = ballA._x;
  48. var y1 = ballA._y;
  49. var dx = ballB._x-x1;
  50. var dy = ballB._y-y1;
  51. var dist = Math.sqrt(dx*dx+dy*dy);
  52. radius = 10;
  53. normalX = dx/dist;
  54. normalY = dy/dist;
  55. midpointX = (x1+ballB._x)/2;
  56. midpointY = (y1+ballB._y)/2;
  57. ballA._x = midpointX-normalX*radius;
  58. ballA._y = midpointY-normalY*radius;
  59. ballB._x = midpointX+normalX*radius;
  60. ballB._y = midpointY+normalY*radius;
  61. dVector = (ballA.xspeed-ballB.xspeed)*normalX+(ballA.yspeed-ballB.yspeed)*normalY;
  62. dvx = dVector*normalX;
  63. dvy = dVector*normalY;
  64. ballA.xspeed -= dvx;
  65. ballA.yspeed -= dvy;
  66. ballB.xspeed += dvx;
  67. ballB.yspeed += dvy;
  68. }

Explaination

stop();
t = 0;
//Creating variables

_root.attachMovie("blip", "blip", _root.getNextHighestDepth(), {_x:1500, _y:200});
_root.createEmptyMovieClip("container_movie", _root.getNextHighestDepth());
//attaching the movieclips

blip.onEnterFrame = function() {
//this is the function that executes every frame

if (Math.random()*1000<100 and t<50) {
//This condition adds another circle after a certain random interval till total circles are 50

circle = container_movie.attachMovie("circle", "circle"+t, container_movie.getNextHighestDepth(), {_width:a, _height:b, _x:(20+Math.random()*300), _y:(20+Math.random()*300), _rotation:Math.random()*300});
t++
circle.xspeed = Math.random()*9;
circle.yspeed = Math.random()*9;
//Creating the circle with random x and y speeds.

circle.onEnterFrame = function() {
this._x -= this.xspeed;
this._y -= this.yspeed;
//Motion of the circles

if (this._x<10) {
this._x=10;
this.xspeed = -this.xspeed;
}
if (this._x>590) {
this._x=590;
this.xspeed = -this.xspeed;
}
if (this._y<10) {
this._y=10;
this.yspeed = -this.yspeed;
}
if (this._y>390) {
this._y=390;
this.yspeed = -this.yspeed;
}
//Making sure the circle won't go out of the boundaries.

};
}
//From here I start checking for collisions of the circles
for (i=0; i
a = _root.container_movie["circle"+i];
for (j=i+1; j
b = _root.container_movie["circle"+j];
var dx = b._x-a._x;
var dy = b._y-a._y;
var dist = Math.sqrt(dx*dx+dy*dy);
//Checking the distances between two circles.
if (dist<20) {
_root.solveBalls(a, b);
//The circles I've taken are of radius 10, so if distance <20 then they collide, so I call a function.
} else {
}
}
}
};

//This function is provided by kazama_bee at mochi forums. I'll try my best to explain it
function solveBalls(ballA, ballB) {
var x1 = ballA._x;
var y1 = ballA._y;
var dx = ballB._x-x1;
var dy = ballB._y-y1;
var dist = Math.sqrt(dx*dx+dy*dy);
radius = 10;
//it calculates the distance, i could have passed it to the function but it works this way

normalX = dx/dist;
normalY = dy/dist;
midpointX = (x1+ballB._x)/2;
midpointY = (y1+ballB._y)/2;
//Now this calculates the normal and mid points..

ballA._x = midpointX-normalX*radius;
ballA._y = midpointY-normalY*radius;
ballB._x = midpointX+normalX*radius;
ballB._y = midpointY+normalY*radius;
//shifts the two circle two a different location so they don't hit each other

dVector = (ballA.xspeed-ballB.xspeed)*normalX+(ballA.yspeed-ballB.yspeed)*normalY;
dvx = dVector*normalX;
dvy = dVector*normalY;
//This calculates the new speeds for the circles

ballA.xspeed -= dvx;
ballA.yspeed -= dvy;
ballB.xspeed += dvx;
ballB.yspeed += dvy;
//assigns the new values
}

And the end result looks like this.

If you liked this post, Buy me some beer (or coffee)

Tagged as: , , ,

admin is An engineering student from India. Enjoying his life both in the real world and in cyberspace
Email this author | All posts by admin

Comments are closed.