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;
}