void ActivatePowerUp(PowerUp pu) { powerupSFX.Play(); switch (pu.GetPUType()) { case "powerup_b": isPuBActive = true; break; case "powerup_c": isPuCActive = true; break; case "powerup_p": isPuPActive = true; break; default: break; } }
protected void CheckCollisions() { float radius = ball.Width / 2; if (ball.caught) { if (ball.tempBallPaddleRatio == new Vector2(0, 0)) { ball.SetRatio(paddle.position); } ball.position = paddle.position + ball.tempBallPaddleRatio; } // Check for paddle if (ballWithPaddle == 0 && (ball.position.X > (paddle.position.X - radius - paddle.Width / 2)) && (ball.position.X < (paddle.position.X + radius + paddle.Width / 2)) && (ball.position.Y < paddle.position.Y) && (ball.position.Y > (paddle.position.Y - radius - paddle.Height / 2)) && !ball.caught) { // Reflect based on which part of the paddle is hit // By default, set the normal to "up" Vector2 normal = -1.0f * Vector2.UnitY; // Distance from the leftmost to rightmost part of the paddle float dist = paddle.Width + radius * 2; // Where within this distance the ball is at float ballLocation = ball.position.X - (paddle.position.X - radius - paddle.Width / 2); // Percent between leftmost and rightmost part of paddle float pct = ballLocation / dist; if (pct < 0.33f) { normal = new Vector2(-0.196f, -0.981f); } else if (pct > 0.66f) { normal = new Vector2(0.196f, -0.981f); } ball.direction = Vector2.Reflect(ball.direction, normal); // No collisions between ball and paddle for 20 frames ballWithPaddle = 20; } else if (ballWithPaddle > 0) { ballWithPaddle--; } // if ball catch is active if (ballWithPaddle == 20 && ballCatch && !ball.caught) { ball.caught = true; ball.tempBallPaddleRatio = ball.position - paddle.position; } // Check for blocks // First, let's see if we collided with any block Block collidedBlock = null; foreach (Block b in blocks) { if ((ball.position.X > (b.position.X - b.Width / 2 - radius)) && (ball.position.X < (b.position.X + b.Width / 2 + radius)) && (ball.position.Y > (b.position.Y - b.Height / 2 - radius)) && (ball.position.Y < (b.position.Y + b.Height / 2 + radius))) { collidedBlock = b; ballBounceSFX.Play(); break; } } // Now figure out how to reflect the ball if (collidedBlock != null) { // Assume that if our Y is close to the top or bottom of the block, // we're colliding with the top or bottom if ((ball.position.Y < (collidedBlock.position.Y - collidedBlock.Height / 2)) || (ball.position.Y > (collidedBlock.position.Y + collidedBlock.Height / 2))) { ball.direction.Y = -1.0f * ball.direction.Y; } else // otherwise, we have to be colliding from the sides { ball.direction.X = -1.0f * ball.direction.X; } // Now remove this block from the list blocks.Remove(collidedBlock); if (random.NextDouble() % 1 < spawnChance) { SpawnPowerUp(collidedBlock.position); } } // Check walls if (Math.Abs(ball.position.X - 32) < radius) { ball.direction.X = -1.0f * ball.direction.X; } else if (Math.Abs(ball.position.X - 992) < radius) { ball.direction.X = -1.0f * ball.direction.X; } else if (Math.Abs(ball.position.Y - 32) < radius) { ball.direction.Y = -1.0f * ball.direction.Y; } else if (ball.position.Y > (768 + radius)) { LoseLife(); } //Destroying powerup when it hits the paddle if (destroyPowerUp) { for (int i = powerups.Count - 1; i >= 0; i--) { if (powerups[i].readyToDestroy) { PowerUp temppowerup = powerups[i]; powerups.Remove(temppowerup); } } destroyPowerUp = false; } }
protected void CheckCollisions(Ball ball) { if (ball.caught) { return; } float radius = ball.Width / 2; if (Math.Abs(ball.position.X - 32) < radius) { ball.direction.X = -1.0f * ball.direction.X; } else if (Math.Abs(ball.position.X - 992) < radius) { ball.direction.X = -1.0f * ball.direction.X; } else if (Math.Abs(ball.position.Y - 32) < radius) { ball.direction.Y = -1.0f * ball.direction.Y; } // Checking for the Paddle here if (ballWithPaddle == 0 && (ball.position.X > (paddle.position.X - radius - paddle.Width / 2)) && (ball.position.X < (paddle.position.X + radius + paddle.Width / 2)) && (ball.position.Y < paddle.position.Y) && (ball.position.Y > (paddle.position.Y - radius - paddle.Height / 2))) { // Reflect based on which part of the paddle is hit // By default, set the normal to "up" Vector2 normal = -1.0f * Vector2.UnitY; // Distance from the leftmost to rightmost part of the paddle float dist = paddle.Width + radius * 2; // Where within this distance the ball is at float ballLocation = ball.position.X - (paddle.position.X - radius - paddle.Width / 2); // Percent between leftmost and rightmost part of paddle float pct = ballLocation / dist; if (pct < 0.33f) { normal = new Vector2(-0.196f, -0.981f); } else if (pct > 0.66f) { normal = new Vector2(0.196f, -0.981f); } ball.direction = Vector2.Reflect(ball.direction, normal); float dotResult = Vector2.Dot(ball.direction, Vector2.UnitX); if (dotResult > 0.9f) { ball.direction = new Vector2(0.906f, -0.423f); } dotResult = Vector2.Dot(ball.direction, -Vector2.UnitX); if (dotResult > 0.9f) { ball.direction = new Vector2(-0.906f, -0.423f); } dotResult = Vector2.Dot(ball.direction, -Vector2.UnitY); if (dotResult > 0.9f) { // We need to figure out if we're clockwise or counter-clockwise Vector3 crossResult = Vector3.Cross(new Vector3(ball.direction, 0), -Vector3.UnitY); if (crossResult.Z < 0) { ball.direction = new Vector2(0.423f, -0.906f); } else { ball.direction = new Vector2(-0.423f, -0.906f); } } // 20 frame collision buffer ballWithPaddle = 20; ballBounceSFX.Play(); if (ballCatchActive) { ball.caught = true; if (pct < 0.5f) { ball.direction = new Vector2(-0.707f, -0.707f); } else { ball.direction = new Vector2(0.707f, -0.707f); } } } else if (ballWithPaddle > 0) { ballWithPaddle--; } // Check for blocks // First, let's see if we collided with any block Block collidedBlock = null; foreach (Block b in blocks) { if ((ball.position.X > (b.position.X - b.Width / 2 - radius)) && (ball.position.X < (b.position.X + b.Width / 2 + radius)) && (ball.position.Y > (b.position.Y - b.Height / 2 - radius)) && (ball.position.Y < (b.position.Y + b.Height / 2 + radius))) { ball.direction.Y = -1.0f * ball.direction.Y; collidedBlock = b; blocks.Remove(collidedBlock); break; } // Now figure out how to reflect the ball if (collidedBlock != null) { // Assume that if our Y is close to the top or bottom of the block, // we're colliding with the top or bottom if ((ball.position.Y < (collidedBlock.position.Y - collidedBlock.Height / 2)) || (ball.position.Y > (collidedBlock.position.Y + collidedBlock.Height / 2))) { ball.direction.Y = -1.0f * ball.direction.Y; } else // otherwise, we have to be colliding from the sides { ball.direction.X = -1.0f * ball.direction.X; } bool shouldRemove = collidedBlock.OnHit(); if (shouldRemove) { blocks.Remove(collidedBlock); // Check if we should spawn a power-up if (random.NextDouble() < powerUpChance) { SpawnPowerUp(collidedBlock.position); } // Add points AddScore(100 + 100 * speedMult); } ballHitSFX.Play(); CheckCollisions(); } // Check walls if (Math.Abs(ball.position.X - 32) < radius) { ball.direction.X = -1.0f * ball.direction.X; ballBounceSFX.Play(); } else if (Math.Abs(ball.position.X - 992) < radius) { ball.direction.X = -1.0f * ball.direction.X; ballBounceSFX.Play(); } else if (Math.Abs(ball.position.Y - 32) < radius) { ball.direction.Y = -1.0f * ball.direction.Y; ballBounceSFX.Play(); } else if (ball.position.Y > (768 + radius)) { ball.shouldRemove = true; LoseLife(); } } void LoseLife() { // Reset paddle and ball paddle.position = new Vector2(512, 740); deathSFX.Play(); ballCatchActive = false; paddle.ChangeTexture("paddle"); if (lives > 0) { lives--; SpawnBall(); } else { gameOver = true; } } void SpawnPowerUp(Vector2 position) { int type = random.Next(3); PowerUp p = new PowerUp((PowerUpType)type, this); p.LoadContent(); p.position = position; powerups.Add(p); } void RemovePowerUps() { for (int i = powerups.Count - 1; i >= 0; i--) { if (powerups[i].shouldRemove) { powerups.RemoveAt(i); } } } void CheckForPowerups() { Rectangle paddleRect = paddle.BoundingRect; foreach (PowerUp p in powerups) { Rectangle powerupRect = p.BoundingRect; if (paddleRect.Intersects(powerupRect)) { p.shouldRemove = true; powerupSFX.Play(); switch (p.type) { case (PowerUpType.BallCatch): ballCatchActive = true; break; case (PowerUpType.PaddleSize): paddle.ChangeTexture("paddle_long"); break; case (PowerUpType.MultiBall): SpawnBall(); break; } AddScore(500 + 500 * speedMult); } } void SpawnBall() { Ball ball = new Ball(this); ball.LoadContent(); ball.position = paddle.position; ball.position.Y -= ball.Height + paddle.Height; ball.speed = level.ballSpeed + 100 * speedMult; balls.Add(ball); } } void RemoveBalls() { for (int i = balls.Count - 1; i >= 0; i--) { if (balls[i].shouldRemove) { balls.RemoveAt(i); } } if (balls.Count == 0) { LoseLife(); } } void LoadLevel(string levelName) { using (FileStream fs = File.OpenRead("Levels/" + levelName)) { XmlSerializer serializer = new XmlSerializer(typeof(Level)); level = (Level)serializer.Deserialize(fs); } // Generate blocks based on level.layout array for (int i = 0; i < level.layout.Length; i++) { for (int j = 0; j < level.layout[i].Length; j++) { if (level.layout[i][j] != 9) { Block tempBlock = new Block((BlockColor)level.layout[i][j], this); tempBlock.LoadContent(); tempBlock.position = new Vector2(64 + j * 64, 100 + i * 32); blocks.Add(tempBlock); } } } } void NextLevel() { AddScore(5000 + 5000 * speedMult + 500 * (balls.Count - 1) * speedMult); balls.Clear(); powerups.Clear(); paddle.position = new Vector2(512, 740); StartLevelBreak(); ballCatchActive = false; paddle.ChangeTexture("paddle"); if (level.nextLevel == "Level1.xml") { speedMult++; } LoadLevel(level.nextLevel); levelNumber++; } void AddScore(int value) { score += value; pointsTilLife -= value; bool gainedLife = false; //I put a while loop here just in case you manage to get multiple lives while (pointsTilLife <= 0) { lives++; pointsTilLife += 20000; gainedLife = true; } if (gainedLife) { powerupSFX.Play(); } } void StartLevelBreak() { inLevelBreak = true; levelBreakTime = 2.0f; } }