Managing multiple ball collisions in Flash as2
By admin • Aug 20th, 2008 • Category: TutorialsThis 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
-
stop();
-
t = 0;
-
_root.attachMovie("blip", "blip", _root.getNextHighestDepth(), {_x:1500, _y:200});
-
_root.createEmptyMovieClip("container_movie", _root.getNextHighestDepth());
-
blip.onEnterFrame = function() {
-
if (Math.random()*1000<100 and t<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;
-
circle.onEnterFrame = function() {
-
this._x -= this.xspeed;
-
this._y -= this.yspeed;
-
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;
-
}
-
};
-
}
-
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);
-
if (dist<20) {
-
_root.solveBalls(a, b);
-
} else {
-
}
-
}
-
}
-
};
-
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;
-
normalX = dx/dist;
-
normalY = dy/dist;
-
midpointX = (x1+ballB._x)/2;
-
midpointY = (y1+ballB._y)/2;
-
ballA._x = midpointX-normalX*radius;
-
ballA._y = midpointY-normalY*radius;
-
ballB._x = midpointX+normalX*radius;
-
ballB._y = midpointY+normalY*radius;
-
dVector = (ballA.xspeed-ballB.xspeed)*normalX+(ballA.yspeed-ballB.yspeed)*normalY;
-
dvx = dVector*normalX;
-
dvy = dVector*normalY;
-
ballA.xspeed -= dvx;
-
ballA.yspeed -= dvy;
-
ballB.xspeed += dvx;
-
ballB.yspeed += dvy;
-
}
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)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
