XNA之RPG游戏开发教程之六

本节的任务有两点:1、创建一个新控件,实现角色的选择;具体操作要求是按左键,呈现上一个角色信息,按右键呈现下一个角色信息;2、创建一个角色选择页面,将新控件添加进去

首先开始第一个任务,前面已经创建了控件基类Control类和控件管理类ControlManager类,新的控件要继承基类,并在页面实例化后要添加进管理类中便于操作管理。新控件LeftRightSelector,一个向左向右可选择控件的代码实现如下

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
namespace XRpgLibrary.Controls
{
public class LeftRightSelector : Control
 {
 #region Event Region
public event EventHandler SelectionChanged;//控件选择更改事件
 #endregion
 #region Field Region
List<string> items = new List<string>();//控件中呈现字符串集合
Texture2D leftTexture;//表示向左,向右,尽头终止的图片
Texture2D rightTexture;
Texture2D stopTexture;
Color selectedColor = Color.Red;//被选字符串呈现红色
int maxItemWidth;//字符串项的最大宽度
int selectedItem;//被选择的项索引
 #endregion
 #region Property Region
public Color SelectedColor
 {
  get { return selectedColor; }
  set { selectedColor = value; }
 }
public int SelectedIndex { get { return selectedItem; } set { selectedItem = (int)MathHelper.Clamp(value, 0f, items.Count); } } public string SelectedItem { get { return Items[selectedItem]; } } public List<string> Items { get { return items; } } #endregion #region Constructor Region public LeftRightSelector(Texture2D leftArrow, Texture2D rightArrow, Texture2D stop) { leftTexture = leftArrow; rightTexture = rightArrow; stopTexture = stop; TabStop = true; Color = Color.White; } #endregion #region Method Region为字符串序列和字符串最大宽度赋值 public void SetItems(string[] items, int maxWidth) { this.items.Clear(); foreach (string s in items) this.items.Add(s); maxItemWidth = maxWidth; }
//事件触发函数
protected void OnSelectionChanged() { if (SelectionChanged != null) { SelectionChanged(this, null); } } #endregion #region Abstract Method Region public override void Update(GameTime gameTime) { } public override void Draw(SpriteBatch spriteBatch) { Vector2 drawTo = position; if (selectedItem != 0) spriteBatch.Draw(leftTexture, drawTo, Color.White); else spriteBatch.Draw(stopTexture, drawTo, Color.White); drawTo.X += leftTexture.Width + 5f;
float itemWidth = spriteFont.MeasureString(items[selectedItem]).X; float offset = (maxItemWidth - itemWidth) / 2; drawTo.X += offset; if (hasFocus) spriteBatch.DrawString(spriteFont, items[selectedItem], drawTo, selectedColor); else spriteBatch.DrawString(spriteFont, items[selectedItem], drawTo, Color); drawTo.X += -1 * offset + maxItemWidth + 5f; if (selectedItem != items.Count - 1) spriteBatch.Draw(rightTexture, drawTo, Color.White); else spriteBatch.Draw(stopTexture, drawTo, Color.White); } public override void HandleInput(PlayerIndex playerIndex) { if (items.Count == 0) return; if (InputHandler.ButtonReleased(Buttons.LeftThumbstickLeft, playerIndex) || InputHandler.ButtonReleased(Buttons.DPadLeft, playerIndex) || InputHandler.KeyReleased(Keys.Left)) { selectedItem--; if (selectedItem < 0) selectedItem = 0; OnSelectionChanged();//触发事件 } if (InputHandler.ButtonReleased(Buttons.LeftThumbstickRight, playerIndex) || InputHandler.ButtonReleased(Buttons.DPadRight, playerIndex) || InputHandler.KeyReleased(Keys.Right)) { selectedItem++; if (selectedItem >= items.Count) selectedItem = items.Count - 1; OnSelectionChanged(); } } #endregion } }

接着就是添加一个新的游戏页面,用来选取角色信息,具体代码如下

using System;
using System.Collections.Generic;
using System.Linq;using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using XRpgLibrary;
using XRpgLibrary.Controls;
namespace EyesOfTheDragon.GameScreens
{
public class CharacterGeneratorScreen : BaseGameState
 {
 #region Field Region
 LeftRightSelector genderSelector;//关于角色性别的selector控件
 LeftRightSelector classSelector;//关于角色类型的selector控件
 PictureBox backgroundImage;//游戏背景图片框
string[] genderItems = { "Male", "Female" };//用于初始化性别selector控件的字符串集
string[] classItems = { "Fighter", "Wizard", "Rogue", "Priest" };
 #endregion
 #region Property Region
 #endregion
 #region Constructor Region
public CharacterGeneratorScreen(Game game, GameStateManager stateManager)
 : base(game, stateManager)
 {
 }
 #endregion
 #region XNA Method Region
public override void Initialize()
 {
base.Initialize();
 }
protected override void LoadContent()
 {
 base.LoadContent();
 CreateControls();
 }
public override void Update(GameTime gameTime)
 {
 ControlManager.Update(gameTime, PlayerIndex.One);//对ControlManager进行更新,在其中会触发对页面上所有控件的更新
 base.Update(gameTime);
 }
public override void Draw(GameTime gameTime)
 {
 GameRef.SpriteBatch.Begin();
 base.Draw(gameTime);
 ControlManager.Draw(GameRef.SpriteBatch);//ControlManager的绘制,在其中可以对页面上所有控件进行绘制
 GameRef.SpriteBatch.End();
 }
 #endregion
 #region Method Region
private void CreateControls() { Texture2D leftTexture = Game.Content.Load<Texture2D>(@"GUI\leftarrowUp"); Texture2D rightTexture = Game.Content.Load<Texture2D>(@"GUI\rightarrowUp"); Texture2D stopTexture = Game.Content.Load<Texture2D>(@"GUI\StopBar"); backgroundImage = new PictureBox( Game.Content.Load<Texture2D>(@"Backgrounds\titlescreen"), GameRef.ScreenRectangle); ControlManager.Add(backgroundImage);//实例化背景控件,并加入到控件管理类中 Label label1 = new Label(); label1.Text = "Who will search for the Eyes of the Dragon?"; label1.Size = label1.SpriteFont.MeasureString(label1.Text); label1.Position = new Vector2((GameRef.Window.ClientBounds.Width - label1.Size.X) / 2, 150); ControlManager.Add(label1);//实例化标题label,并加入到控件管理类中 genderSelector = new LeftRightSelector(leftTexture, rightTexture, stopTexture); genderSelector.SetItems(genderItems, 125); genderSelector.Position = new Vector2(label1.Position.X, 200); ControlManager.Add(genderSelector);//实例化性别selector,加入管理类 classSelector = new LeftRightSelector(leftTexture, rightTexture, stopTexture); classSelector.SetItems(classItems, 125); classSelector.Position = new Vector2(label1.Position.X, 250); ControlManager.Add(classSelector);//实例化类型selector,加入管理类 LinkLabel linkLabel1 = new LinkLabel(); linkLabel1.Text = "Accept this character."; linkLabel1.Position = new Vector2(label1.Position.X, 300); linkLabel1.Selected += new EventHandler(linkLabel1_Selected); ControlManager.Add(linkLabel1);//实例化接受LinkLabel对象,加入管理类 ControlManager.NextControl();//执行NextControl,使得当前呈现选项为被选中状态 } void linkLabel1_Selected(object sender, EventArgs e) { InputHandler.Flush(); StateManager.PopState(); StateManager.PushState(GameRef.GamePlayScreen);//呈现游戏页面 } #endregion } }

接下来就是讲新的角色选择页面添加到Game1类中,代码如下

public CharacterGeneratorScreen CharacterGeneratorScreen;
public Game1()
{
 graphics = new GraphicsDeviceManager(this);
 graphics.PreferredBackBufferWidth = screenWidth;
 graphics.PreferredBackBufferHeight = screenHeight;
 ScreenRectangle = new Rectangle(
 0,
 0,
 screenWidth,
 screenHeight);
 Content.RootDirectory = "Content";
 Components.Add(new InputHandler(this)); 
stateManager = new GameStateManager(this); Components.Add(stateManager); TitleScreen = new TitleScreen(this, stateManager); StartMenuScreen = new StartMenuScreen(this, stateManager); GamePlayScreen = new GamePlayScreen(this, stateManager); CharacterGeneratorScreen = new CharacterGeneratorScreen(this, stateManager);//添加新的页面 stateManager.ChangeState(TitleScreen); }

同时在StartMenuScreen页面中修改menuItem_Selected方法,使得选择startgame选项时候,跳转到新建的角色选择页面

private void menuItem_Selected(object sender, EventArgs e)
{
if (sender == startGame)
 {
 StateManager.PushState(GameRef.CharacterGeneratorScreen);
 }
if (sender == loadGame)
 {
 StateManager.PushState(GameRef.GamePlayScreen);
 }
if (sender == exitGame)
 {
 GameRef.Exit();
 }
}

OK,本节任务结束

原文地址:https://www.cnblogs.com/zcftech/p/3001652.html