public RectangleCollision Colliding(Ball ball) { RectangleCollision collision = RectangleCollision.None; if (!ball.IsBallInPocket) { if (x < 288 && (ball.X - Ball.Radius < x + width) && (ball.Y >= y && ball.Y <= y + height) && (ball.TranslateVelocity.X + ball.VSpinVelocity.X < 0.0d) && (ball.LastX > x + width)) { collision = RectangleCollision.Right; } else if (x > 288 && (ball.X + Ball.Radius > x) && (ball.Y >= y && ball.Y <= y + height) && (ball.TranslateVelocity.X + ball.VSpinVelocity.X > 0.0d) && (ball.LastX < x)) { collision = RectangleCollision.Left; } if (y < 161 && (ball.Y - Ball.Radius < y + height) && (ball.X >= x && ball.X - Ball.Radius <= x + width) && (ball.TranslateVelocity.Y + ball.VSpinVelocity.Y < 0.0d) && (ball.LastY > y) && (ball.LastX < x + width)) { collision = RectangleCollision.Bottom; } else if (y > 161 && (ball.Y + Ball.Radius > y) && (ball.X >= x && ball.X <= x + width) && (ball.TranslateVelocity.Y + ball.VSpinVelocity.Y > 0.0d) && (ball.LastY < y) && (ball.LastY < y) && (ball.LastX < x + width)) { collision = RectangleCollision.Top; } } return(collision); }
/// <summary> /// Allows the game to run logic such as updating the world, /// checking for collisions, gathering input, and playing audio. /// </summary> /// <param name="gameTime">Provides a snapshot of timing values.</param> protected override void Update(GameTime gameTime) { theGentleman.handleInput(gameTime); // input physics.Update(gameTime, characterSprites); // physics RectangleCollision.update(characterSprites, staticSprites); // collision if (theGentleman.spritePos.X < 0) // background slide { background.slide(BasicBackground.SLIDE_DIRECTION.SLIDE_RIGHT); theGentleman.spritePos = new Vector2(GraphicsDevice.Viewport.Width - theGentleman.spriteSize.X, theGentleman.spritePos.Y); } else if (theGentleman.spritePos.X + theGentleman.spriteSize.X > GraphicsDevice.Viewport.Width) { background.slide(BasicBackground.SLIDE_DIRECTION.SLIDE_LEFT); theGentleman.spritePos = new Vector2(0, theGentleman.spritePos.Y); } else if (theGentleman.spritePos.Y + theGentleman.spriteSize.Y > GraphicsDevice.Viewport.Height) { background.slide(BasicBackground.SLIDE_DIRECTION.SLIDE_UP); theGentleman.spritePos = new Vector2(theGentleman.spritePos.X, 0); } else if (theGentleman.spritePos.Y < 0) { background.slide(BasicBackground.SLIDE_DIRECTION.SLIDE_DOWN); theGentleman.spritePos = new Vector2(theGentleman.spritePos.X, GraphicsDevice.Viewport.Height - theGentleman.spriteSize.Y); } base.Update(gameTime); }
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 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(Ball ball, RectangleCollision collision) { double xSound = (float)(ball.Position.X - 300.0) / 300.0; observer.Hit(@"Sounds\Bank02.wav" + "|" + xSound.ToString()); float absorption = 0.9f; if (this.direction == ForcedDirection.None) { switch (collision) { case RectangleCollision.Right: case RectangleCollision.Left: if (Math.Sign(ball.TranslateVelocity.X) == Math.Sign(ball.VSpinVelocity.X) && ball.VSpinVelocity.X > 0.0) { ball.TranslateVelocity.X += ball.VSpinVelocity.X; ball.VSpinVelocity.X = (double)0.0; } ball.TranslateVelocity.X *= -1.0d * absorption; break; case RectangleCollision.Bottom: case RectangleCollision.Top: if (Math.Sign(ball.TranslateVelocity.Y) == Math.Sign(ball.VSpinVelocity.Y) && ball.VSpinVelocity.Y > 0.0) { ball.TranslateVelocity.Y += ball.VSpinVelocity.Y; ball.VSpinVelocity.Y = (double)0.0; } ball.TranslateVelocity.Y *= -1.0d * absorption; break; } } else { Vector2D position = new Vector2D(x + width / 2, y + height / 2); switch (this.direction) { case ForcedDirection.Up: ball.TranslateVelocity.Y *= -0.5d; ball.TranslateVelocity.X = ball.TranslateVelocity.Y * -0.5d; break; case ForcedDirection.Down: ball.TranslateVelocity.Y *= -0.5d; ball.TranslateVelocity.X = ball.TranslateVelocity.Y * -0.5d; break; } return; // get the mtd Vector2D delta = (position.Subtract(ball.Position)); float d = delta.Lenght(); // minimum translation distance to push balls apart after intersecting Vector2D mtd = delta.Multiply((float)(((this.width * 2) - d) / d)); // resolve intersection -- // inverse mass quantities float im1 = 0.5f; float im2 = 0.5f; // push-pull them apart based off their mass ball.Position = ball.Position.Subtract(mtd.Multiply(im2 / (im1 + im2))); // impact speed Vector2D v = ball.TranslateVelocity.Multiply(-1.0d); float vn = v.Dot(mtd.Normalize()); //float vn = 1; // 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(1); switch (this.direction) { case ForcedDirection.Up: ball.TranslateVelocity = ball.TranslateVelocity.Add(new Vector2D((double)0, (double)vn)); break; case ForcedDirection.Down: ball.TranslateVelocity = ball.TranslateVelocity.Subtract(new Vector2D((double)0, (double)vn)); break; case ForcedDirection.Left: ball.TranslateVelocity = ball.TranslateVelocity.Subtract(new Vector2D((double)vn, (double)0)); break; case ForcedDirection.Right: ball.TranslateVelocity = ball.TranslateVelocity.Add(new Vector2D((double)vn, (double)0)); break; } } }
private void MoveBalls() { foreach (Ball ball in balls) { if (Math.Abs(ball.X) < 5 && Math.Abs(ball.Y) < 5 && Math.Abs(ball.XVelocity) < 10 && Math.Abs(ball.YVelocity) < 10) { ball.X = ball.Y = 0; ball.XVelocity = ball.YVelocity = 0; } } bool conflicted = true; int totalPoints1 = 0; int totalPoints2 = 0; while (conflicted) { conflicted = false; //foreach (Ball ball in balls) //{ // //int xOffset = (int)(ball.X + Ball.Radius + ball.XVelocity) - pnlTable.Width; // int xOffset = (int)(ball.X + Ball.Radius) - pnlTable.Width; // if (xOffset > 0) // { // ball.X = ball.X - xOffset * 2; // ball.XVelocity *= -1 * absorption; // conflicted = true; // } // //xOffset = (int)(ball.X + ball.XVelocity); // xOffset = (int)(ball.X - Ball.Radius); // if (xOffset < 0) // { // ball.X = ball.X - xOffset * 2; // ball.XVelocity *= -1 * absorption; // conflicted = true; // } // //int yOffset = (int)(ball.Y + Ball.Radius * 2 + ball.YVelocity - pnlTable.Height); // int yOffset = (int)(ball.Y + Ball.Radius) - pnlTable.Height; // if (yOffset > 0) // { // ball.Y = ball.Y - yOffset * 2; // ball.YVelocity *= -1 * absorption; // conflicted = true; // } // //yOffset = (int)(ball.Y + Ball.Radius + ball.YVelocity); // yOffset = (int)(ball.Y - Ball.Radius); // if (yOffset < 0) // { // ball.Y = ball.Y - yOffset * 2; // ball.YVelocity *= -1 * absorption; // conflicted = true; // } //} //foreach (Ball ballA in balls) //{ bool someCollision = true; while (someCollision) { someCollision = false; foreach (Ball ballA in balls) { foreach (DiagonalBorder diagonalBorder in diagonalBorders) { if (diagonalBorder.Colliding(ballA)) { //listBox1.Items.Add(diagonalBorder.ToString()); //listBox1.SelectedIndex = listBox1.Items.Count - 1; //tableGraphics.DrawLine(new Pen(Brushes.White), diagonalBorder.X1, diagonalBorder.Y1, diagonalBorder.X2, diagonalBorder.Y2); diagonalBorder.ResolveCollision(ballA); } } RectangleCollision borderCollision = RectangleCollision.None; foreach (TableBorder tableBorder in tableBorders) { borderCollision = tableBorder.Colliding(ballA); if (borderCollision != RectangleCollision.None) { //listBox1.Items.Add(tableBorder.ToString()); //listBox1.SelectedIndex = listBox1.Items.Count - 1; someCollision = true; tableBorder.ResolveCollision(ballA, borderCollision); } } foreach (Ball ballB in balls) { if (ballA.Id.CompareTo(ballB.Id) != 0) { if (ballA.Colliding(ballB)) { ballA.PlaySound(); while (ballA.Colliding(ballB)) { someCollision = true; ballA.ResolveCollision(ballB); ballA.X += (int)ballA.Velocity.X; ballA.Y += (int)ballA.Velocity.Y; ballB.X += (int)ballB.Velocity.X; ballB.Y += (int)ballB.Velocity.Y; } } } } double absXVelocity = Math.Abs(ballA.XVelocity); double absYVelocity = Math.Abs(ballA.YVelocity); double signalXVelocity = ballA.XVelocity >= 0 ? 1 : -1; double signalYVelocity = ballA.YVelocity >= 0 ? 1 : -1; absXVelocity = absXVelocity * (1 - friction) - 0.01; absYVelocity = absYVelocity * (1 - friction) - 0.01; if (absXVelocity < 0) { absXVelocity = 0; } if (absYVelocity < 0) { absYVelocity = 0; } ballA.XVelocity = absXVelocity * signalXVelocity; ballA.YVelocity = absYVelocity * signalYVelocity; MoveBall((int)ballA.X, (int)ballA.Y, false); } } conflicted = false; } double totalVelocity = 0; foreach (Ball ball in balls) { ball.Position.X += ball.XVelocity; ball.Position.Y += ball.YVelocity; totalVelocity += ball.XVelocity; totalVelocity += ball.YVelocity; } if (poolState == PoolState.Moving && totalVelocity == 0) { foreach (Ball ball in balls) { MoveBall((int)ball.X, (int)ball.Y, true); } listBox1.Items.Add(snapShotCount.ToString()); snapShotCount = 0; poolState = PoolState.AwaitingShot; pnlTable.Cursor = Cursors.SizeAll; } foreach (Ball ball in balls) { if (ball.IsBallInHole) { //MoveBalls(); } foreach (Hole hole in holes) { if (hole.IsBallInHole(ball) && (ball.Velocity.X != 0 || ball.Velocity.Y != 0)) { //MoveBalls(); //MessageBox.Show(string.Format("Ball {0} in hole {1}", ball.Id, hole.Id)); } } } }
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; } }