Collision Detection Question

Hello,

I have my poolgame in development but I still have trouble.

The balls sometimes just jump out of the area…

Im not an physics expert, but my collision detection must be perfect.

Can

Here is my code (I made the code from different sources):



function frameEntered(e:Event):void {
			
			var i:int = 0;
			var len:int = 4;
			
			for (i = 0; i < len; i++) {
			
				var ball1 = _balls*;
				
				//
				var j:int = 0;
				var len2:int = 4;
				
				for (j = 0; j < len2; j++) {
					
					if (ball1 == _balls[j]) continue;
					
					var ball2 = _balls[j];
					
					//
					ballToBallDetection(ball1, ball2);
					
				}
				
				var hit:Boolean = false;
					
					hit = checkUpperWall(ball1);
					if (hit) return;
					
					hit = checkRightWall(ball1);
					if (hit) return;
						
					hit = checkLowerWall(ball1);
					if (hit) return;
						
					hit = checkLeftWall(ball1);
					if (hit) return;
					
					//
					if (_clickAngle > 45 && _clickAngle < 135) {
						
						hit = false;
						
						hit = checkLowerWall(ball1);
						if (hit) return;
						
						hit = checkRightWall(ball1);
						if (hit) return;
						
						hit = checkLeftWall(ball1);
						if (hit) return;
						
						hit = checkUpperWall(ball1);
						if (hit) return;
						
					}
					
					if (_clickAngle > 135 && _clickAngle < 225) {
						
						hit = false;
						
						hit = checkLeftWall(ball1);
						if (hit) return;
						
						hit = checkUpperWall(ball1);
						if (hit) return;
						
						hit = checkLowerWall(ball1);
						if (hit) return;
						
						hit = checkRightWall(ball1);
						if (hit) return;
					
					}
					
					if (_clickAngle > 225 && _clickAngle < 315) {
						
						hit = false;
						
						hit = checkUpperWall(ball1);
						if (hit) return;
						
						hit = checkRightWall(ball1);
						if (hit) return;
						
						hit = checkLeftWall(ball1);
						if (hit) return;
						
						hit = checkLowerWall(ball1);
						if (hit) return;
						
					}
					
					if ((_clickAngle > 315 && _clickAngle < 360) || (_clickAngle > 0 && _clickAngle < 45)) {
						
						hit = false;
						
						hit = checkRightWall(ball1);
						if (hit) return;
						
						hit = checkLowerWall(ball1);
						if (hit) return;
						
						hit = checkUpperWall(ball1);
						if (hit) return;
						
						hit = checkLeftWall(ball1);
						if (hit) return;
						
					}
					
					_clickAngle = null;
					
					
					
					moveMC(ball1);
				
				
			}
			
		}
		
		protected function checkUpperWall(ball:*):Boolean {
			
			var ballX:Number = ball.x;
			var ballY:Number = ball.y;
			
			var radius:Number = _radius;
			
			var distance:Number = _upperWallY - (ballY - radius);
 

			var t:Number = distance / ball.speedY; 
			 
			
			if ((t > 0) && (t < 1)) {
				
			   
			   ball.x += (ball.speedX * t); 
			   ball.y += (ball.speedY * t); 
			   
			   
			   ball.speedY *= -1; 
			   
			   return true;
			   
			}
			
			return false;
			
		}
		
		protected function checkRightWall(ball:*):Boolean{
			
			var ballX:Number = ball.x;
			var ballY:Number = ball.y;
			
			var radius:Number = _radius;
			
			var distance:Number = _rightWallX - (ballX + radius);
 
			
			var t:Number = distance / ball.speedX; 
			 
			
			if ((t > 0) && (t < 1)) {
				
			   
			   ball.x += (ball.speedX * t); 
			   ball.y += (ball.speedY * t);
			   
			  
			  ball.speedX *= -1; 
			   
			   return true;
			   
			}
			
			return false;
			
		}
		
		protected function checkLeftWall(ball:*):Boolean {
			
			var ballX:Number = ball.x;
			var ballY:Number = ball.y;
			
			var radius:Number = _radius;
			
			var distance:Number = _leftWallX - (ballX - radius);
 
			
			var t:Number = distance / ball.speedX; 
			 
			
			if ((t > 0) && (t < 1)) {
				
			   
			   ball.x += (ball.speedX * t); 
			   ball.y += (ball.speedY * t); 
			   
			   
			   ball.speedX *= -1; 
			   
			   return true;
			   
			}
			
			return false;
			
		}
		
		protected function checkLowerWall(ball:*):Boolean {
			
			var ballX:Number = ball.x;
			var ballY:Number = ball.y;
			
			var radius:Number = _radius;
			
			var distance:Number = _lowerWallY - (ballY + radius);
 
			
			var t:Number = distance / ball.speedY; 
			
			
			if ((t > 0) && (t < 1)) {
				
			  
			   ball.x += (ball.speedX * t); 
			   ball.y += (ball.speedY * t); 
			   
			   
			  ball.speedY *= -1; 
			   
			  return true;
			   
			}
			
			return false;
			
		}

		protected function mouseIsDown(e:MouseEvent) :void {
			
			var point:Point = new Point();
			point.x = this.mouseX;
			point.y = this.mouseY;
			
			var distX:Number = (point.x - _whiteBall_mc.x);
			var distY:Number = (point.y - _whiteBall_mc.y);
			var dist:Number = Math.sqrt(distX * distX + distY * distY);
			
			_whiteBall_mc.speedX = (distX * speed) / dist;
			_whiteBall_mc.speedY = (distY * speed) / dist;
			
			var angle = Math.atan2(this.mouseY - _whiteBall_mc.y, this.mouseX - _whiteBall_mc.x);
			var deg:Number = angle / (Math.PI / 180);
			
			//_whiteBall_mc.rotation = deg;
		
			//calculate click angle
			angle = Math.atan2(this.mouseY - (this.height / 2), this.mouseX - (this.width / 2));
			deg = angle / (Math.PI / 180);
			deg = ((deg %= 360) < 0) ? deg + 360 : deg;
			_clickAngle = deg;
			
			//
			this.addEventListener(Event.ENTER_FRAME, frameEntered);
			
		}
		
		function ballToBallDetection(b1, b2) {

			  //set the speed variables
			  var xmov1 = b1.speedX;
			  var ymov1 = b1.speedY;
			  var xmov2 = b2.speedX;
			  var ymov2 = b2.speedY;
			  //set the position variables
			  var xl1 = b1.x;
			  var yl1 = b1.y;
			 var xl2 = b2.x;
			 var yl2 = b2.y;
			 //define the constants
			 var R = b1.radius+b2.radius;
			 var a = -2*xmov1*xmov2+xmov1*xmov1+xmov2*xmov2;
			 var b = -2*xl1*xmov2-2*xl2*xmov1+2*xl1*xmov1+2*xl2*xmov2;
			 var c = -2*xl1*xl2+xl1*xl1+xl2*xl2;
			 var d = -2*ymov1*ymov2+ymov1*ymov1+ymov2*ymov2;
			 var e = -2*yl1*ymov2-2*yl2*ymov1+2*yl1*ymov1+2*yl2*ymov2;
			 var f = -2*yl1*yl2+yl1*yl1+yl2*yl2;
			 var g = a+d;
			 var h = b+e;
			 var k = c+f-R*R;
			 //solve the quadratic equation
			 var sqRoot = Math.sqrt(h*h-4*g*k);
			 var t1 = (-h+sqRoot)/(2*g);
			 var t2 = (-h-sqRoot)/(2*g);
			 if (t1>0 && t1<=1) {
				var whatTime = t1;
				var ballsCollided = true;
			 }
			 if (t2>0 && t2<=1) {
				if (whatTime == null || t2<t1) {
				   whatTime = t2;
				   ballsCollided = true;
				}
			 }
			 if (ballsCollided) {
				//Collision has happened, so throw a trace
				//trace("Ouch!");
				
				//b1.x += (b1.speedX * t2); 
				//b1.y += (b1.speedY * t2); 
				
				ball2BallReaction(b1, b2, b1.x, b2.x, b1.y, b2.y, whatTime) ;
				
			 }

		}
		
		function ball2BallReaction(b1, b2, x1, x2, y1, y2, time) {

			 var mass1 = b1.mass;
			 var mass2 = b2.mass;
			 
			 // -----set initial velocity variables
			 var xVel1 = b1.speedX;
			 var xVel2 = b2.speedX;
			 var yVel1 = b1.speedY;
			 var yVel2 = b2.speedY;
			 var run = (x1-x2);
			 var rise = (y1-y2);
			 var Theta = Math.atan2(rise, run);
			 var cosTheta = Math.cos(Theta);
			 var sinTheta = Math.sin(Theta);
			 //Find the velocities along the line of action
			 var xVel1prime = xVel1*cosTheta+yVel1*sinTheta;
			 var xVel2prime = xVel2 * cosTheta + yVel2 * sinTheta;
			 
			 //Find the velocities perpendicular to the line of action
			 var yVel1prime = yVel1*cosTheta-xVel1*sinTheta;
			 var yVel2prime = yVel2 * cosTheta - xVel2 * sinTheta;
			 
			 // Conservation Equations
			 var P = (mass1*xVel1prime+mass2*xVel2prime);
			 var V = (xVel1prime-xVel2prime);
			 var v2f = (P+mass1*V)/(mass1+mass2);
			 var v1f = v2f-xVel1prime+xVel2prime;
			 xVel1prime = v1f;
			 xVel2prime = v2f;
			 
			 //Project back to Flash's x and y axes
			 xVel1 = xVel1prime*cosTheta-yVel1prime*sinTheta;
			 xVel2 = xVel2prime*cosTheta-yVel2prime*sinTheta;
			 yVel1 = yVel1prime*cosTheta+xVel1prime*sinTheta;
			 yVel2 = yVel2prime * cosTheta + xVel2prime * sinTheta;
			 
			 //change old pos
			 b1.tempX = b1.x + b1.speedX*time;
			 b1.tempY = b1.y + b1.speedY*time;
			 b2.tempX = b2.x + b2.speedX*time;
			 b2.tempY = b2.y + b2.speedY * time;
			 
			 b1.speedX = xVel1;
			 b2.speedX = xVel2;
			 b1.speedY = yVel1;
			 b2.speedY = yVel2;
			 
		}

		protected function moveMC(ball:*) :void {
		
			ball.x += ball.speedX;
			ball.y += ball.speedY;
			
			ballFriction(ball);
			
		}
		
		protected function ballFriction(ball:*) {
			
			ball.speedX *= friction;
			ball.speedY *= friction;
		
		}