本节的任务有两点: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 Regionpublic event EventHandler SelectionChanged;//控件选择更改事件 #endregion #region Field RegionListitems = new List ();//控件中呈现字符串集合Texture2D leftTexture;//表示向左,向右,尽头终止的图片Texture2D rightTexture;Texture2D stopTexture;Color selectedColor = Color.Red;//被选字符串呈现红色int maxItemWidth;//字符串项的最大宽度int selectedItem;//被选择的项索引 #endregion #region Property Regionpublic 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 Items { get { return items; } } #endregion #region Constructor Regionpublic 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 Regionpublic 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 Regionpublic CharacterGeneratorScreen(Game game, GameStateManager stateManager) : base(game, stateManager) { } #endregion #region XNA Method Regionpublic 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(@"GUI\leftarrowUp");Texture2D rightTexture = Game.Content.Load (@"GUI\rightarrowUp");Texture2D stopTexture = Game.Content.Load (@"GUI\StopBar"); backgroundImage = new PictureBox( Game.Content.Load (@"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,本节任务结束