§5.3 插入更多游戏组件

甚至在你注意到你的图像引擎已经成长为一个惊人的尺寸之前,你立刻拥有了大量的有用的类,这些类帮助你渲染2D和3D数据相当容易,就如你所见在大多数类中可以得到许多单元测试(如图5-14)。

图5-14

到现在为止你还没有用过许多游戏组件,并且在你看来用组件编写图像引擎没有太重大的意义。你没有用任何Update 方法,或 Draw 方法,而游戏组件这种方式用到了。OK,Model 类使用了一个 Render方法,Input 类有一个 Update方法,不过除了you did not have any functionality that is compatible with game components。在model中的Render 方法和texture中的Render 方法工作完全不相同因为它们期待用户以不同的值调用它们,并且每一帧非常频繁的调用。我猜 Input 类可以被修改为一个游戏组件,不过我对这个主意并不非常兴奋。

取代我们考虑组件,哪一个更合适于游戏组件模型。如果你有一个类需要每一帧都被更新和绘制,那就有意义。这种类的范例可能是每秒帧的计数器或者摄像机类,你的引擎仍然缺少这个类。

简单的照相机类Simple Camera Class

对于你的单元测试,你不需要一个复杂的摄像机,不过它能四处移动一点,并且在你的引擎单元测试中对你渲染的对象有一个简单的3D观测就不错了。在view matrix 和 Matrix.CreateLookAt 方法的帮助下,你轻易就能创建上述功能,并且把它设置在任何你需要的地方。使用一个游戏组件类自动去做所有这些甚至更好;你必须去做的所有事是在YourGame 类的构造器中创建一个camera 类的实例,YourGame 类继承自BaseGame 类,并且不用额外的代码,所有的单元测试和其他3D代码突然将使用这个新的camera 类,因为对于YourGame 类中拥有的每一个游戏组件,Update方法被你自动调用。

public YourGame() {

// Init simple camera

this.Components.Add(new SimpleCamera(this));

} // YourGame()

SimpleCamera 类有一个构造器、 一个Initialize 方法和Update方法,这两者也都被自动调用。对于摄像机的X、Y、Z位置也有3个字段成员变量,它被初始化为 (0, 0, 15)。然后Update方法基于鼠标的移动改变 x 和 y ,或者如果你有一个gamepad,给予正确的操纵杆移动。此外,你能用左thumb stick放大缩小。

这个类相当简单,易于阅读整个代码:

/// <summary>

/// Simple camera class just to move around a little.

/// Always focuses on the center and uses the same height.

 /// </summary>

class SimpleCamera : GameComponent {

#region Variables

float x = 0, y = 0;

 float zHeight = 15.0f;

#endregion

#region Constructor

public SimpleCamera(BaseGame game) : base(game)

{

}

 // SimpleCamera(game)

#endregion

#region Initialize

public override void Initialize() {

 base.Initialize();

} // Initialize

 #endregion

#region Update

public override void Update(GameTime gameTime) {

base.Update(gameTime);

// Update camera position (allow mouse and gamepad)

x += Input.MouseXMovement / 10;

y += Input.MouseYMovement / 10;

 x += Input.GamePad.ThumbSticks.Right.X;

y += Input.GamePad.ThumbSticks.Right.Y;

zHeight += Input.GamePad.ThumbSticks.Left.Y;

BaseGame.ViewMatrix = Matrix.CreateLookAt( new Vector3(x, y, zHeight), Vector3.Zero, Vector3.Up);

} // Update(gameTime)

#endregion

} // class SimpleCamera

这里重要的一件事是来自于BaseGame类的ViewMatrix,它在Update 方法的末尾被设置。在model类或者在任何其他诸如line manager中渲染shader的时候,你将使用这个view matrix 并且确定你所有的 3D 数据被转换到你的view space with this exact matrix 直到你在下一帧再次修改它。

对于你在本章开始编写的TestRenderOurNewGraphicEngine 测试,现在你一起拥有一切,如果你朝项目中的所有导入的和编写的类看一看,它一个既易于使用也能够扩展的相当好的引擎,你将在下一章探索这些。

ScreenshotCapturer类

在引擎中还有另一个辅助类叫做ScreenshotCapturer,它允许你使用Print-Screen 键抓取屏幕快照。它也被作为一个游戏组件实现,并且被BaseGame 构造器初始化。Update 方法被自动地调用,如果用户正好按了Print-Screen 键就调用MakeScreenshot方法 :

public override void Update(GameTime gameTime)

{

if (Input.KeyboardKeyJustPressed(Keys.PrintScreen))

MakeScreenshot();

base.Update(gameTime);

} // Update(gameTime)

MakeScreenshot 方法创建一个临时的texture 纹理,并且在device的ResolveBackBuffer方法的帮助下保存back buffer。然后借助于类中的某些其它辅助方法,最终结果被保存到磁盘:

using (Texture2D dstTexture = new Texture2D( BaseGame.Device, BaseGame.Width, BaseGame.Height, 1, ResourceUsage.ResolveTarget, SurfaceFormat.Color, ResourceManagementMode.Manual))

{

// Get data with help of the resolve method

BaseGame.Device.ResolveBackBuffer(dstTexture);

dstTexture.Save( ScreenshotNameBuilder(screenshotNum), ImageFileFormat.Jpg);

} // using (dstTexture)


发布时间:2008/8/30 下午3:16:55  阅读次数:6173

2006 - 2024,推荐分辨率 1024*768 以上,推荐浏览器 Chrome、Edge 等现代浏览器,截止 2021 年 12 月 5 日的访问次数:1872 万 9823 站长邮箱

沪 ICP 备 18037240 号-1

沪公网安备 31011002002865 号