Managing multiple balls collisions with Flash

The first post of the new year (you should know the new year starts on May, 27th) is made by Sunil Changrani and it’s about managing multiple balls collisions with Flash.

I already published a tutorial about Managing ball vs ball collision with Flash but this time we’ll manage any number of balls.

Sunil was just making a Flash game and he ended up getting stuck when he needed a lot of circles to collide with each other.

With some help from Tony Pa, Voidskipper and Kazama_bee, ended up making some nice perfect collisions.

In the movie there are two symbols, one empty movieclip called blip and a movieclip called circle (which has the ball)

So here it is the commented code:

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
stop();
t = 0;
dx = 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>490) {
				this._x = 490;
				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<t; i++) {
		a = _root.container_movie["circle"+i];
		for (j=i+1; j<t; 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 this is the result: look at the balls… how interesting!

Now tell me for how long will we see games based on this engine… I have one idea… download the source code and thank all developers.

Rate this post: 1 Star2 Stars3 Stars4 Stars5 Stars (17 votes, average: 4.94 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 25 comments

  1. Nerdsrule10

    on May 27, 2008 at 11:35 pm

    Hey..love everyone one of your tutorials..but a few questions. Whenever i go to the main page of your site, it freezes and i have to wait untill it opens up adobe reader, and it says theres an error, and i check and its blank.. i have no idea why this is happening. also with the tutorial, is there any way to have multiple mouse events with the same object? Like being able to click each ball. Everytime i do this it just works for the first one made. I have no clue how to fix this? How would you do it, if you do it at all? Thanks

  2. Kesh

    on May 28, 2008 at 12:27 am

    Thats cool. Try adding gravity to those balls. It is a hard thing to do i think. I had to make a class for that on my game, Jubble. I haven’t Published it yet but you can see it on the forums. I made a class and just declared the gravity vars.

  3. Gregory Athons

    on May 28, 2008 at 12:36 am

    Wow, just the other day I was googling for some examples on multiple ball collision and found an example on this site. But that previous post was limited to do only so many balls. And now, this example provides the programmer to do, what it seems, at least 50 without any overlapping.

    Thanks again “PROgrammer”

  4. Sodaplayer

    on May 28, 2008 at 4:40 am

    @Kesh
    Gravity isn’t so hard to do. Just add to the yspeed every frame. Nice collisions, the balls no longer get stuck to each other.

  5. voidSkipper

    on May 28, 2008 at 5:24 am

    Hey Emanuele, thanks for the citation – nice to be on such a prestigious blog!

    I’d just make a small suggestion, in the loop, rather than what you have now, try

    var dist = dx*dx+dy*dy;
    if (dist<400) {
    _root.solveBalls(a,b);
    }

    (eg, is less than the distance squared)

    This eliminates the extremely costly Math.sqrt() function.

  6. Sunil Changrani

    on May 28, 2008 at 11:34 am

    Thanks for putting up the tutorial Emanuele, I hope everyone benefits from it!

    Even I was googling for multiball collisions, Since I didn’t find any thing that I could use.. I ended up with this.

  7. Krystian Majewski

    on May 28, 2008 at 12:01 pm

    Well, you see – that’s not very efficient. You are checking collision between every possible pair of circle in every frame. Just running that program maxes out my CPU and we don’t even have any extraordinary graphical effects.

    For this amount of objects, it might be wise to implement a smarter collision detection algorythm. Try this one:
    http://www.gskinner.com/blog/archives/2008/01/proximitymanage.html

    And here is a nice example:
    http://www.nulldesign.de/exp/expviewer.php?file=f9_particle2.swf&width=500&height=400

  8. Scarybug

    on May 28, 2008 at 5:01 pm

    Great point on eliminating the square root calculation, Voidskipper!

    And thanks for pointing out the grid-based proximity manager, Krystian.

    It’s great when a blog becomes so popular that it attracts expert commenters ^_^

  9. Xodus

    on May 28, 2008 at 6:11 pm

    What is the blip….srry, im not good at AS.

  10. Sunil Changrani

    on May 28, 2008 at 6:44 pm

    Blip is just an empty movieclip, I use it because I like to put codes that execute every frame into the onenterframe function of a movieclip. Although this may not be standard procedure, I find I can organize stuff well this way (atleast in my mind)

  11. Xodus

    on May 29, 2008 at 9:07 am

    can’t you just say:
    onEnterFrame = function() {

    it should just work the same right?

  12. voidSkipper

    on May 29, 2008 at 9:13 am

    Sunil – that method is slower than just looping through an array. Using a large amount of onEnterFrame handlers is not encouraged.

  13. styxtwo

    on May 29, 2008 at 1:47 pm

    very impressive, not the unlimited ball colision, but the way you could put that many in without causing lag. :)

  14. Sunil Changrani

    on May 29, 2008 at 6:48 pm

    I agree its slower,
    I’m not expert, An hour before I wrote this tutorial I was wondering how to make two balls collide…

  15. brart

    on May 31, 2008 at 4:27 pm

    I made a port to as3. I’m fixing the last bugs

    I also will make a mode so it can calculate this with different massen… if a heavy one hits a light one the light one gains a great boost of speed and the heavy one just a litle.

    Wil have it ready tommorow and wil also put it on rapidshare if there are enough people want that.

    brart

  16. Bradley

    on June 4, 2008 at 8:29 am

    This code doesn’t seem very effiecent. Check the first ball against every other one, the second against every one but the first, and so forth. That adds up to 49+48+…+3+2+1 equations solved every frame, or 1275. Mutiply that by a modest 10fps? 12250 equations per second.

    Not very efficient, though it is easier to understand and code that some more advanced algorithms. A final point, if 100 balls are used, that’s 50500 times the lines inside the “for loop” are called. hmm. I don’t know about my computer, but I couldn’t calculate that many equations per second.

    Good suggestion Krystian to reduce the number of checks, and also voidSkipper, that’s a great idea!

  17. Managing multiple balls collisions with Flash: AS3 version : Emanuele Feronato - italian geek and PROgrammer

    on June 7, 2008 at 11:55 pm

    [...] days ago Sunil Changrani sent me a the script to manage multiple balls collisions with Flash, in [...]

  18. Malboro Jones

    on September 15, 2008 at 11:14 pm

    heeeey can someone help me,
    I’ve searched for hours on the web and cant find out how to make a boundary!
    I have a ball game, simply the ball moves around at the moment, I’m really new to Flash Gaming so I’m just testing things right now, but I seriously need to know how to stop the ball from flying off the stage!
    If you could send me instructions directly via email that would be great!
    malborojones@hotmail.co.uk

    All help will be very much appreciated thank you!

  19. Awoke

    on November 20, 2008 at 5:54 pm

    It’s exactly what I was looking for, thanks :]

  20. Z_dub

    on October 26, 2009 at 4:36 pm

    hello, im working on a project for school and ive gome to a little roadblock, i hope this is the right thread to post on
    hered teh code ive got so far, the names are from a tutorial i used to pretty much start it

    chevelle_mc.addEventListener(MouseEvent.MOUSE_UP, carStart)
    function carStart(carMove:Event):void{
    Mouse.hide()
    chevelle_mc.startDrag();
    };
    //1.
    truck_mc.addEventListener(Event.ENTER_FRAME, circleHit);

    //2.
    function circleHit(truckMove:Event):void {
    if (truck_mc.hitTestObject(chevelle_mc) ){
    text_mc.visible = true;
    } else {
    text_mc.visible = false;
    }
    };

    i have two problems, the first is that i have multiple trucks, there all named accordingly, truck_mc, truck2_mc and so on…but only the first one will collide with my ball. where would i put the code to make so that it also collides with the rest of them?
    also, i want the video to stop until i can click the ball, and ive seen a lot of other tutorials that say to use a stop() method, where would i put that, and how would i phrase it?

  21. GhostlyGamer

    on November 4, 2009 at 2:57 am

    This is a very cool tutorial, but I was wondering how to make a function for when the mouse rollsover a circle, my _root.lives, goes -1. Is there a way I can go this?

  22. atoi_power

    on December 31, 2009 at 2:32 am

    This cool,

    i try to collided between two ball, i mean like pool game but i’m using on press key function, it seem I’ve gone no where, can some one help me on this,,,

  23. Darren

    on May 10, 2011 at 8:51 am

    Hi,
    this version doesn’t take into account ball’s mass like the one in this page
    http://www.emanueleferonato.com/2007/08/19/managing-ball-vs-ball-collision-with-flash/

    Can you revise this version ?

  24. Aby

    on June 30, 2011 at 10:44 am

    Any body…pls help me to stop the balls after 15 sec :(

  25. rams

    on December 14, 2011 at 1:09 pm

    i didn`t understood the function of below line.. plz somebody explain….
    “dVector = (ballA.xspeed-ballB.xspeed)*normalX+(ballA.yspeed-ballB.yspeed)*normalY”

    thanqqqqqqqqq