c#monogame visual studio - 游戏菜单不起作用,当敌人击中时游戏结束时屏幕无效

时间:2018-05-21 10:45:41

标签: c# visual-studio monogame

我正在使用C#和monogame框架在Visual Studio中构建此游戏。游戏的目的是让你使用埃里克躲避随着时间的推移而变得更快的堕落敌人,如果你击中了敌人,那么游戏结束了。

有一个主菜单在游戏开始之前加载,要求你按Enter键开始游戏,如果你按下这个游戏加载,如果你击中一个敌人就会出现一个屏幕上的游戏,你返回到主菜单按A.

但是,目前我的游戏并未首先打开主菜单或在屏幕上显示游戏。这些屏幕使用与主游戏本身相同的背景图像,但文本采用深红色字体,以使状态易于区分。

这是我的代码,请有人建议

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using System.Collections.Generic;
using System;
using System.Media;
using Microsoft.Xna.Framework.Audio;


namespace AttackOfTheUnknown
{
    /// <summary>
    /// Constructor for Game.
    /// This is called when the Game object is created.
    /// </summary>
    public class SuperAlianorRescue : Game
    {
        // --- GAME STATE ---
        enum GameState
        {
            GameMenu = 0,
            GamePlay = 1,
            GameOver = 2,
        }
        GameState currentGameState;

        // --- GRAPHICS ---
        // Manages the graphics
        GraphicsDeviceManager graphics;
        // Used to draw sprite images (textures)
        SpriteBatch spriteBatch;
        // Area which should be visible on all TVs (OK to draw inside)
        Rectangle safeBounds;
        // Percentage of the screen on every side is the safe area
        const float safeAreaPortion = 0.05f;

        // --- CHARACTER ---
        // Used for character sprite
        Texture2D characterTexture;
        // Used to store current character position
        Vector2 characterPosition;
        // Used to calculate next position of character given user input
        const int characterSpeed = 10;
        // Used to state character has collided with enemy
        bool characterHit = false;

        //--- ENEMIES ---
        // Used for enemy sprite
        Texture2D enemyTexture;
        // The list of enemies currently in the game
        List<Vector2> enemyPositions = new List<Vector2>();
        // Probability that an enemy will be spawned
        float enemySpawnProbability = 0.05f;
        // Speed of enemy
        public float speedIncrement = 0.01f;
        public float enemySpeed = 0.005f;
        public float speed = 0;
        // Used to generate random colours
        Random random = new Random();
        // Current enemy colour
        Color enemyColor = Color.White;

        // IMPORT GAME BACKGROUND
        Texture2D backgroundTexture;

        // SOUND
        // enemy spawn sound
        SoundEffect enemySpawnSound;
        SoundEffectInstance enemySpawnSoundInstance;

        // --- IN_GAME INFORMATION ---
        // Player score
        long score;
        // Highest score
        long highScore;
        // Font used to display score
        SpriteFont scoreFont;
        // Used to hold current on-screen information
        string scoreText = "SCORE: 0";
        string highScoreText = "HI: 0";
        string gameName = "Super Alianor Rescue";
        string aimText = "Aim: Move Eric with WASD keys to dodge the enemies.";
        string menuWelcome = "Welcome to Super Alianor Rescue.";
        string menuHowToPlay = "Press ENTER To Start New Game.";
        string GameOverText = "Game Over";
        string GameOverClose = "Press Escape To Quit Game";

        Song theSong;

        public SuperAlianorRescue()
        {
            graphics = new GraphicsDeviceManager(this);

            graphics.PreferredBackBufferHeight = 600;
            graphics.PreferredBackBufferWidth = 650;

            Content.RootDirectory = "Content";
        }

        /// <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()
        {
            base.Initialize();

            // Calculate safe bounds based on current resolution
            Viewport viewport = graphics.GraphicsDevice.Viewport;
            safeBounds = new Rectangle(
                (int)(viewport.Width * safeAreaPortion),
                (int)(viewport.Height * safeAreaPortion),
                (int)(viewport.Width * (1 - 2 * safeAreaPortion)),
                (int)(viewport.Height * (1 - 2 * safeAreaPortion)));

            // Start the player in the centre along the bottom of the screen
            characterPosition.X = (safeBounds.Width - characterTexture.Width) / 2;
            characterPosition.Y = safeBounds.Height - characterTexture.Height;

            // Reset score
            score = 0;
            highScore = 0;

            MediaPlayer.IsRepeating = true;
            MediaPlayer.Play(theSong);
            MediaPlayer.Volume = 0.01f;

            // Set the initial game state
            currentGameState = GameState.GameMenu;

            // Reset score
            score = 0;
            highScore = 0;
        }

