public void ResolveCollision(Discoid discoid, RectangleCollision collision) { double absorption = 0.9f; switch (collision) { case RectangleCollision.Right: case RectangleCollision.Left: //double dX = 0; //if (collision == RectangleCollision.Left) //{ // dX = (discoid.X + discoid.Radius) - this.position.X; //} //else //{ // dX = (this.position.X + this.size.X ) - (discoid.X + discoid.Radius); //} //discoid.Position.X = this.position.X - dX; if (Math.Sign(discoid.TranslateVelocity.X) == Math.Sign(discoid.VSpinVelocity.X) && discoid.VSpinVelocity.X > 0.0) { discoid.TranslateVelocity = discoid.TranslateVelocity.Add(new Vector2D(discoid.VSpinVelocity.X, 0)); discoid.VSpinVelocity = discoid.VSpinVelocity.Add(new Vector2D(0, discoid.VSpinVelocity.Y)); } discoid.TranslateVelocity.X = discoid.TranslateVelocity.X * (-1.0f * absorption); break; case RectangleCollision.Bottom: case RectangleCollision.Top: //double dY = 0; //if (collision == RectangleCollision.Top) //{ // dY = (discoid.Y + discoid.Radius) - this.position.Y; //} //else //{ // dY = this.position.Y - (discoid.Y + discoid.Radius); //} //discoid.Position.Y = this.position.Y - dY; if (Math.Sign(discoid.TranslateVelocity.Y) == Math.Sign(discoid.VSpinVelocity.Y) && discoid.VSpinVelocity.Y > 0.0) { discoid.TranslateVelocity = discoid.TranslateVelocity.Add(new Vector2D(0, discoid.VSpinVelocity.Y)); discoid.VSpinVelocity = discoid.VSpinVelocity.Add(new Vector2D(discoid.VSpinVelocity.X, 0)); } discoid.TranslateVelocity.Y = discoid.TranslateVelocity.Y * (-1.0f * absorption); break; } }
public bool Colliding(Discoid otherDiscoid) { //if (!otherDiscoid.IsBallInGoal && !IsBallInGoal) //{ float xd = (float)(position.X - otherDiscoid.Position.X); float yd = (float)(position.Y - otherDiscoid.Position.Y); //float sumRadius = (float)((this.Radius + 1.0) + (otherDiscoid.Radius + 1.0)); float sumRadius = (float)((this.Radius + 1.0) + (otherDiscoid.Radius + 1.0)); float sqrRadius = sumRadius * sumRadius; float distSqr = (xd * xd) + (yd * yd); if (Math.Round(distSqr) < Math.Round(sqrRadius)) { return(true); } //} return(false); }
public RectangleCollision Colliding(Discoid discoid) { RectangleCollision collision = RectangleCollision.None; double mediumX = (discoid.LastX + discoid.Position.X) / 2.0; double mediumY = (discoid.LastY + discoid.Position.Y) / 2.0; //if (!discoid.IsBallInGoal) //{ //bool insideWidth = (discoid.X > position.X) && (discoid.X < position.X + size.X); //bool insideHeight = (discoid.Y > position.Y) && (discoid.Y < position.Y + size.Y); bool insideWidth = ((discoid.Position.X > position.X) && (discoid.Position.X < position.X + size.X)); bool insideHeight = (discoid.Position.Y > position.Y) && (discoid.Position.Y < position.Y + size.Y); //if ((discoid.X < position.X) && (discoid.X + discoid.Radius > position.X) && (discoid.X - discoid.Radius < position.X + size.X) && insideHeight && (discoid.TranslateVelocity.X + discoid.VSpinVelocity.X > 0)) if ((discoid.LastX < position.X) && (discoid.Position.X + discoid.Radius > position.X) && (discoid.Position.X - discoid.Radius < position.X + size.X) && insideHeight && (discoid.TranslateVelocity.X + discoid.VSpinVelocity.X > 0)) { collision = RectangleCollision.Left; } //else if ((discoid.X > (position.X + size.X)) && (discoid.X - discoid.Radius < position.X + size.X) && (discoid.X + discoid.Radius > position.X) && insideHeight && (discoid.TranslateVelocity.X + discoid.VSpinVelocity.X < 0)) else if ((discoid.LastX + discoid.Radius > position.X + size.X) && (discoid.Position.X - discoid.Radius < position.X + size.X) && (discoid.Position.X + discoid.Radius > position.X) && insideHeight && (discoid.TranslateVelocity.X + discoid.VSpinVelocity.X < 0)) { collision = RectangleCollision.Right; } //if ((discoid.Y < position.Y) && (discoid.Y + discoid.Radius > position.Y) && (discoid.Y - discoid.Radius < position.Y + size.Y) && insideWidth && (discoid.TranslateVelocity.Y + discoid.VSpinVelocity.Y > 0)) if ((discoid.LastY < position.Y) && (discoid.Position.Y + discoid.Radius > position.Y) && (discoid.Position.Y - discoid.Radius < position.Y + size.Y) && insideWidth && (discoid.TranslateVelocity.Y + discoid.VSpinVelocity.Y > 0)) { collision = RectangleCollision.Top; } else if ((discoid.Position.Y + discoid.Radius > position.Y + size.Y) && (discoid.Position.Y - discoid.Radius < position.Y + size.Y) && (discoid.Position.Y + discoid.Radius > position.Y) && insideWidth && (discoid.TranslateVelocity.Y + discoid.VSpinVelocity.Y < 0)) //else if ((discoid.LastY > (position.Y + size.Y)) && (discoid.Y - discoid.Radius < position.Y + size.Y) && (discoid.Y + discoid.Radius > position.Y) && insideWidth && (discoid.TranslateVelocity.Y + discoid.VSpinVelocity.Y < 0)) { collision = RectangleCollision.Bottom; } //} return(collision); }
public void ResolveCollision(Discoid otherDiscoid) { // get the mtd Vector2D delta = (position.Subtract(otherDiscoid.position)); float d = delta.Length(); // minimum translation distance to push balls apart after intersecting Vector2D mtd = delta.Multiply((float)(((this.Radius + 1.0 + otherDiscoid.Radius + 1.0) - d) / d)); // resolve intersection -- // inverse mass quantities double im1 = 1f / this.Mass; double im2 = 1f / otherDiscoid.Mass; // push-pull them apart based off their mass if (!this.IsFixed) { position = position.Add((mtd.Multiply(im1 / (im1 + im2)))); } if (!otherDiscoid.IsFixed) { otherDiscoid.position = otherDiscoid.position.Subtract(mtd.Multiply(im2 / (im1 + im2))); } // impact speed Vector2D v = (this.translateVelocity.Subtract(otherDiscoid.translateVelocity)); Vector2D mtdNormalize = new Vector2D(mtd.X, mtd.Y); mtdNormalize.Normalize(); float vn = v.Dot(mtd.Normalize()); // sphere intersecting but moving away from each other already if (vn > 0.0f) { return; } // collision impulse float i = Math.Abs((float)((-(1.0f + 0.1) * vn) / (im1 + im2))); Vector2D impulse = mtd.Multiply(0.5); //Vector2D impulse = mtd.Multiply(1.0); //double i = (float)((-(0.1f + 0.1) * vn)) / (im1 + im2); //Vector2D impulse = mtd.Multiply(i); int hitSoundIntensity = (int)(Math.Abs(impulse.X) + Math.Abs(impulse.Y)); if (hitSoundIntensity > 5) { hitSoundIntensity = 5; } if (hitSoundIntensity < 1) { hitSoundIntensity = 1; } //GameSound sound = GameSound.None; //switch (hitSoundIntensity) //{ // case 1: // sound = GameSound.Hit01; // break; // case 2: // sound = GameSound.Hit02; // break; // case 3: // sound = GameSound.Hit03; // break; // case 4: // sound = GameSound.Hit04; // break; // case 5: // sound = GameSound.Hit05; // break; // case 6: // sound = GameSound.Hit06; // break; //} //observer.Hit(sound); // change in momentum if (!isFixed) { this.translateVelocity = this.translateVelocity.Add(impulse.Multiply(im1)); } if (!otherDiscoid.IsFixed) { otherDiscoid.translateVelocity = otherDiscoid.translateVelocity.Subtract(impulse.Multiply(im2)); } }