Managing multiple balls collisions with Flash: AS3 version
Some days ago Sunil Changrani sent me a the script to manage multiple balls collisions with Flash, in AS2.
Now, it’s time for Andrew Cook to give us the AS3 version.
Hi Emanuele,
I’ve been coming to your blog for over a year now. I am doing a new game with Ball vs. Ball collision and turn to your tutorials for help. I am programming my game in AS3, so I reprogrammed the tutorial in AS3. I thought you might want to check it out. There are three files. The main .fla, a document class, and a Ball class.
Thank you for starting your great blog that helps developers like me all the time. I really appreciate the way you give back to the development community. Keep it up!
This is the script to solve collisions:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 | package
{
import flash.display.MovieClip;
import flash.display.Stage;
import flash.events.Event;
import flash.events.KeyboardEvent;
public class BallCollision extends MovieClip
{
private var mcBallContainer:MovieClip;
private var nNumBalls:Number = 15;
private var nStageWidth:Number = 500;
private var nStageHeight:Number = 400;
public function BallCollision ( ) : void
{
mcBallContainer = new MovieClip ( ) ;
mcBallContainer.x = mcBallContainer.y = 0;
stage.addChild(mcBallContainer);
this.addEventListener ( Event.ENTER_FRAME, enterFrameHandler );
for ( var i = 0; i < nNumBalls; i++ )
{
var mcBall:Ball = new Ball ( Math.floor ( ( Math.random() * 12 ) - 4 ), Math.floor ( ( Math.random() * 12 ) - 4 ) );
mcBall.x = Math.random() * nStageWidth;
mcBall.y = Math.random() * nStageHeight;
mcBallContainer.addChild ( mcBall );
}
}
private function enterFrameHandler ( E:Event ) : void
{
for ( var i = 0; i < mcBallContainer.numChildren; i++ )
{
var mcBall1:* = mcBallContainer.getChildAt( i );
for ( var j = i + 1; j < mcBallContainer.numChildren; j++ )
{
var mcBall2:* = mcBallContainer.getChildAt( j );
var nDistX:Number = Math.abs ( mcBall1.x - mcBall2.x );
var nDistY:Number = Math.abs ( mcBall1.y - mcBall2.y );
var nDistance:Number = Math.sqrt ( nDistX * nDistX + nDistY * nDistY );
if ( nDistance < 20 )
{
solveBalls ( mcBall1, mcBall2 );
}
}
}
}
private function solveBalls ( MCBallA:MovieClip, MCBallB:MovieClip ) : void
{
var nX1:Number = MCBallA.x;
var nY1:Number = MCBallA.y;
var nDistX:Number = MCBallB.x - nX1;
var nDistY:Number = MCBallB.y - nY1;
var nDistance:Number = Math.sqrt ( nDistX * nDistX + nDistY * nDistY );
var nRadiusA:Number = MCBallA.width/2;
var nRadiusB:Number = MCBallB.width/2;
//var nRadius:Number = 10;
var nNormalX:Number = nDistX/nDistance;
var nNormalY:Number = nDistY/nDistance;
var nMidpointX:Number = ( nX1 + MCBallB.x )/2;
var nMidpointY:Number = ( nY1 + MCBallB.y )/2;
MCBallA.x = nMidpointX - nNormalX * nRadiusA;
MCBallA.y = nMidpointY - nNormalY * nRadiusA;
MCBallB.x = nMidpointX + nNormalX * nRadiusB;
MCBallB.y = nMidpointY + nNormalY * nRadiusB;
var nVector:Number = ( ( MCBallA.nSpeedX - MCBallB.nSpeedX ) * nNormalX )+ ( ( MCBallA.nSpeedY - MCBallB.nSpeedY ) * nNormalY );
var nVelX:Number = nVector * nNormalX;
var nVelY:Number = nVector * nNormalY;
MCBallA.nSpeedX -= nVelX;
MCBallA.nSpeedY -= nVelY;
MCBallB.nSpeedX += nVelX;
MCBallB.nSpeedY += nVelY;
}
}
} |
And this is the one to manage balls
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | package
{
import flash.events.Event;
import flash.display.MovieClip;
public class Ball extends MovieClip
{
public var nSpeedX:Number;
public var nSpeedY:Number;
private var nStageWidth:Number = 500;
private var nStageHeight:Number = 400;
public function Ball ( NSpeedX:Number, NSpeedY:Number ) : void
{
nSpeedX = NSpeedX;
nSpeedY = NSpeedY;
this.addEventListener ( Event.ENTER_FRAME, onEnterFrameHandler );
}
private function onEnterFrameHandler ( E:Event ) : void
{
this.x -= nSpeedX;
this.y -= nSpeedY;
if ( this.x >= nStageWidth - 10 )
{
this.x = nStageWidth - 10;
nSpeedX *= -1;
}
else if ( this.x <= 10 )
{
this.x = 10;
nSpeedX *= -1;
}
if ( this.y >= nStageHeight - 10 )
{
this.y = nStageHeight - 10;
nSpeedY *= -1;
}
else if ( this.y <= 10 )
{
this.y = 10;
nSpeedY *= -1;
}
}
}
} |
Enjoy the result
They can be easily customized to meet the unique requirements of your project.