        /// <summary>
        /// LoadContent will be called once per game and is the place to load
        /// all of your content.
        /// </summary>
        protected override void LoadContent()
        {
            // Create a new SpriteBatch, which can be used to draw textures.
            spriteBatch = new SpriteBatch(GraphicsDevice);

            // Load textures
            enemyTexture = Content.Load<Texture2D>("enemy");
            characterTexture = Content.Load<Texture2D>("eric2");
            backgroundTexture = Content.Load<Texture2D>("gameback");

            // create the font
            scoreFont = Content.Load<SpriteFont>("GameFont");

            theSong = Content.Load<Song>("Komiku_-_63_-_The_Zone");


            // create the sound effect
            enemySpawnSound = Content.Load<SoundEffect>("Zombie Demon");
            enemySpawnSoundInstance = enemySpawnSound.CreateInstance();
            enemySpawnSoundInstance.Volume = 1.0f;
            enemySpawnSoundInstance.Pitch = 1.0f;

        }
        /// <summary>
        /// UnloadContent will be called once per game and is the place to unload
        /// game-specific content.
        /// </summary>
        protected override void UnloadContent()
        {
            // TODO: Unload any non ContentManager content here
        }

        /// <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)
        {
            // Get input
            KeyboardState keyboard = Keyboard.GetState();
            GamePadState gamePad = GamePad.GetState(PlayerIndex.One);

            // use game state
            switch (currentGameState)
            {
                case GameState.GameMenu:
                    // Allows the game to exit
                    if (gamePad.Buttons.Back == ButtonState.Pressed ||
                        keyboard.IsKeyDown(Keys.Escape))
                    {
                        this.Exit();
                    }
                    if (gamePad.Buttons.Start == ButtonState.Pressed ||
                        keyboard.IsKeyDown(Keys.Enter))
                    {
                        // Start the player in the center along the bottom of the screen
                        characterPosition.X = (safeBounds.Width - characterTexture.Width) / 2;
                        characterPosition.Y = (safeBounds.Height - characterTexture.Height);

                        // Set the game state to play
                        currentGameState = GameState.GamePlay;

                        // Reset score
                        score = 0;
                    }
                    break;
                case GameState.GameOver:
                    // If game is over, the game allows return to main menu if key A is pressed 
                    if (gamePad.Buttons.A == ButtonState.Pressed ||
                        keyboard.IsKeyDown(Keys.A))
                    {
                        currentGameState = GameState.GameMenu;
                    }
                    break;
                case GameState.GamePlay:
                    // Press X during game play to return to main menu
                    if (gamePad.Buttons.X == ButtonState.Pressed ||
                        keyboard.IsKeyDown(Keys.X))
                    {
                        currentGameState = GameState.GameMenu;
                    }
                    // Press ESC to quit game during game play
                    if (gamePad.Buttons.Back == ButtonState.Pressed ||
                keyboard.IsKeyDown(Keys.Escape))
                    {
                        this.Exit();
                    }

                    //Move the player left and right with arrow keys or d-pad
                    if (keyboard.IsKeyDown(Keys.Left) || gamePad.DPad.Left == ButtonState.Pressed)
                    {
                        characterPosition.X -= characterSpeed;
                    }
                    if (keyboard.IsKeyDown(Keys.Right) || gamePad.DPad.Right == ButtonState.Pressed)
                    {
                        characterPosition.X += characterSpeed;
                    }

                    // Prevent the character from moving off of the screen
                    characterPosition.X = MathHelper.Clamp(characterPosition.X,
                        safeBounds.Left, safeBounds.Right - characterTexture.Width);

                    // Get the bounding rectangle of the character
                    Rectangle characterRectangle =
                        new Rectangle((int)characterPosition.X, (int)characterPosition.Y,
                        characterTexture.Width, characterTexture.Height);

                    // Spawn new enemy
                    if (random.NextDouble() < enemySpawnProbability)
                    {
                        float x = (float)random.NextDouble() *
                            (Window.ClientBounds.Width - enemyTexture.Width);
                        enemyPositions.Add(new Vector2(x, -enemyTexture.Height));

                        // play the enemy spawn sound
                        enemySpawnSoundInstance.Play();
                    }

                    // Increase enemy speed as game progresses
                    enemySpeed += speedIncrement;
                    if (speed >= speedIncrement) speed = enemySpeed;

                    // Update each enemy
                    characterHit = false;
                    for (int i = 0; i < enemyPositions.Count; i++)
                    {
                        // Animate this enemy
                        enemyPositions[i] =
                            new Vector2(enemyPositions[i].X,
                                        enemyPositions[i].Y + enemySpeed);

                        // Get the bounding rectangle of this enemy
                        Rectangle enemyRectangle =
                            new Rectangle((int)enemyPositions[i].X, (int)enemyPositions[i].Y,
                            enemyTexture.Width, enemyTexture.Height);

                        // Check collision with character
                        if (characterRectangle.Intersects(enemyRectangle))
                            characterHit = true;

                        // Remove this enemy if it has fallen off the screen
                        if (enemyPositions[i].Y > Window.ClientBounds.Height)
                        {
                            enemyPositions.RemoveAt(i);

                            // When removing an enemy, the next enemy will have the same index 
                            // as the current enemy. Decrement i to prevent skipping an enemy.
                            i--;
                        }
                    }

                    // Reset game if character has been hit
                    if (characterHit)
                    {
                        // check for highscore
                        if (score > highScore)
                            highScore = score;

                        // reset score to zero
                        score = 0;

                        // empty the enemies list
                        enemyPositions = new List<Vector2>();

                        // change color of enemies to indicate a new game
                        enemyColor = new Color(random.Next(0, 255), random.Next(0, 255), random.Next(0, 255));

                        // finish game by loading gameover screen
                        currentGameState = GameState.GameOver;
                    }
                    else
                    {
                        // update score (character has been hit)
                        score = score + 1;
                    }

                    // update on-screen information variables
                    scoreText = "SCORE: " + score.ToString();
                    highScoreText = "HIGH SCORE: " + highScore.ToString();

                    break;
            }
            base.Update(gameTime);
        }
        /// <summary>
        /// This is called when the game should draw itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice device = graphics.GraphicsDevice;

