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:

ACTIONSCRIPT:
  1. stop();
  2. t = 0;
  3. dx = 0;
  4. //Creating variables
  5. _root.attachMovie("blip","blip",_root.getNextHighestDepth(),{_x:1500, _y:200});
  6. _root.createEmptyMovieClip("container_movie",_root.getNextHighestDepth());
  7. //attaching the movieclips
  8. blip.onEnterFrame = function() {
  9.     //this is the function that executes every frame
  10.     if (Math.random()*1000<100 and t<50) {
  11.         //This condition adds another circle after a certain random interval till total circles are 50
  12.  
  13.         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});
  14.         t++;
  15.         circle.xspeed = Math.random()*9;
  16.         circle.yspeed = Math.random()*9;
  17.         //Creating the circle with random x and y speeds.
  18.         circle.onEnterFrame = function() {
  19.             this._x -= this.xspeed;
  20.             this._y -= this.yspeed;
  21.             //Motion of the circles
  22.             if (this._x<10) {
  23.                 this._x = 10;
  24.                 this.xspeed = -this.xspeed;
  25.             }
  26.             if (this._x>490) {
  27.                 this._x = 490;
  28.                 this.xspeed = -this.xspeed;
  29.             }
  30.             if (this._y<10) {
  31.                 this._y = 10;
  32.                 this.yspeed = -this.yspeed;
  33.             }
  34.             if (this._y>390) {
  35.                 this._y = 390;
  36.                 this.yspeed = -this.yspeed;
  37.             }
  38.             //Making sure the circle won't go out of the boundaries.
  39.         };
  40.     }
  41.     //From here I start checking for collisions of the circles
  42.     for (i=0; i<t; i++) {
  43.         a = _root.container_movie["circle"+i];
  44.         for (j=i+1; j<t; j++) {
  45.             b = _root.container_movie["circle"+j];
  46.             var dx = b._x-a._x;
  47.             var dy = b._y-a._y;
  48.             var dist = Math.sqrt(dx*dx+dy*dy);
  49.             //Checking the distances between two circles.
  50.             if (dist<20) {
  51.                 _root.solveBalls(a,b);
  52.                 //The circles I've taken are of radius 10, so if distance <20 then they collide, so I call a function.
  53.             }
  54.             else {
  55.             }
  56.         }
  57.     }
  58. };
  59. //This function is provided by kazama_bee at mochi forums. I'll try my best to explain it
  60. function solveBalls(ballA, ballB) {
  61.     var x1 = ballA._x;
  62.     var y1 = ballA._y;
  63.     var dx = ballB._x-x1;
  64.     var dy = ballB._y-y1;
  65.     var dist = Math.sqrt(dx*dx+dy*dy);
  66.     radius = 10;
  67.     //it calculates the distance, i could have passed it to the function but it works this way
  68.     normalX = dx/dist;
  69.     normalY = dy/dist;
  70.     midpointX = (x1+ballB._x)/2;
  71.     midpointY = (y1+ballB._y)/2;
  72.     //Now this calculates the normal and mid points..
  73.     ballA._x = midpointX-normalX*radius;
  74.     ballA._y = midpointY-normalY*radius;
  75.     ballB._x = midpointX+normalX*radius;
  76.     ballB._y = midpointY+normalY*radius;
  77.     //shifts the two circle two a different location so they don't hit each other
  78.     dVector = (ballA.xspeed-ballB.xspeed)*normalX+(ballA.yspeed-ballB.yspeed)*normalY;
  79.     dvx = dVector*normalX;
  80.     dvy = dVector*normalY;
  81.     //This calculates the new speeds for the circles
  82.     ballA.xspeed -= dvx;
  83.     ballA.yspeed -= dvy;
  84.     ballB.xspeed += dvx;
  85.     ballB.yspeed += dvy;
  86.     //assigns the new values
  87. }

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.

Improve the blog rating this post
Tell me what do you think about this post. I'll write better and better entries.
1 Star2 Stars3 Stars4 Stars5 Stars (4 votes, average: 5 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.

18 Responses to “Managing multiple balls collisions with Flash”

  1. Nerdsrule10 on May 27th, 2008 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 28th, 2008 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 28th, 2008 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 28th, 2008 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 28th, 2008 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 28th, 2008 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 28th, 2008 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 28th, 2008 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 28th, 2008 6:11 pm

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

  10. Sunil Changrani on May 28th, 2008 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 29th, 2008 9:07 am

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

    it should just work the same right?

  12. voidSkipper on May 29th, 2008 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 29th, 2008 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 29th, 2008 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 31st, 2008 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 4th, 2008 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. Malboro Jones on September 15th, 2008 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!

Leave a Reply




Trackbacks

  1. Managing multiple balls collisions with Flash: AS3 version : Emanuele Feronato - italian geek and PROgrammer on June 7th, 2008 11:55 pm

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