(29 votes, average: 4.55 out of 5)










This post has 36 comments
Jack Hopkins
How many balls can this handle before it lags?
Nice post!
CopyleftDev
I was able to get to a 1500 ball count before I saw a major chuck of lag. :) AS3 is no joke and it is only getting better :)
Jack Hopkins
Thats quite a leap from the 300 we saw in AS2
I have CS3 and I think I will take the leap to AS3
after today!
Kesh
How would u make an angle that the ball would hit? like a ball hitting an angled wall.
|
|
O – - -/
Kesh
okay the lines didnt work out well lol. lets try this again.
…..|
…..|
…..|
O—-/
where the dashes are the balls old places.
Robin
Balls are touching. Gay :P
Scarybug
change
var nDistance:Number = Math.sqrt ( nDistX * nDistX + nDistY * nDistY );
if ( nDistance <20 )
{
to
var nDistanceSqr:Number = (nDistX * nDistX) + (nDistY * nDistY);
if ( nDistanceSqr <400 )
{
for extra speed.
Chris
Additionally, There is no need to take the absolute value of nDistX and nDistY in these lines…
var nDistX:Number = Math.abs ( mcBall1.x – mcBall2.x );
var nDistY:Number = Math.abs ( mcBall1.y – mcBall2.y );
Once you square them it doesn’t matter if they are negative or not. Shouldn’t be a huge boost but every little bit helps. Also, while we are optimizing there is no need really to declare nDistX and nDistY explicitly but I can see why it would be helpful for the tutorial.
Mark
Great work!!
Any thoughts on what happens if a ball has simultanious collisions from both sides?
AKA Newtons cradle?
Marc
Does anyone know how to add the functionality of being able to grab, hold and throw these balls? This is a great effort btw.
bob
does anyone know how the collisionBall cobject is created? i cant see it anywhere.
bob
u say 1500????
it laggs with me with 300 balls
150 balls is ok on my pc.
Nathan
Hey Emanuele,
I’m just started using AS3. I’m creating a game where you drive a bumper car, there’s two variables, speed and rotate. Is there way you can make a realistic bounce off the walls. Thanx
Adobe Flash CS3- AS3 and AS2 game tutorials roundup | Lemlinh.com
[...] Read more [...]
Nick
Andrew, this is great, *however* you have not commented your code, in particular your physics (use of the dot product etc.) so you are assuming everyone knows what this does. I ranked this 4 out of 5, it is otherwise a superbly well structured and relatively fast rehash on the bouncy ball theme.
Joe
yes some explanation of the physics would be greatly appreciated…
anyone want to take a stab at it…
maybe I’ll try.
john
hey,i used this code in my own game. and stumbled upon a problem. when you increase the balldiameter, then they wotn bounce anymore, they just stik to eachother and shake like hell. on balldiameter of 30 they sometimes get knocked out of this stickiness, but when made the ball diameter 40 they just stick to 1 bick chunk, and shake.
im talking about this:
if ( nDistance <20 )
{solveBalls ( mcBall1, mcBall2 );}
if made the 20 into 30 or 40, this happens
FlashHamsta
I wanted to, instead of a variable boundary, add walls. I’ve tried swapping the edge detection script in ball.as with “this.hitTestObject(wall)” (I have a non-dynamic movieclip on the stage instanced as wall) but the ball ignores it and goes straight through. help appreciated.
George Kazanjian
Anyone care to help explain this definition ?
var mcBall1:* = mcBallContainer.getChildAt( i );
especially the * . Do we mean McBall1 is of type object and we don’t care which type at this point ?
Thanks in advance
Ciro Continisio
If I remember correctly, mcBall1:* means that mcBall1 is of type undefined, so yes, it can be any type.
AS3 Ball on Ball Collision, Part 1 « Dan Cotton
[...] detection and physics are both a major part of creating a pool game, and after finding this (Linky ) article on Emanuele Feronato’s website, I choseto modify it for my style of naming [...]
Saiyidah
Hi there, I am currently using these exact codes for a school project of mine. I am very very new to coding and of course AS3. My question is that, I have actually import these two classes into the fla file that I’m working on. But I want the balls to be remove after let say frame #220. How do I go about with it? Anybody can help me, please?
Thank you very much. I really hope somebody will reply.
Regards,
Saiyidah
DQvsRA
Hello.
Interesting thing will be if we want to calculate and create a multi collision balls with different radius. Is anybode know how to create this effects?
Nicholas
Can someone debug this code and tell me out a formula that can solve the distance between my floor of my space and the ball object. Here is the start.
if(ball.ypos > floor)
{
ball.ypos = floor;
// we want the bouncing noise to stop when the balls are not bouncing
trace(“ball hitting floor variable required”);
knock.play();
ball.vy *= bounce;
}
where floor variable causes ball to “bounce” and figure out their distances and if the number is close to 0, to omit the sound of a ball bouncing on glass.
Aditya
Hi Emanuele,
Firstly muchos gracias and kudos for your great blog.
Secondly
Thank you Andrew Cook for working this out in AS3.
i have been Obsessing over this for quite some time now. ball vs ball collision was my first experiment when i started learning action script and recently i have been on the look out for getting redoing the same with Pixel Perfect Collision Detection.
had come across this great CDK by Corey Oniel
http://www.coreyoneil.com/portfolio/index.php?project=5. had been successful at detecting the collisions using it but was unable to handle the ball reflections after collision. I find this Example very good and helpful.
Thanks
Aditya
well i got what i was trying for utilizing the CDK and the angle handling from Andrew cooks implementation . A decent pixel based object collision detection.
http://adityagameprogrammer.blogspot.com/2009/12/pixel-perfect-collision-system-as3.html
i would appreciate your input on this if you find the time.
Pete
very elegant solution – I was working on the same thing, but mine seemed more complicated since I was rotating the velocity vectors to calculate the normals.
One issue with this: you determine if the balls are closer than the radius and move them back to the point at which they are just touching…you should figure how far back you moved, and then move a corresponding amount AFTER the collision. right now if they are very fast and the overlap is quite large, the bounce off effect is slightly distorted since they are simply moving back to the point of collision at the start of the next frame. minor point depending upon the frame rate of the movie and the radius of the balls, but something to consider…
carograph
beautiful solution. i had been tampering with this for a while, as i am learning to switch from AS2 to AS3. Thanks for the inspiration.
Now for a question:
would it be possible to load this swf into another fla, and using a movie clip as holder, that would increase and decrease in size, thus letting the balls react to the surrounding space it is being loaded into? volume vs. pressure sort of thing? i hope i am explaining myself clearly. any suggestions would be very helpful. I am a gamer newby, so help very much appreciated.
Cheerio
carograph
Kreis-Kreis Collision Detecion mit Prediciton - Flashforum
[...] Ahnung ob das einfacher ist (hatte das von hgseib nicht angeschaut)… Managing multiple balls collisions with Flash: AS3 version – Emanuele Feronato Managing ball vs ball collision with Flash – Emanuele Feronato __________________ . [...]
Andrea
Sorry, how can the listener be removed?
Thank you!
Bye
Christian
Whenever I use this, the balls stick together, until another ball knocks them apart
anant
what if the balls have different size will it work
anant
what if the balls have different sizes will it work.
I mean will collisions be detected at edges or it will overlap till it detects hittest and then move apart
Camille
I’m not a flash developer but I can understand a few actionscript but can someone please elaborate this? How come when I change the stage size it no longer has the same effect? Balls appears disappears, flicker from here to there… Please help. Thank you!
Portfolio of Nikolaj Stausbøl – Designer and Artist Creative coding of logotype - Portfolio of Nikolaj Stausbøl
[...] looked realistic or worked flawlessly. From searching the web I found this guy Andrew Cook’s script which was just what I [...]
Han Erim
Wonderful tutorial lady.
Thanks
Han