XNA之RPG游戏开发教程之三

本节在上一节基础上继续完善该游戏引擎,主要完成以下任务:

(1)完善StartMenuScreen,同时添加一个GamePlayScreen页面

(2)创建一个新的控件,picture box

(3)为ControlManager类添加新的事件处理

首先是给ControlManager类添加新的事件处理,FocusChanged事件;因为要通过LinkLabel实现页面间跳转,控件的聚焦变化后触发该事件,ControlManager类代码修改如下:

#region Event Region

public event EventHandler FocusChanged;//聚焦更改事件

#endregion

public void NextControl()

{

if (Count == 0)

return;

int currentControl = selectedControl;

this[selectedControl].HasFocus = false;

do

 {

 selectedControl++;

if (selectedControl == Count)

 selectedControl = 0;

if (this[selectedControl].TabStop && this[selectedControl].Enabled)

 {
//代码增添部分,当LinkLabel控件聚焦发生改变,触发事件
if (FocusChanged != null) FocusChanged(this[selectedControl], null); break; } } while (currentControl != selectedControl); this[selectedControl].HasFocus = true; }
public void PreviousControl() { if (Count == 0) return; int currentControl = selectedControl; this[selectedControl].HasFocus = false; do { selectedControl--; if (selectedControl < 0) selectedControl = Count - 1; if (this[selectedControl].TabStop && this[selectedControl].Enabled) { if (FocusChanged != null) FocusChanged(this[selectedControl], null); break; } } while (currentControl != selectedControl); this[selectedControl].HasFocus = true; }

添加一个新的游戏页面GamePlayScreen,代码跟上一节的StartMenuScreen的代码相似,只是对BaseGameState的简单继承

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;

namespace EyesOfTheDragon.GameScreens

{

public class GamePlayScreen : BaseGameState

 {

 #region Field Region

 #endregion

 #region Property Region

 #endregion

 #region Constructor Region

public GamePlayScreen(Game game, GameStateManager manager)

 : base(game, manager)

 {

 }

 #endregion #region XNA Method Region

public override void Initialize()

 {

base.Initialize();

 }

protected override void LoadContent()

 {

base.LoadContent();

 }

public override void Update(GameTime gameTime)

 {

base.Update(gameTime);

 }

public override void Draw(GameTime gameTime)

 {

base.Draw(gameTime);

 }

 #endregion

 #region Abstract Method Region

 #endregion

 }

}

将该页面添加到Game1.cs中

public GamePlayScreen GamePlayScreen;//定义一个类级变量

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);//在类中添加对象

 stateManager.ChangeState(TitleScreen);

}

第二件事就是创建一个新的控件:picture box,跟LinkLabel一样

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 PictureBox : Control

 {

 #region Field Region

Texture2D image;//控件中加载的图片

Rectangle sourceRect;//图片的长度矩形

Rectangle destRect;//图片在窗体上呈现的矩形

 #endregion

 #region Property Region

public Texture2D Image

 {

get { return image; }

set { image = value; }

 }

public Rectangle SourceRectangle

 {

get { return sourceRect; }

set { sourceRect = value; }

 }

public Rectangle DestinationRectangle

 {

get { return destRect; }

set { destRect = value; }

 }

 #endregion

 #region Constructors构造函数的重载

public PictureBox(Texture2D image, Rectangle destination)

 {

 Image = image;

 DestinationRectangle = destination;

 SourceRectangle = new Rectangle(0, 0, image.Width, image.Height);//原图片大小

 Color = Color.White;

 }

public PictureBox(Texture2D image, Rectangle destination, Rectangle source)

 {

 Image = image;

 DestinationRectangle = destination;

 SourceRectangle = source;

 Color = Color.White;

 }

 #endregion

 #region Abstract Method Region//来自于继承类的方法重载

public override void Update(GameTime gameTime)

 { }

public override void Draw(SpriteBatch spriteBatch)

 {

 spriteBatch.Draw(image, destRect, sourceRect, Color);

 }

public override void HandleInput(PlayerIndex playerIndex)

 {

 }

 #endregion

 #region Picture Box Methods//为新的图片框设定位置

public void SetPosition(Vector2 newPosition)

 {

 destRect = new Rectangle(

 (int)newPosition.X,

 (int)newPosition.Y,

 sourceRect.Width,

 sourceRect.Height);

 }

 #endregion

 }

}

