我正在使用XNA 4.0在Visual Studio 2012中的游戏中实现一个菜单系统。我有我的game1类文件中的枚举GameStates mainMenu,Instructions和PlayGame以及所有按钮。如何让游戏使用
我正在运行游戏并希望实现主菜单系统。以下代码是我将在主菜单中使用的代码。我的问题是如何将现有游戏添加到此主菜单代码
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
namespace MainMenu
{
/// <summary>
/// This is the main type for your game
/// </summary>
public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
enum GameState
{
//which states we which to have
MainMenu, Instructions, PlayGame,
}
//when the game loads, it begins with main menu
GameState CurrentGameState = GameState.MainMenu;
//Screen Adjustments
int screenWidth = 800, screenHeight = 600;
cButton btnPlay;
cButton btnInstru;
public Game1()
{
graphics = new GraphicsDeviceManager(this);
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()
{
// TODO: Add your initialization logic here
base.Initialize();
}
/// <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);
//Screen Properties
graphics.PreferredBackBufferWidth = screenWidth;
graphics.PreferredBackBufferHeight = screenHeight;
graphics.ApplyChanges();
IsMouseVisible = true;
btnPlay = new cButton(Content.Load<Texture2D>("Button"), graphics.GraphicsDevice);
btnInstru = new cButton(Content.Load<Texture2D>("Button"), graphics.GraphicsDevice);
btnPlay.setPosition(new Vector2(350, 300));
btnInstru.setPosition(new Vector2(350, 350));
}
/// <summary>
/// UnloadContent will be called once per game and is the place to unload
/// all 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)
{
MouseState mouse = Mouse.GetState();
switch (CurrentGameState)
{
case GameState.MainMenu:
if (btnPlay.isClicked == true)
{
CurrentGameState = GameState.PlayGame;
}
if (btnInstru.isClicked == true)
{
CurrentGameState = GameState.Instructions;
}
btnPlay.Update(mouse);
btnInstru.Update(mouse);
break;
case GameState.PlayGame:
break;
case GameState.Instructions:
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.Clear(Color.CornflowerBlue);
spriteBatch.Begin();
switch (CurrentGameState)
{
case GameState.MainMenu:
spriteBatch.Draw(Content.Load<Texture2D>("MainMenu"), new Rectangle(0, 0, screenWidth, screenHeight), Color.White);
btnPlay.Draw(spriteBatch);
btnInstru.Draw(spriteBatch);
break;
case GameState.PlayGame:
break;
case GameState.Instructions:
break;
}
spriteBatch.End();
base.Draw(gameTime);
}
}
}
答案 0 :(得分:0)
通常你会把它添加到你的GameState.PlayGame中,好像它不够明显。那就是你要画你的精灵,游戏物品,敌人等等。
此外,如果你打算做一个菜单系统,你可能想要使用类。
答案 1 :(得分:0)
我避免放下任何代码,我只是提出一些关于你可以遵循的指示。如果您自己动手(它的优秀实践),它将允许您思考并添加您可能没有完成的不同功能,如果您刚刚直接使用我的代码。或者你可以更简单的方式继承gamecomponent对象,但它缺乏灵活性imo。
关于你的游戏,这就是我的错误:你将使用一个巨大的开关盒。当你的游戏处于良好的发展阶段时,它最终会变得无法控制。为避免出现这种情况,请立即停止操作,而是为自己创建一个GameState Manager。你想要的是分离游戏的每个元素。您的主循环应始终呼叫经理。并且让我们了解应该在这些经理中绘制什么。让我们称之为GameWindows。
每个管理器都有一个属性,它是一个自定义类列表,它们处理逻辑(WindowsList)。你给那些“Windows”一个ID或一个唯一的名字(在你的情况下是一个GameState)。
在管理器的更新代码中,您迭代抛出WindowsList,并更新所有具有标志“WindowIsActive”的类为true。在绘图代码中,您绘制所有具有“可见”标志的窗口为true。
在GameWindows中,你创建一个函数Erase(windowsName)(你不能只从列表中删除一个窗口,否则它会在迭代中崩溃,你创建第二个列表“WindowsToDelete”并添加你要删除的窗口那里,你在更新阶段处理删除)
现在,您的主要game1课程将更加清洁。你只需要在update方法中使用GameWindows.Update(),在draw方法中使用GameWindows.Draw()。
基本上,这可以让你创建不同的元素和功能(比如一个菜单,可以看不见,并在按键时调用),而不必在每次添加不同的游戏元素时处理越来越大的开关案例。并且它将仅更新/绘制您需要的窗口,允许您“睡眠”您不需要的元素,并允许您保持游戏快速运行。
将所有自定义类“Windows”视为一个单独的元素,您可以为它们中的每一个处理它们的特定Draw()函数。我还在每个“Window”中都有一个TestClick(mousePosition)函数,您可以在GameWindows.Update()中使用它来处理不同的鼠标点击。