A Flash Developer Resource Site

+ Reply to Thread
Results 1 to 3 of 3
  1. #1
    Unregistered User dnalogic's Avatar
    Join Date
    Feb 2001
    Location
    UK
    Posts
    146

    im bored. here's some 2D ball colliding source code. enjoy.

    ok.
    so its 3:30am and i have nothing to do.

    right, make a new flash document. (im using MX by the way).
    now in the first frame in the first layer, paste this code...
    Code:
    function math2DDistance(O,P){
    	// returns distance from point (O) to point (P)
    	return Math.sqrt( (P.x - O.x)*(P.x - O.x) + (P.y - O.y)*(P.y - O.y));
    }
    function math2DRotatePoint(O,P,Theta){
    	// rotates (by Theta) a point (P) about an origin (O)
    	var R = math2DDistance(O,P);
    	var A = Math.atan2(P.y - O.y, P.x - O.x);
    	Px = R * Math.cos(A + Theta);
    	Py = R * Math.sin(A + Theta);
    	return {x:Px, y:Py}
    }
    function math2DBallCollisionPlus(A,B){
    	if(math2DDistance(A,B) >= A.r +B.r){ // the balls arent touching
    		return false;
    	}
    	// get velocity in frame of line of action
    	var Theta = Math.atan2(B.y - A.y, B.x - A.x);
    	var kVA = math2DRotatePoint( {x:0,y:0}, {x:A.vx, y:A.vy}, -Theta);
    	var kVB = math2DRotatePoint( {x:0,y:0}, {x:B.vx, y:B.vy}, -Theta);
    	// move ball A so that it is not inside ball B
    	var Ax = B.x - (A.r + B.r) * Math.cos(Theta);
    	var Ay = B.y - (A.r + B.r) * Math.sin(Theta);
    	// swap momentums along the line of action (perfectly elastic, frictionless collision, with two equal masses)
    	var t = kVA.x;
    	kVA.x = kVB.x;
    	kVB.x = t;
    	// put velocity back into original frame axis
    	var VA = math2DRotatePoint( {x:0,y:0}, kVA, Theta);
    	var VB = math2DRotatePoint( {x:0,y:0}, kVB, Theta);
    	// return data (including new trajectories, and new position of ball A)
    	var o = { A:{x:Ax, y:Ay, vx:VA.x, vy:VA.y}, B:{vx:VB.x, vy:VB.y} }
    	return o;
    }
    //===================================================================================
    
    
    // create the balls
    balls = 6;
    for(var n=1;n<=balls;n++){
    	var o=_root.createEmptyMovieClip("ball"+n,n);
    	with(o){
    		r=Math.random()*50+10;
    		lineStyle(0,0x000000,100);
    		beginFill(0x0000CC);
    		moveTo(r,0);
    		for(c=0;c<=350;c+=10){
    			lineTo(r * Math.cos(Math.PI / 180 * c), r * Math.sin(Math.PI / 180 * c));
    		}
    		endFill();
    	}
    	o.vx = Math.random()*10-5;
    	o.vy = Math.random()*10-5;
    	o._x = Math.random()*550;
    	o._y = Math.random()*400;
    }
    
    
    
    // make some code that will run every frame (so the balls move)
    _root.onEnterFrame = function(){
    	for(var n=1;n<=balls;n++){
    		o=eval("ball"+n);
    		o.vy += 0.2; // gravity (erase this line for no gravity)
    		o._x += o.vx;
    		o._y += o.vy;
    		
    		// collisions with walls and ceilings (i have just assumed that the document is 550 pixels x 400 pixels)
    		if(o._x + o._width/2 >= 550){
    			o._x = 550 - o._width/2;
    			o.vx = -Math.abs(o.vx);
    		}
    		if(o._x - o._width/2 <= 0){
    			o._x = o._width/2;
    			o.vx = Math.abs(o.vx);
    		}
    		if(o._y + o._height/2 >= 400){
    			o._y = 400 - o._height/2;
    			o.vy = -Math.abs(o.vy);
    		}
    		if(o._y - o._height/2 <= 0){
    			o._y = o._height/2;
    			o.vy = Math.abs(o.vy);
    		}
    		
    		
    		for(var p=1;p<=balls;p++){if(p!=n){
    			q=eval("ball"+p);
    			
    			//=========== collision detect ===========
    			// pack variables for function
    			var A = { x:o._x, y:o._y, r:o._width/2, vx:o.vx, vy:o.vy }
    			var B = { x:q._x, y:q._y, r:q._width/2, vx:q.vx, vy:q.vy }
    			
    			// call function
    			var R = math2DBallCollisionPlus(A,B);
    
    			if(R){ // there is a collision
    				// unpack results
    				o._x = R.A.x;
    				o._y = R.A.y;
    				o.vx = R.A.vx;
    				o.vy = R.A.vy;
    				q.vx = R.B.vx;
    				q.vy = R.B.vy;
    			}
    			//========================================
    			
    		}}
    	}
    }
    stop();
    thats it.

    now run it.

    sorry i cant be bothered to make it into more of a tutorial, but making tutorials isnt fun, but writing code is.

    the key to this, and the bit that people will find most useful, is the 'math2DBallCollisionPlus' function. (You need to have the other two functions there aswell, but most people dont need those explained, right?)

    i tried to make the function as self contained as possible.
    the information it needs is the X & Y position, radius, and X & Y velocity of two circles.
    It needs this in the form of two objects, A, and B,
    where A contains variables x,y,r,vx,yv for ball A,
    and B contains variables x,y,r,vx,vy for ball B

    The information the function returns is the new velocities of each circle, and the new position of the first circle. (sometimes it is required to move one of the circles so that the arent 'inside' each other).
    It is returned in one object, which contains two objects A, and B,
    where A contains variables x,y,vx,vy for ball A,
    and B contains variables vx,vy for ball B.

    This maybe sounds complicated, but it is extremely easy to use.


    To have a decent 2d ball collision, you basically just need to have those functions, and then its all in the bit of code that looks like this...
    Code:
    			var A = { x:o._x, y:o._y, r:o._width/2, vx:o.vx, vy:o.vy }
    			var B = { x:q._x, y:q._y, r:q._width/2, vx:q.vx, vy:q.vy }
    			
    			// call function
    			var R = math2DBallCollisionPlus(A,B);
    
    			if(R){ // there is a collision
    				// unpack results
    				o._x = R.A.x;
    				o._y = R.A.y;
    				o.vx = R.A.vx;
    				o.vy = R.A.vy;
    				q.vx = R.B.vx;
    				q.vy = R.B.vy;
    			}
    o is one ball movie clip,
    q is the other ball movie clip.

    anyway.
    i hope someone finds it useful for a game.
    everyone seems to want to know that.

    dean.

  2. #2
    n00b LeechmasterB's Avatar
    Join Date
    May 2004
    Location
    Switzerland
    Posts
    1,067
    Well done .
    I do stuff that does stuff...

    J-Force

  3. #3
    do your smiles love u? slicer4ever's Avatar
    Join Date
    Dec 2005
    Location
    in a random occurance
    Posts
    475
    cool very cool

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts




Click Here to Expand Forum to Full Width


HTML5 Development Center