C#XNA - 背景音乐逻辑

时间:2014-10-14 20:09:37

标签: c# xna

所以我正在使用XNA游戏状态样本。我有2首不同的歌曲在游戏状态中播放和循环。这意味着:

mainMenu.mp3 goes to the mainMenu game state
backgroundMusic.mp3 goes to the Playing game state

所以这很有效。但是我也有Escape键逻辑,它将你从任何状态返回到mainMenu状态(按下Esc时)。来自Playing的歌曲停止,来自mainMenu的歌曲开始播放。但是,如果我单击“开始游戏”按钮将我移至Playing,则不会播放背景音乐。哪个可能是问题?

这是我的代码:

    // Main Menu game state
    if (Game1.g_CurrentGameState == Game1.g_GameStates.g_MainMenu && !m_SongStart)
    {
        MediaPlayer.Play(m_MainMenuTheme);
        m_SongStart = true; // bool
    }

    if (Game1.g_CurrentGameState != Game1.g_GameStates.g_MainMenu)
    {
        MediaPlayer.Stop();
        m_SongStart = false; // bool
    }

    // Playing game state
    if (Game1.g_CurrentGameState == Game1.g_GameStates.g_GamePlaying && !m_SongStart)
    {
        MediaPlayer.Play(m_GamePlayingMainTheme);
        m_SongStart = true;
    }
    if (Game1.g_CurrentGameState != Game1.g_GameStates.g_GamePlaying)
    {
        MediaPlayer.Stop();
        m_SongStart = false;
    }

2 个答案:

答案 0 :(得分:1)

以下代码将根据当前游戏状态播放歌曲:

using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;

namespace WindowsGame1
{
    public class Game1 : Game
    {
        private GameState _gameState;
        private GraphicsDeviceManager _graphicsDeviceManager;
        private KeyboardState _keyboardState;
        private Song _song1;
        private Song _song2;

        public Game1() {
            _graphicsDeviceManager = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";
        }

        protected override void LoadContent() {
            _song1 = Content.Load<Song>("song1");
            _song2 = Content.Load<Song>("song2");
        }

        protected override void UnloadContent() {
            if (_song1 != null) _song1.Dispose();
            if (_song2 != null) _song2.Dispose();
        }

        protected override void Update(GameTime gameTime) {
            GameState gameState = _gameState;
            var keyboardState = Keyboard.GetState();
            if (keyboardState.IsKeyDown(Keys.A) && _keyboardState.IsKeyUp(Keys.A)) {
                gameState = GameState.Menu;
            }
            else if (keyboardState.IsKeyDown(Keys.B) && _keyboardState.IsKeyUp(Keys.B)) {
                gameState = GameState.InGame;
            }
            else if (keyboardState.IsKeyDown(Keys.C) && _keyboardState.IsKeyUp(Keys.C)) {
                gameState = GameState.Undefined;
            }
            _keyboardState = keyboardState;
            if (gameState != _gameState) {
                switch (gameState) {
                    case GameState.Undefined:
                        MediaPlayer.Stop();
                        break;
                    case GameState.Menu:
                        MediaPlayer.Stop();
                        MediaPlayer.Play(_song1);
                        break;
                    case GameState.InGame:
                        MediaPlayer.Stop();
                        MediaPlayer.Play(_song2);
                        break;
                    default:
                        throw new ArgumentOutOfRangeException();
                }
                _gameState = gameState;
            }

            base.Update(gameTime);
        }

        protected override void Draw(GameTime gameTime) {
            GraphicsDevice.Clear(Color.CornflowerBlue);
            base.Draw(gameTime);
        }
    }

    internal enum GameState
    {
        Undefined,
        Menu,
        InGame
    }
}

答案 1 :(得分:1)

为什么不写一个包装类来包装歌曲和游戏状态成员并在当前游戏状态等于那个时播放歌曲? @ Aybe的答案的oop版本。相信他!

这是我提出的。应该易于使用和管理。很简单。

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

namespace WindowsGame1
{
    public class GameStateManager
    {
        private static List<GameState> GameStates = new List<GameState>();
        private static GameState CurrentGameState = null;

        public static void AddState(GameState gameState)
        {
            GameStates.Add(gameState);
        }

        public static GameState GetState(string name)
        {
            return GameStates.Find(gameState => gameState.Name == name);
        }

        public static void SwitchStates(GameState gameState)
        {
            if (CurrentGameState != null)
            {
                if (MediaPlayer.State == MediaState.Playing)
                    MediaPlayer.Stop();
            }
            CurrentGameState = gameState;
            if (CurrentGameState != null)
                MediaPlayer.Play(CurrentGameState.Song);
        }

        public static void SwitchStates(string gameState)
        {
            SwitchStates(GetState(gameState));
        }

        public static void Dispose()
        {
            foreach (var gameState in GameStates)
            {
                gameState.Song.Dispose();
            }
            GameStates.Clear();
        }
    }

    public class GameState
    {
        public Song Song;
        public string Name;

        public GameState(string name, Song song)
        {
            Name = name;
            Song = song;
        }
    }

    public class Game1 : Game
    {
        private GraphicsDeviceManager _graphicsDeviceManager;
        private KeyboardState _keyboardState;

        public Game1()
        {
            _graphicsDeviceManager = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";
        }

        protected override void LoadContent()
        {
            GameStateManager.AddState(new GameState("InGame", Content.Load<Song>("song1")));
            GameStateManager.AddState(new GameState("Menu", Content.Load<Song>("song2")));
        }

        protected override void UnloadContent()
        {
            GameStateManager.Dispose();
        }

        protected override void Update(GameTime gameTime)
        {
            var keyboardState = Keyboard.GetState();
            if (keyboardState.IsKeyDown(Keys.A) && _keyboardState.IsKeyUp(Keys.A))
            {
                GameStateManager.SwitchStates("Menu");
            }
            else if (keyboardState.IsKeyDown(Keys.B) && _keyboardState.IsKeyUp(Keys.B))
            {
                GameStateManager.SwitchStates("InGame");
            }
            else if (keyboardState.IsKeyDown(Keys.C) && _keyboardState.IsKeyUp(Keys.C))
            {
                GameStateManager.SwitchStates("Undefined");
            }
            _keyboardState = keyboardState;


            base.Update(gameTime);
        }

        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.CornflowerBlue);
            base.Draw(gameTime);
        }
    }
}