public bool CollidesWith(CollisionBody other) { if (this.Shape == ShapeType.Circle && other.Shape == ShapeType.Circle) { CircleBody a = (CircleBody)this; CircleBody b = (CircleBody)other; return(Vector2.Distance(this.Position, other.Position) <= a.Radius + b.Radius); } else if (this.Shape == ShapeType.Circle && other.Shape == ShapeType.Rectangle) { return(RectCircCollision((CircleBody)this, (RectangleBody)other)); } else if (this.Shape == ShapeType.Rectangle && other.Shape == ShapeType.Circle) { return(RectCircCollision((CircleBody)other, (RectangleBody)this)); } else if (this.Shape == ShapeType.Rectangle && other.Shape == ShapeType.Rectangle) { RectangleBody a = (RectangleBody)this; RectangleBody b = (RectangleBody)other; return((a.Position.X <= b.Position.X + b.Size.X || a.Position.X + a.Size.X >= b.Position.X) && (a.Position.Y <= b.Position.Y + b.Size.Y || a.Position.Y + a.Size.Y >= b.Position.Y)); } else { throw new NotImplementedException("Attempted collision with a shape that doesn't exist"); } }
private bool RectCircCollision(CircleBody a, RectangleBody b) { float nearestX = Clamp(a.Position.X, b.Position.X, b.Position.X + b.Size.X); float nearestY = Clamp(a.Position.Y, b.Position.Y, b.Position.Y + b.Size.Y); Vector2 nearestPoint = new Vector2(nearestX, nearestY); return(Vector2.Distance(nearestPoint, a.Position) <= a.Radius); }
public Dictionary <uint, CollisionBody> GetPotentialCollisions(CollisionBody toCheck) { int xMin = 0; int xMax = 0; int yMin = 0; int yMax = 0; if (toCheck.Shape == CollisionBody.ShapeType.Circle) { CircleBody body = (CircleBody)toCheck; xMin = ((int)(Math.Max(body.Position.X - body.Radius / 2, 0)) / tileSize); xMax = (int)(Math.Min(body.Position.X + body.Radius / 2, maxWidth - 1)) / tileSize; yMin = ((int)(Math.Max(body.Position.Y - body.Radius / 2, 0)) / tileSize); yMax = (int)(Math.Min(body.Position.Y + body.Radius / 2, maxHeight - 1)) / tileSize; } else if (toCheck.Shape == CollisionBody.ShapeType.Rectangle) { RectangleBody body = (RectangleBody)toCheck; xMin = ((int)(Math.Max(body.Position.X, 0)) / tileSize); xMax = (int)(Math.Min(body.Position.X + body.Size.X, 49)) / tileSize; yMin = ((int)(Math.Max(body.Position.Y, 0)) / tileSize); yMax = (int)(Math.Min(body.Position.Y + body.Size.Y, 49)) / tileSize; } // Get every possible CollisionBody Dictionary <uint, CollisionBody> potentials = new Dictionary <uint, CollisionBody>(); for (int y = yMin; y <= yMax; y++) { for (int x = xMin; x <= xMax; x++) { foreach (CollisionBody c in Tiles[y * columns + x].Data.Values) { if (!potentials.ContainsKey(c.id)) { potentials.Add(c.id, c); } } } } return(potentials); }
private void BounceOffBottom(Object other) { if (this.Collision.Shape == CollisionBody.ShapeType.Circle) { CircleBody c = (CircleBody)this.Collision; RectangleBody r = (RectangleBody)other.Collision; float dist = (r.Position.Y + r.Size.Y) - (c.Position.Y - c.Radius); this.Collision.Position.Y += dist * 2; this.Velocity.Y *= -1; } else { RectangleBody r1 = (RectangleBody)this.Collision; RectangleBody r2 = (RectangleBody)other.Collision; float dist = (r2.Position.Y + r2.Size.Y) - (r1.Position.Y); this.Collision.Position.Y += dist * 2; this.Velocity.Y *= -1; } }
private void BounceOffLeft(Object other) { if (this.Collision.Shape == CollisionBody.ShapeType.Circle) { CircleBody c = (CircleBody)this.Collision; RectangleBody r = (RectangleBody)other.Collision; float dist = (c.Position.X + c.Radius) - (r.Position.X); this.Collision.Position.X -= dist * 2; this.Velocity.X *= -1; } else { RectangleBody r1 = (RectangleBody)this.Collision; RectangleBody r2 = (RectangleBody)other.Collision; float dist = (r1.Position.X + r1.Size.X) - (r2.Position.X); this.Collision.Position.X -= dist * 2; this.Velocity.X *= -1; } }
private List <GridTile> GetCoveredTiles(CollisionBody toAdd) { int xMin = 0; int xMax = 0; int yMin = 0; int yMax = 0; if (toAdd.Shape == CollisionBody.ShapeType.Circle) { CircleBody body = (CircleBody)toAdd; xMin = ((int)(Math.Max(body.Position.X - body.Radius / 2, 0)) / tileSize); xMax = (int)(Math.Min(body.Position.X + body.Radius / 2, maxWidth - 1)) / tileSize; yMin = ((int)(Math.Max(body.Position.Y - body.Radius / 2, 0)) / tileSize); yMax = (int)(Math.Min(body.Position.Y + body.Radius / 2, maxHeight - 1)) / tileSize; } else if (toAdd.Shape == CollisionBody.ShapeType.Rectangle) { RectangleBody body = (RectangleBody)toAdd; xMin = ((int)(Math.Max(body.Position.X, 0)) / tileSize); xMax = (int)(Math.Min(body.Position.X + body.Size.X, maxWidth - 1)) / tileSize; yMin = ((int)(Math.Max(body.Position.Y, 0)) / tileSize); yMax = (int)(Math.Min(body.Position.Y + body.Size.Y, maxWidth - 1)) / tileSize; } List <GridTile> toReturn = new List <GridTile>(); for (int y = yMin; y <= yMax; y++) { for (int x = xMin; x <= xMax; x++) { toReturn.Add(Tiles[y * columns + x]); } } return(toReturn); }
/// <summary> /// Allows the game to perform any initialization it needs to before starting to run. /// This is where it can query for any required services and load any non-graphic /// related content. Calling base.Initialize will enumerate through any components /// and initialize them as well. /// </summary> protected override void Initialize() { SpriteMapper mapper = new SpriteMapper(); spriteSheet = mapper.ReadFile(SHEET_CONFIG_FILE_NAME, Content); graphics.PreferredBackBufferWidth = viewportWidth; graphics.PreferredBackBufferHeight = viewportHeight; graphics.ApplyChanges(); for (int i = 1; i <= hitSoundCount; i++) { hitSounds.Add(Content.Load <SoundEffect>("hit" + i)); } for (int i = 1; i <= deathSoundCount; i++) { deathSounds.Add(Content.Load <SoundEffect>("death" + i)); } grid = new Grid(new Point(0, 0), gameWidth, gameHeight, GridTileSize); Vector2 paddleSize = new Vector2(paddleSizeX, paddleSizeY); Vector2 paddlePos = new Vector2((gameWidth / 2) - (paddleSize.X / 2), gameHeight - paddleSize.Y - paddlePaddingY); RectangleBody collision = new RectangleBody(paddlePos, paddleSize); paddle = new Paddle(this, collision); Brick.MaxHealth = brickHealth; for (int i = 0; i < bricksCountX; i++) { int x = bricksPaddingX + i * ((gameWidth - bricksPaddingX - brickSizeX) / bricksCountX); for (int j = 0; j < bricksCountY; j++) { int y = bricksPaddingTop + j * ((gameHeight - bricksPaddingBottom - brickSizeY) / bricksCountY); RectangleBody brick = new RectangleBody(new Vector2(x, y), new Vector2(brickSizeX, brickSizeY)); PowerUpType powerUpType = Powerup.GetRandomType((float)rand.NextDouble()); Brick newBrick = new Brick(this, brick, brickHealth, rand.Next(0, 8), rand.Next(0, 8), powerUpType); bricks.Add(newBrick); grid.Add(newBrick.Collision); } } RectangleBody leftcollision = new RectangleBody(new Vector2(gameWidth * -1, gameHeight * -1), new Vector2(gameWidth, gameHeight * 3)); Object leftwall = new Object(this, leftcollision); walls.Add(leftwall); RectangleBody rightcollision = new RectangleBody(new Vector2(gameWidth, gameHeight * -1), new Vector2(gameWidth, gameHeight * 3)); Object rightwall = new Object(this, rightcollision); walls.Add(rightwall); RectangleBody topcollision = new RectangleBody(new Vector2(gameWidth * -1, gameHeight * -1), new Vector2(gameWidth * 3, gameHeight)); Object topwall = new Object(this, topcollision); walls.Add(topwall); RectangleBody bottomcollision = new RectangleBody(new Vector2(gameWidth * -1, gameHeight), new Vector2(gameWidth * 3, gameHeight)); bottom = new Object(this, bottomcollision); livesFont = Content.Load <SpriteFont>("LivesFont"); gameOverFont = Content.Load <SpriteFont>("GameOver"); parallax = new Parallax(gameWidth, gameHeight); base.Initialize(); }
public void BounceOff(Object other) { Vector2 velocityToCheck = this.Velocity - other.Velocity; if (this.Collision.Shape == CollisionBody.ShapeType.Circle && other.Collision.Shape == CollisionBody.ShapeType.Circle) { // Circle on Circle } else if (this.Collision.Shape == CollisionBody.ShapeType.Circle && other.Collision.Shape == CollisionBody.ShapeType.Rectangle) { CircleBody c = (CircleBody)this.Collision; RectangleBody r = (RectangleBody)other.Collision; if (velocityToCheck.X >= 0) { // Moving right if (velocityToCheck.Y >= 0) { // Moving right-down if (r.Position.X - c.Position.X <= r.Position.Y - c.Position.Y) { this.BounceOffTop(other); } else { this.BounceOffLeft(other); } } else { // Moving right-up if (-1 * (r.Position.X - c.Position.X) <= (r.Position.Y + r.Size.Y - c.Position.Y)) { this.BounceOffLeft(other); } else { this.BounceOffBottom(other); } } } else { // Moving left if (velocityToCheck.Y >= 0) { // Moving left-down if (r.Position.X + r.Size.X - c.Position.X <= -1 * (r.Position.Y - c.Position.Y)) { this.BounceOffRight(other); } else { this.BounceOffTop(other); } } else { // Moving left-up if (r.Position.X + r.Size.X - c.Position.X <= r.Position.Y + r.Size.Y - c.Position.Y) { this.BounceOffRight(other); } else { this.BounceOffBottom(other); } } } } }