Install Circle Chain on your iPhone for free and get the source code!! 645 downloads to go - last updated: April 21, 2012

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

And download the source code

Rate this post: 1 Star2 Stars3 Stars4 Stars5 Stars (29 votes, average: 4.55 out of 5)
Loading ... Loading ...
Flash Templates provided by Template Monster are pre-made web design products developed using Flash technology.
They can be easily customized to meet the unique requirements of your project.
Be my fan on Facebook and follow me on Twitter! Exclusive content for my Facebook fans and Twitter followers

This post has 36 comments

  1. Jack Hopkins

    on June 8, 2008 at 12:16 am

    How many balls can this handle before it lags?

    Nice post!

  2. CopyleftDev

    on June 8, 2008 at 6:56 am

    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 :)

  3. Jack Hopkins

    on June 8, 2008 at 11:58 am

    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!

  4. Kesh

    on June 9, 2008 at 7:58 am

    How would u make an angle that the ball would hit? like a ball hitting an angled wall.

    |
    |
    O – - -/

  5. Kesh

    on June 9, 2008 at 8:00 am

    okay the lines didnt work out well lol. lets try this again.

    …..|
    …..|
    …..|
    O—-/

    where the dashes are the balls old places.

  6. Robin

    on June 9, 2008 at 9:26 am

    Balls are touching. Gay :P

  7. Scarybug

    on June 9, 2008 at 5:06 pm

    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.

  8. Chris

    on June 9, 2008 at 9:25 pm

    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.

  9. Mark

    on July 17, 2008 at 5:32 am

    Great work!!

    Any thoughts on what happens if a ball has simultanious collisions from both sides?

    AKA Newtons cradle?

  10. Marc

    on July 18, 2008 at 10:56 am

    Does anyone know how to add the functionality of being able to grab, hold and throw these balls? This is a great effort btw.

  11. bob

    on August 16, 2008 at 7:08 pm

    does anyone know how the collisionBall cobject is created? i cant see it anywhere.

  12. bob

    on August 16, 2008 at 10:00 pm

    u say 1500????
    it laggs with me with 300 balls
    150 balls is ok on my pc.

  13. Nathan

    on August 18, 2008 at 10:44 pm

    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

  14. Adobe Flash CS3- AS3 and AS2 game tutorials roundup | Lemlinh.com

    on August 19, 2008 at 6:36 pm

    [...] Read more [...]

  15. Nick

    on August 22, 2008 at 8:28 pm

    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.

  16. Joe

    on September 19, 2008 at 3:53 pm

    yes some explanation of the physics would be greatly appreciated…
    anyone want to take a stab at it…
    maybe I’ll try.

  17. john

    on October 11, 2008 at 8:42 am

    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

  18. FlashHamsta

    on October 31, 2008 at 11:12 am

    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.

  19. George Kazanjian

    on February 1, 2009 at 2:11 am

    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

  20. Ciro Continisio

    on February 26, 2009 at 4:48 pm

    If I remember correctly, mcBall1:* means that mcBall1 is of type undefined, so yes, it can be any type.

  21. AS3 Ball on Ball Collision, Part 1 « Dan Cotton

    on November 10, 2009 at 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 [...]

  22. Saiyidah

    on November 16, 2009 at 4:15 pm

    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

  23. DQvsRA

    on November 16, 2009 at 4:49 pm

    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?

  24. Nicholas

    on November 23, 2009 at 5:35 am

    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.

  25. Aditya

    on December 29, 2009 at 11:35 am

    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

  26. Aditya

    on December 29, 2009 at 2:54 pm

    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.

  27. Pete

    on January 12, 2010 at 6:09 pm

    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…

  28. carograph

    on February 15, 2010 at 5:07 pm

    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

  29. Kreis-Kreis Collision Detecion mit Prediciton - Flashforum

    on May 20, 2010 at 5:43 pm

    [...] 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 __________________ . [...]

  30. Andrea

    on October 19, 2011 at 5:51 pm

    Sorry, how can the listener be removed?
    Thank you!
    Bye

  31. Christian

    on December 6, 2011 at 7:29 am

    Whenever I use this, the balls stick together, until another ball knocks them apart

  32. anant

    on December 13, 2011 at 3:13 pm

    what if the balls have different size will it work

  33. anant

    on December 13, 2011 at 3:15 pm

    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

  34. Camille

    on January 9, 2012 at 5:18 am

    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!

  35. Portfolio of Nikolaj Stausbøl – Designer and Artist Creative coding of logotype - Portfolio of Nikolaj Stausbøl

    on February 6, 2012 at 10:18 am

    [...] looked realistic or worked flawlessly. From searching the web I found this guy Andrew Cook’s script which was just what I [...]

  36. Han Erim

    on February 8, 2012 at 5:24 pm

    Wonderful tutorial lady.

    Thanks

    Han