            // use game state
            switch (currentGameState)
            {
                case GameState.GameMenu:                              // load game menu and clear once enter key is pressed
                    spriteBatch.Begin();
                    spriteBatch.Draw(backgroundTexture, Vector2.Zero, Color.White);
                    spriteBatch.DrawString(scoreFont, menuWelcome,
                new Vector2((float)safeBounds.Right / 2 - scoreFont.MeasureString(menuWelcome).X / 3,
                30), Color.DarkRed);
                    spriteBatch.DrawString(scoreFont, menuHowToPlay,
                new Vector2((float)safeBounds.Right / 2 - scoreFont.MeasureString(menuHowToPlay).X / 4,
                30), Color.DarkRed);
                    spriteBatch.End();
                    device.Clear(Color.DarkBlue);
                    break;

                case GameState.GameOver:                          // load game menu and clear once escape is pressed
                    spriteBatch.Begin();
                    spriteBatch.Draw(backgroundTexture, Vector2.Zero, Color.White);
                    spriteBatch.DrawString(scoreFont, GameOverText,
                new Vector2((float)safeBounds.Right / 2 - scoreFont.MeasureString(GameOverText).X / 3,
                30), Color.DarkRed);
                    spriteBatch.DrawString(scoreFont, GameOverClose,
                new Vector2((float)safeBounds.Right / 2 - scoreFont.MeasureString(GameOverClose).X / 4,
                30), Color.DarkRed);
                    spriteBatch.End();
                    device.Clear(Color.DarkBlue);
                    break;

                case GameState.GamePlay:                // load the sprite batch for main game play
                    // Open sprite batch
                    spriteBatch.Begin();
                    spriteBatch.End();
                    break;
            }
            device.Clear(Color.CornflowerBlue);

            // "Open" the sprite batch
            spriteBatch.Begin();

            // Clear game screen with background colour
            device.Clear(Color.DarkBlue);

            // Draw background
            spriteBatch.Draw(backgroundTexture, Vector2.Zero, Color.White);

            // Draw character
            spriteBatch.Draw(characterTexture, characterPosition, Color.White);

            // Draw enemies
            foreach (Vector2 enemyPosition in enemyPositions)
                spriteBatch.Draw(enemyTexture, enemyPosition, enemyColor);

