Пример #1
0
        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;
            }
        }
Пример #2
0
        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;
            }
        }
Пример #3
0
        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;
            }
        }