• home
  • forum
  • my
  • kt
  • download
  • Pixel Perfect Circle Collisions

    Author: 2008-12-31 09:03:27 From:

    We are going to make a script that will make circles collide with each other. This would be very hard to do with hitTest()’s so we are going to use a small amount of trigonometry. Don’t let the big word or its meaning scare you. All we are going to need is 13 lines of code. Here is what it should look like:

    As always, open up flash and start a new flash file (CS3 users, make sure you select AS2. For AS3 code jump to the bottom of the tutorial). Select the oval tool and draw a circle whatever size you want on the stage. Make sure you hold the shift button when you draw the circle so it is perfectly round, otherwise this won’t work. Select the circle and hit F8 to convert it to a movieclip. Call it whatever you want. Make sure the registration point is in the center.

    Converting to a MC

    Drag another “circle” MC from the library and onto the stage. Give each MC an instance name of c0 and c1 (obviously make sure you don’t call them both c1). Now we are ready to get into the code.

    onEnterFrame = function () {
    	c0._x = _xmouse;
    	c0._y = _ymouse;
     
    	xdist = c1._x - c0._x;
    	ydist = c1._y - c0._y;
    	dist = Math.sqrt(xdist * xdist + ydist * ydist);
    	angle = Math.atan2(ydist, xdist);
     
    	if(dist < c0._width) {
    		c1._x = c0._x + (c0._width * Math.cos(angle));
    		c1._y = c0._y + (c0._width * Math.sin(angle));
    	}
    };

    Paste that code onto the frame.

    First of all, we put everything inside an onEnterFrame() funtion. This tells flash that we want this code to be run every frame.

    c0._x = _xmouse sets the circle with the instance name c0’s x coordinate to whatever the mouses is that frame. The same goes for the next line, except with the y coordinates. This makes our MC follow the mouse around.

    The next 3 lines all have to do with the Pythagorean theorem, or pythag. Pythag is used to get the length of the hypotenuse of a right angled triangle. What are we using it for then? This diagram should be able to explain it better than me:

    So basically pythag tells us that if you square xdist and ydist, add them together and then get the square root of that you will have the distance of the red line above, which is handy to us because it tells us how far apart the circles are. Since circles are perfectly round, if they are closer than the half of the width of each circle (or the width of one circle if they are the same size) then they are touching.

    Back to the code. We get xdist, then ydist, then do pythag and alakazam. We have the distance between the circles. The next line tells us the angle of the angles in the triangle. You don’t need to understand how this works, it just does :P. We will use this a bit later.

    if(dist < c0._width) { checks if the circles are colliding like I explained above. If the are it runs the following code.

    c1._x = c0._x + (c0._width * Math.cos(angle));
    c1._y = c0._y + (c0._width * Math.sin(angle));

    The trig.

    This relates back to a right angled triangle. Cosine (cos) and Sine (sin) are both trig functions that tell us a certain side of the right angled triangle if we give it the angle. The answer it gives us is on a triangle with a hypotenuse with the length of 1.

    STOP! Diagram time.

    As you (probably) can(’t) see from this (crappy) diagram c0._width * Math.cos(angle) returns the x distance the circle needs to move until they aren’t colliding. Same goes for the c0._width * Math.sin(angle) and the y distance. We simply make c1 move those distances from c0 and they shouldn’t be colliding anymore.

    If you haven’t already gotten bored from me taking over 9000 lines to explain 13 lines of code, press Ctrl+Enter to test out this nifty little script.

    AS3 code thanks to Corey:

    addEventListener(Event.ENTER_FRAME, circleCollision);
     
    function circleCollision(event:Event):void {
    c0.x = mouseX;
    c0.y = mouseY;
     
    var xdist:Number = c1.x - c0.x;
    var ydist:Number = c1.y - c0.y;
    var dist:Number = Math.sqrt(xdist * xdist + ydist * ydist);
    var angle:Number = Math.atan2(ydist, xdist);
     
    if (dist < c0.width) {
    c1.x = c0.x + (c0.width * Math.cos(angle));
    c1.y = c0.y + (c0.width * Math.sin(angle));
    }

    discuss this topic to forum

    relation tutorial

    No information

    Category

      3D (29)
      Math Physics (17)
      3rd Party (7)
      Navigation (63)
      Actionscripting (158)
      Optimization (17)
      Animation (108)
      Projector (11)
      Audio (52)
      Special Effects (152)
      Backend (26)
      Text Effects (82)
      Drawing (32)
      Tips and Techniques (47)
      Dynamic Content (31)
      Tricks (8)
      Games (97)
      Utilities (21)
      Getting Started (91)
      Video (24)
      Interactivity (43)
      Web Design (29)

    New

    Hot