2. 推进游戏
我们还要对Advance方法进行重写。在该方法中,要检测游戏中的每个对象来查看其位置是否发生了移动或是发生了其他状况,从而需要对对象进行重绘。其原因也将在第4.4节中进行介绍。
4.2.5 CGameFunctions类
下面对CGameFunctions类进行介绍:
● 目的 为游戏引擎项目提供实用函数。
● 类型 包含了静态成员的内部类。
● 父类 没有父类。
● 子类 没有继承的子类。
● 主要功能
● IsSmartphone 标识设备是触摸屏设备还是smart phone设备。
● CombineRectangles 帮助我们操纵矩形区域。
游戏引擎所包含的最后一个类是CGameFunctions,它为引擎提供了不同的工具函数。该类为内部类,所以在引擎程序集之外看不到它。该类的构造函数为私有的,所以无法创建其实例:该类中所有的函数都是statics的,所以不需要创建对象实例就可以调用它。
我们将在该类中构建一些额外的功能,以在后面章节中增强引擎。但是现在只实现两个函数:
● IsSmartphone 就像第2章中所介绍的那样,该函数用于判断设备是一个触摸屏设备还是一个smart phone设备。
● CombineRectangles 此函数以两个Rectangle对象作为参数,并返回一个恰好能容纳下这两个矩形的Rectangle。它实际上是对Rectangle.Union方法进行了包装,但它将空矩形(将Top、Left、Width及Height全部设置为0)作为特例,并将其排除在外。
这样,游戏引擎的雏形就完成了——还好,这不太费力。接下来,我们将简单地将引擎应用到一个游戏中。
4.3 使用游戏引擎
我们在一个单独的项目中来构建游戏,通过对游戏引擎项目或对其DLL进行引用来访问游戏引擎类。
游戏项目中将包含一个game类,它继承于CGameEngineGDIBase类,我们将控制游戏本身整体流程的代码放到该类中。
我们还将添加一些Object类,用于代表游戏中的对象(分别是星球、导弹、外星人等)。game类可以将这些类的实例添加到游戏中。
最后要在一个.NET CF窗体中实现游戏,在该窗体中需要一点代码,其中大部分是相似的,并且很简单:
● 在窗体的构造函数中,对已经定义在游戏项目中的game类进行实例化,将窗体本身作为一个参数进行引用。
● 对OnPaintBackgroud方法进行重写,正如前面所讨论的。
● 为Paint事件添加处理程序,在其中调用game类的Present方法,用于将后台缓冲区显示在屏幕上。
● 创建一个游戏循环,来重复更新游戏。在循环中将调用game类的Advance函数。
稍后我们将对该循环进行详解。
目前来看,外部程序调用引擎本身看起来还是非常简单的!
创建弹球示例游戏
接下来,我们用游戏引擎来构建一个示例项目。我们将创建一个小球,小球能在游戏的窗口中到处反弹。与上一章中创建的移动方块比较相像,但这里将模拟重力,所以小球在降落到窗口的底部的过程中会加速。
Bounce项目是一个单独的程序集,项目中添加了对GameEngineCh4的引用(本章中所构建的游戏引擎版本)。在提供的项目中已经添加了该引用。也可以在Solution Explorer窗口中,右击游戏项目中的References节点,然后选择Add Reference选项(在VB.NET中,双击My Project节点,选择References选项卡,然后单击Add按钮)自行添加引用。如果游戏引擎项目包含在同一个解决方案中,那么单击Projects选项卡在其中选择游戏引擎项目;否则,就在Browse选项卡中定位编译后的DLL。这样就可以在游戏项目中使用该游戏引擎了。
Bounce项目包含了一个用于显示游戏输出的窗体,以及两个用于运行游戏的类(一个从GameEngineCh4.CGameEngineGDIBase继承,另一个从CGameObjectGDIBase继承)。在本书配套下载代码的4_1_Bounce目录中可以找到该项目。
1. CbounceGame类
首先要创建游戏引擎。这将在CbounceGame类中实现,该类从游戏引擎的CgameEngine-
GDIBase类中继承。除了其构造函数之外,它只有两个函数,即Prepare函数和Reset函数的重写。程序清单4-8展示了Prepare函数中的代码。
程序清单4-8 Bounce 游戏的Prepare函数
/// <summary>
/// Prepare the game
/// </summary>
public override void Prepare()
{
Assembly asm;
// Allow the base class to do its work
base.Prepare();
// Initialise graphics library
if (GameGraphics.Count == 0)
{
asm = Assembly.GetExecutingAssembly();
GameGraphics.Add("Ball",
new Bitmap(asm.GetManifestResourceStream("Bounce.Graphics.Ball. png")));
}
}