• 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,本节任务结束

  • 相关阅读:
    大学总结(一)
    关于数组名与指针的相互转换
    错误:无法执行操作,因为未将指定的 Storyboard 应用到此交互控件的对象
    延迟初始化 (Lazy Initialization)
    Sql Server 中 GAM、SGAM、PAM、IAM、DCM 和 BCM 的详解与区别
    Xml格式的字符串(string)到DataSet(DataTable)的转换
    Sql Server 内存用不上的解决办法
    Sql Server 管理区分配(GAM,SGAM)和可用空间(PAM)的原理
    Sql Server LightWeight Pooling(纤程) 选项
    在线 Sql Server 服务无法启动的解决办法
  • 原文地址:https://www.cnblogs.com/zcftech/p/3001652.html
Copyright © 2020-2023  润新知