Zurück   Flashforum > Flash > ActionScript > ActionScript 3

Antwort
 
LinkBack Themen-Optionen Ansicht
Alt 25-05-2010, 11:57   #1 (permalink)
Haaajmo Bosno!!!
 
Benutzerbild von mirzahat
 
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;
		
		}
mirzahat ist offline   Mit Zitat antworten
Alt 28-05-2010, 01:08   #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.
Flashesjetzt ist offline   Mit Zitat antworten
Alt 28-05-2010, 02:22   #3 (permalink)
ING
whatever
 
Registriert seit: May 2008
Beiträge: 419
Zitat:
Zitat von Flashesjetzt Beitrag anzeigen
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).
das könnt schon schwierig werden denn die bälle kommen niemals zu stehen, achte mal drauf

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.
ING ist offline   Mit Zitat antworten
Antwort

Lesezeichen

Themen-Optionen
Ansicht

Forumregeln
Es ist Ihnen nicht erlaubt, neue Themen zu verfassen.
Es ist Ihnen nicht erlaubt, auf Beiträge zu antworten.
Es ist Ihnen nicht erlaubt, Anhänge hochzuladen.
Es ist Ihnen nicht erlaubt, Ihre Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks sind an
Pingbacks sind an
Refbacks sind an


Ä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


Alle Zeitangaben in WEZ +1. Es ist jetzt 16:21 Uhr.

Domains, Webhosting & Vserver von Host Europe
Unterstützt das Flashforum!
Adobe User Group


Copyright ©1999 – 2012 Marc Thiele