C#XNA-背景音乐逻辑

本文关键字:背景音乐 C#XNA- | 更新日期: 2023-09-27 18:26:27

所以我正在处理XNA游戏状态示例。我有两首不同的歌曲在游戏状态下播放和循环。这意味着:

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;
    }

C#XNA-背景音乐逻辑

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

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
    }
}

为什么不写一个包装类来包装歌曲和游戏状态成员,并在当前游戏状态等于该状态时播放歌曲?@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);
        }
    }
}