Managing multiple balls collisions with Flash: AS3 version
Filed Under Actionscript 3, Flash, Tutorials, Users contributions • 28 Comments
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.
28 Responses to “Managing multiple balls collisions with Flash: AS3 version”
Leave a Reply
Trackbacks
-
Adobe Flash CS3- AS3 and AS2 game tutorials roundup | Lemlinh.com on
August 19th, 2008 6:36 pm
[...] Read more [...]
-
AS3 Ball on Ball Collision, Part 1 « Dan Cotton on
November 10th, 2009 4:14 pm
[...] 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 [...]
- Citrus Engine released for free for learning
- My epic fail with ClickBank
- Get up to $100,000 for your next Flash game with Mochi GAME Developer Fund
- Create a dynamic content animated footer ad for your site in just 9 jQuery lines – 17 lines version
- Sell sitelocked version of your Flash games and even .fla sources to Free Online Games
- Protect your work from ActionScript code theft with SWF Protector
- Create a dynamic content animated footer ad for your site in just 9 jQuery lines
- Understanding Box2D’s one-way platforms, aka CLOUDS
- Triqui MochiAds Arcade plugin for WordPress upgraded to 1.2
- Box2D Flash game creation tutorial – part 2
- Create a Lightbox effect only with CSS - no javascript needed
- Flash game creation tutorial - part 1
- Create a Flash Racing Game Tutorial
- Flash game creation tutorial - part 2
- Make a Flash game like Flash Element Tower Defense - Part 2
- Flash game creation tutorial - part 3
- Triqui MochiAds Arcade plugin for WordPress official page
- Make a Flash game like Flash Element Tower Defense - Part 1
- Create a flash draw game like Line Rider or others - part 1
- Create a flash artillery game - step 1
- Flash game creation tutorial – part 5.2 (4.88/5)
- Create a flash artillery game – step 1 (4.79/5)
- Create a Flash Racing Game Tutorial (4.76/5)
- Create a survival horror game in Flash tutorial – part 1 (4.74/5)
- Create a flash artillery game – step 2 (4.74/5)
- Creation of a Flash arcade site using WordPress – step 2 (4.73/5)
- Flash game creation tutorial – part 1 (4.71/5)
- Flash game creation tutorial – part 2 (4.71/5)
- Create a flash draw game like Line Rider or others – part 1 (4.69/5)
- Creation of a platform game with Flash – step 2 (4.68/5)

(18 votes, average: 4.61 out of 5)



How many balls can this handle before it lags?
Nice post!
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 :)
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!
How would u make an angle that the ball would hit? like a ball hitting an angled wall.
|
|
O – - -/
okay the lines didnt work out well lol. lets try this again.
…..|
…..|
…..|
O—-/
where the dashes are the balls old places.
Balls are touching. Gay :P
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.
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.
Great work!!
Any thoughts on what happens if a ball has simultanious collisions from both sides?
AKA Newtons cradle?
Does anyone know how to add the functionality of being able to grab, hold and throw these balls? This is a great effort btw.
does anyone know how the collisionBall cobject is created? i cant see it anywhere.
u say 1500????
it laggs with me with 300 balls
150 balls is ok on my pc.
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
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.
yes some explanation of the physics would be greatly appreciated…
anyone want to take a stab at it…
maybe I’ll try.
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
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.
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
If I remember correctly, mcBall1:* means that mcBall1 is of type undefined, so yes, it can be any type.
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
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?
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.
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
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.
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…
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