//------------------------------------------------------------------------------------------ // BallBallCollisionDetection() //------------------------------------------------------------------------------------------ private void BallBallCollisionDetection(ref GameObject current, ref Vec2 currentNormal) { for (int i = 0; i < myGame.GetNumberOfMovers(); i++) { Bullet mover = (Bullet)myGame.GetMover(i); if (mover != this) { Vec2 relativePosition = position - mover.position; Vec2 u = _oldPosition - mover.position; float a = velocity.Magnitude() * velocity.Magnitude(); float b = 2 * u.Dot(velocity); float c = u.Magnitude() * u.Magnitude() - (radius + mover.radius) * (radius + mover.radius); float delta = b * b - 4 * a * c; float t; t = (-b - Mathf.Sqrt(delta)) / (2 * a); if (c < 0) { if (b < 0) { t = 0; } else { continue; } } if (a != 0) { if (delta >= 0) { Vec2 pointOfImpact = _oldPosition + velocity * t; Vec2 normal = (pointOfImpact - mover.position).Normalized(); if (0 <= t && t < 1) { if (t < smallestToi) { smallestToi = t; current = mover; currentNormal = normal; } } } } } } }
// This method is just an example of how to get information about other blocks in the scene. void CheckBlockOverlaps() { MyGame myGame = (MyGame)game; for (int i = 0; i < myGame.GetNumberOfMovers(); i++) { Block other = myGame.GetMover(i); if (other != this) { // TODO: improve hit test, move to method: if (Mathf.Abs(other.position.x - _position.x) < 25 && Mathf.Abs(other.position.y - _position.y) < 25) { SetFadeColor(0.2f, 0.2f, 1); other.SetFadeColor(0.2f, 0.2f, 1); if (wordy) { Console.WriteLine("Block-block overlap detected."); } } } } }
private Block getEarliestCollision() { MyGame myGame = (MyGame)game; smallestTOI = 2f; Block currentBlock = null; for (int i = 0; i < myGame.GetNumberOfMovers(); i++) { Block other = myGame.GetMover(i); if (other != this) { // TODO: improve hit test, move to method: if (isOverlapping(other)) { float toi = claculateTOI(other); currentBlock = setSmallestTOI(currentBlock, other, toi); } } } return(currentBlock); }
CollisionInfo FindEarliestCollision() { GameObject current = null; Vec2 currentNormal = new Vec2(); smallestToi = 2f; MyGame myGame = (MyGame)game; // Check other movers: for (int i = 0; i < myGame.GetNumberOfMovers(); i++) { Ball mover = myGame.GetMover(i); if (mover != this) { Vec2 relativePosition = position - mover.position; //if (relativePosition.Magnitude() < radius + mover.radius) //{ // TODO: compute correct normal and time of impact, and // return *earliest* collision instead of *first detected collision*: Vec2 u = _oldPosition - mover.position; float a = velocity.Magnitude() * velocity.Magnitude(); float b = 2 * u.Dot(velocity); float c = u.Magnitude() * u.Magnitude() - (radius + mover.radius) * (radius + mover.radius); float delta = b * b - 4 * a * c; float t; t = (-b - Mathf.Sqrt(delta)) / (2 * a); if (c < 0) { if (b < 0) { t = 0; //Vec2 normal = (_oldPosition - mover.position).Normalized(); //return new CollisionInfo(normal, mover, t); } else { continue; } } if (a != 0) //{ // return null; //} //else { if (delta >= 0) //{ // return null; //} //else { Vec2 pointOfImpact = _oldPosition + velocity * t; Vec2 normal = (pointOfImpact - mover.position).Normalized(); if (0 <= t && t < 1) { if (t < smallestToi) { smallestToi = t; current = mover; currentNormal = normal; } } //else return null; } } //Vec2 normal = relativePosition.Normalized(); //float overlap = radius + mover.radius - relativePosition.Magnitude(); //return new CollisionInfo(normal, mover, overlap); //} } } for (int i = 0; i < myGame.GetNumberOfLines(); i++) { NLineSegment line = myGame.GetLine(i); Vec2 differenceVector = _oldPosition - line.start; float ballDistance = differenceVector.Dot((line.end - line.start).Normal()); //if (ballDistance < radius) //{ Vec2 normal = (line.end - line.start).Normal(); Vec2 dist = position + (-ballDistance + radius) * normal; float difference = (dist - position).Magnitude(); float b = -velocity.Dot(normal); //float a = b - difference; float a = ballDistance - radius; if (b > 0) //{ // return null; //} //else { float t = 3f; if (a >= 0) //{ // return null; //} //else { t = a / b; } else if (a >= -radius) { t = 0; } else { continue; } if (t <= 1f) { Vec2 POI = _oldPosition + t * velocity; float d = (POI - line.start).Dot((line.end - line.start).Normalized()); if (0 <= d && d <= (line.end - line.start).Magnitude()) { if (t < smallestToi) { smallestToi = t; current = line; currentNormal = normal; } } // else return null; } } //} } if (current != null) { return(new CollisionInfo(currentNormal, current, smallestToi)); } else { return(null); } // TODO: Check Line segments using myGame.GetLine(); // return null; }