            // Draw on-screen game information
            spriteBatch.DrawString(scoreFont, scoreText, new Vector2(30, 30), Color.Black);
            spriteBatch.DrawString(scoreFont, highScoreText,
                new Vector2((float)safeBounds.Right - scoreFont.MeasureString(highScoreText).X,
                30), Color.Black);
            spriteBatch.DrawString(scoreFont, gameName,
                new Vector2((float)safeBounds.Right / 2 - scoreFont.MeasureString(gameName).X / 2,
                30), Color.Black);
            spriteBatch.DrawString(scoreFont, aimText,
                new Vector2((float)safeBounds.Right / 2 - scoreFont.MeasureString(gameName).X / 1,
                60), Color.Black);

            // "Close" the sprite batch
            spriteBatch.End();
            break;
            base.Draw(gameTime);
        }
    }
}

1 个答案:

答案 0 :(得分:1)

您的游戏状态的绘制代码在switch语句之外,因此在绘制的精灵上删除任何菜单或游戏,并在顶部绘制游戏精灵。这是由这段代码引起的:

            case GameState.GamePlay:                // load the sprite batch for main game play
                // Open sprite batch
                spriteBatch.Begin();
                spriteBatch.End();
                break;
        }

要解决此问题,您需要将游戏状态绘制代码移至switch语句中,如下所示:

    protected override void Draw(GameTime gameTime)
    {
        GraphicsDevice device = graphics.GraphicsDevice;

        // use game state
        switch (currentGameState)
        {
            case GameState.GameMenu:                              // load game menu and clear once enter key is pressed
                device.Clear(Color.DarkBlue);
                spriteBatch.Begin();
                spriteBatch.Draw(backgroundTexture, Vector2.Zero, Color.White);
                spriteBatch.DrawString(scoreFont, menuWelcome,
                    new Vector2((float)safeBounds.Right / 2 - scoreFont.MeasureString(menuWelcome).X / 3,
                    30), Color.DarkRed);
                spriteBatch.DrawString(scoreFont, menuHowToPlay,
                    new Vector2((float)safeBounds.Right / 2 - scoreFont.MeasureString(menuHowToPlay).X / 4,
                    30), Color.DarkRed);
                spriteBatch.End();
                break;

            case GameState.GameOver:                          // load game menu and clear once escape is pressed
                device.Clear(Color.DarkBlue);
                spriteBatch.Begin();
                spriteBatch.Draw(backgroundTexture, Vector2.Zero, Color.White);
                spriteBatch.DrawString(scoreFont, GameOverText,
                    new Vector2((float)safeBounds.Right / 2 - scoreFont.MeasureString(GameOverText).X / 3,
                    30), Color.DarkRed);
                spriteBatch.DrawString(scoreFont, GameOverClose,
                    new Vector2((float)safeBounds.Right / 2 - scoreFont.MeasureString(GameOverClose).X / 4,
                    30), Color.DarkRed);
                spriteBatch.End();
                device.Clear(Color.DarkBlue);
                break;

            case GameState.GamePlay:                // load the sprite batch for main game play

                device.Clear(Color.CornflowerBlue);

                // Open sprite batch
                spriteBatch.Begin();

                // Draw background
                spriteBatch.Draw(backgroundTexture, Vector2.Zero, Color.White);

                // Draw character
                spriteBatch.Draw(characterTexture, characterPosition, Color.White);

                // Draw enemies
                foreach (Vector2 enemyPosition in enemyPositions)
                    spriteBatch.Draw(enemyTexture, enemyPosition, enemyColor);

                // Draw on-screen game information
                spriteBatch.DrawString(scoreFont, scoreText, new Vector2(30, 30), Color.Black);
                spriteBatch.DrawString(scoreFont, highScoreText,
                    new Vector2((float)safeBounds.Right - scoreFont.MeasureString(highScoreText).X,
                    30), Color.Black);
                spriteBatch.DrawString(scoreFont, gameName,
                    new Vector2((float)safeBounds.Right / 2 - scoreFont.MeasureString(gameName).X / 2,
                    30), Color.Black);
                spriteBatch.DrawString(scoreFont, aimText,
                    new Vector2((float)safeBounds.Right / 2 - scoreFont.MeasureString(gameName).X / 1,
                    60), Color.Black);

                // "Close" the sprite batch
                spriteBatch.End();
                break;
        }
        base.Draw(gameTime);
    }

以前你在switch语句中的游戏状态创建了一个空的sprite批处理并关闭了switch语句,然后是游戏绘制代码。

在上文中,我已将您的游戏绘制代码移至switch语句中(为了清晰起见,将device.clear()语句移至每个开关块的顶部)