PictureBox控件需要加载图片,在EyesOfTheDragonContent目录下添加一个新的文件夹GUI,将leftarrowUp.png,rightarrowUp.png,StopBar.png三幅图片加入以便用于图片控件的调用

接下来就是最后一个任务,将PictureBox控件添加到StartMenuGreen.cs中来完善该页面,具体代码如下

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 Microsoft.Xna.Framework.Content;

using XRpgLibrary;

using XRpgLibrary.Controls;

namespace EyesOfTheDragon.GameScreens

{

public class StartMenuScreen : BaseGameState

 {

 #region Field region

PictureBox backgroundImage;//页面中的背景图片

PictureBox arrowImage;//页面中的箭头图标

LinkLabel startGame;//三个选项,开始游戏,登陆游戏,结束游戏

LinkLabel loadGame;

LinkLabel exitGame;

float maxItemWidth = 0f;//用来控制箭头图标显示位置

 #endregion

 #region Property Region

 #endregion

 #region Constructor Region

public StartMenuScreen(Game game, GameStateManager manager)

 : base(game, manager)

 {

 }

 #endregion

 #region XNA Method Region

public override void Initialize()

 {

base.Initialize();

 }

protected override void LoadContent()

 {

base.LoadContent();//要先调用基类的登陆函数,这样就实例化了ControlManager对象

ContentManager Content = Game.Content; //
backgroundImage = new PictureBox( Content.Load<Texture2D>(@"Backgrounds\titlescreen"), GameRef.ScreenRectangle);//实例化背景图片框并加入到控件管理对象中 ControlManager.Add(backgroundImage); Texture2D arrowTexture = Content.Load<Texture2D>(@"GUI\leftarrowUp"); arrowImage = new PictureBox( arrowTexture, new Rectangle( 0, 0, arrowTexture.Width, arrowTexture.Height)); ControlManager.Add(arrowImage);//实例化箭头图片框并加入到控件管理对象中 startGame = new LinkLabel(); startGame.Text = "The story begins"; startGame.Size = startGame.SpriteFont.MeasureString(startGame.Text); startGame.Selected +=new EventHandler(menuItem_Selected); ControlManager.Add(startGame); loadGame = new LinkLabel(); loadGame.Text = "The story continues"; loadGame.Size = loadGame.SpriteFont.MeasureString(loadGame.Text); loadGame.Selected += menuItem_Selected; ControlManager.Add(loadGame); exitGame = new LinkLabel(); exitGame.Text = "The story ends"; exitGame.Size = exitGame.SpriteFont.MeasureString(exitGame.Text); exitGame.Selected += menuItem_Selected; ControlManager.Add(exitGame);//在控件管理类中添加三个选择按键 ControlManager.NextControl(); ControlManager.FocusChanged += new EventHandler(ControlManager_FocusChanged);//订阅焦点改变事件 Vector2 position = new Vector2(350, 500);//定义选择按键的起始位置
//遍历控件管理类中的所有控件
foreach (Control c in ControlManager) { if (c is LinkLabel) {
//如果是LinkLabel控件,就在起始位置上向下排列放置
if (c.Size.X > maxItemWidth) maxItemWidth = c.Size.X; c.Position = position; position.Y += c.Size.Y + 5f; } } ControlManager_FocusChanged(startGame, null);//触发事件,起始状态为箭头出现在startGame按键旁 } void ControlManager_FocusChanged(object sender, EventArgs e)//聚焦改变事件,为箭头标记重绘显示位置 { Control control = sender as Control; Vector2 position = new Vector2(control.Position.X + maxItemWidth + 10f, control.Position.Y); arrowImage.SetPosition(position); } private void menuItem_Selected(object sender, EventArgs e) {
//按键选中事件触发,如果选中startGame或者loadGame按键,跳转到GamePlayScreen页面
if (sender == startGame) { StateManager.PushState(GameRef.GamePlayScreen); } if (sender == loadGame) { StateManager.PushState(GameRef.GamePlayScreen); }
//如果选中的是exitGame按键,跳出游戏
if (sender == exitGame) { GameRef.Exit(); } } public override void Update(GameTime gameTime) { ControlManager.Update(gameTime, playerIndexInControl); base.Update(gameTime); } public override void Draw(GameTime gameTime) { GameRef.SpriteBatch.Begin(); base.Draw(gameTime); ControlManager.Draw(GameRef.SpriteBatch); GameRef.SpriteBatch.End(); } #endregion #region Game State Method Region #endregion } }

OK,今天任务结束

 

你可能感兴趣的:(游戏开发)