开发游戏引擎(9)

 

4.2.4  CGameEngineGDIBase类

下面对CGameEngineGDIBase类进行概要的介绍:

● 目的  一个CGameEngineBase类的实现,提供GDI图形所需的功能。

● 类型  抽象基类。

● 父类  CgameEngineBase。

● 子类  各个游戏,创建在独立的程序集中。

● 主要功能

● Prepare  为执行GDI渲染做好准备。

● Render  提供有效的图形渲染技术。

● Present  将生成好的图形显示到屏幕上。

抽象引擎对象与抽象游戏对象都已经就位了,现在要为GDI绘制引擎添加功能。CGameEngineGDIBase类仍然被声明为abstract,但实际的游戏类将从它继承而来。

该类附加函数中最有意义的是Render方法。我们来看看该方法以及这里实现方式上的区别。

1. 渲染

每个对象需要对后台缓冲区进行更新时,都会使用Render函数。我们要进行许多需要的操作:

● 如果后台缓冲区尚未执行初始化,则进行初始化。

● 清空背景。

● 向后台缓冲区中绘制所有对象。

● 使游戏窗体失效,触发一个Paint事件,这样我们就可以将修改了的后台缓冲区复制到窗体中。

我们首先来讨论后台缓冲区,正如上一章中所述,这是一个不显示在屏幕上的Bitmap对象,我们将在其中绘制所有的图形对象。它通常维护的是当前要显示的游戏内容的图形。在Render函数的开始阶段,如果对象尚未可用,就会调用InitBackBuffer来对缓冲区进行准备。在本例中,图形后台缓冲区的大小与游戏窗体的大小一致,如程序清单4-7所示。

程序清单4-7  对后台缓冲区进行初始化

/// <summary>

/// If not already ready, creates and initialises the back buffer that we

/// use for off-screen rendering.

/// </summary>

private void InitBackBuffer()

{

// Make a new back buffer if needed.

if (_backBuffer == null)

{

_backBuffer = new Bitmap(GameForm.ClientSize.Width, GameForm.ClientSize.Height);

// Ensure we repaint the whole form

ForceRepaint();

}

}

下一步,清空背景。这里有两种可能的方法:将背景改为纯色,或者在移动的图形背后显示一个背景图像。

如果没有图像,那么调用CreateBackgroundImage函数,该函数为虚函数,继承游戏类可以对它进行重写。如果需要背景图片,可以返回一个包含了背景图片的Bitmap对象。然后在绘制图形之前调用该函数来清空后台缓冲区。

另一方面,如果调用了该函数之后还是没有背景图像,那么游戏会用一个纯色来清除后台缓冲区。通过对象的BackgroundColor属性来指定该颜色。

第三步是将所有的对象都绘制到后台缓冲区中。这里先跳过这一步骤的细节,因为我们马上要在第4.4节中对它进行深入的介绍。可以这样说:所有需要重绘的对象都会在后台缓冲区中绘制好。

最后,我们调用窗体的Invalidate方法来触发重绘事件。就是靠这种机制,将修改后的后台缓冲区中的内容绘制到屏幕上,这样才能被人们看到。当该事件被触发时,通过传递窗体的Graphics实例,在CGameEngineGDIBase.Present方法中会对窗体进行调用。我们很快就会看到窗体是如何与引擎相联系的。

读书导航