| |||||||
Du magst keine Werbung? Wir auch nicht!
Einfach registrieren und die Werbung ist weg. Diese Nachricht sehen nur nicht registrierte Nutzer.
![]() |
| | LinkBack | Themen-Optionen | Ansicht |
| | #1 (permalink) |
| Haaajmo Bosno!!! Registriert seit: Aug 2001 Ort: Bihać
Beiträge: 692
| Collision Detection Probleme
Hallo, bei meinen Pool Game Versuch geht bisher alles in Ordnung, aber manchmal gibt es Probleme. Manchmal fliegen die Bälle aus dem Rahmen und die Bälle verfangen sich machmal. Da ich kein Physics Experte bin, frage ich ob jemand Vorschläge hat, was da falsch sein soll, da mein Collision Detection Code perfekt sein muss. Hier also (den Code habe ich aus verschiedenen Quellen zusammengebaselt): Code:
function frameEntered(e:Event):void {
var i:int = 0;
var len:int = 4;
for (i = 0; i < len; i++) {
var ball1 = _balls[i];
//
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;
}
__________________ http://www.oreillynet.com/pub/au/3675 |
| | |
| | #2 (permalink) |
| Neuer User Registriert seit: Aug 2008
Beiträge: 205
|
Ich glaube den unerwünschten Effekt kann man nur durch wildes Klicken erzielen, oder? Ich würde den listener für den mouseclick einfach wieder removen, nach jedem Klick und erst wieder registrieren wenn alle Bälle still stehen (gemäß des Spiels). Ich denke, dass sich das Problem dadurch behebt, weil durch das Klicken neue speedX- und speedY - Eigenschaften beim whiteBall gesetzt werden, die dann zu entsprechenden Verwirrungen bei den Kollisionserkennungen führen. Kollision wird erkannt - speedX und speedY entsprechend neu berechnet, aber durch den Klick überschrieben. |
| | |
| | #3 (permalink) | |
| whatever Registriert seit: May 2008
Beiträge: 419
| Zitat:
![]() ansonsten ist das noch sehr weit von "perfekt" entfernt, besonders gut erkennt mans auch bei hohen ballgeschwindigkeiten, da treffen sich teilweise bälle die noch über 50 pixel voneinander entfernt sind usw. | |
| | |
![]() |
| Lesezeichen |
| Themen-Optionen | |
| Ansicht | |
| |
Ähnliche Themen | ||||
| Thema | Autor | Forum | Antworten | Letzter Beitrag |
| Collision Detection ohne Overlapping | mirzahat | ActionScript 3 | 15 | 21-05-2010 10:45 |
| AS2: Collision Detection mit Quadtree | Padde85 | Flash CS3 Professional | 3 | 26-04-2010 17:52 |
| massen collision detection | _kweso | ActionScript 3 | 7 | 26-03-2010 12:57 |
| Collision Detection | FLASHStyler | ActionScript 3 | 2 | 03-09-2008 22:13 |
| ** Collision Detection ** | powl | ActionScript 1 | 7 | 31-01-2003 11:33 |