博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Pocket PC 实时处理(转)
阅读量:2492 次
发布时间:2019-05-11

本文共 2720 字,大约阅读时间需要 9 分钟。

摘要:John Kennedy 在上个月的专栏中对实时时间处理进行了介绍,本文在此基础之上演示了如何创建在 Pocket PC 上显示和浏览的三维坐标系。

上个月 ,我们最后创建了一个实用、精干的类,用于管理一些要在游戏中使用的三维对象。我们甚至可以在此类中生成对象的形状,轻松地将坦克、立方体或旗帜与实例化对象的小圆片放在一起。

本月我们将了解如何使用这些对象创建可以在 Pocket PC 上显示和浏览的简单三维坐标系,我们将介绍实时时间处理以及对按键的响应,但首先简单介绍一下相对性。

一切都是相对的

我们的游戏坐标系包含玩家,玩家周围散布着对象选择集。我们先将此游戏制成二维游戏,因此您可以想象游戏是在平面上进行,如图 1 所示。

20051221173742706.gif

图 1:我们是坐标系的控制者。这是一种刺激、充满力量的感觉。

上图中的绿色区域表示玩家可以“看到”的坐标系部分,或者至少是计算机屏幕上绘制的部分。Y 轴表示每个对象的高度,由于对象不在 Y 轴方向上移动,因此我们暂时忽略 Y 轴。

我还希望您注意三个立方体(在此图中为正方形)及其相对形状。随着立方体位置的改变,立方体的形状也在改变 - 看起来好象在绕屏幕中心旋转。

还要注意尽管玩家看不到立方体 3,但它仍然存在。这一点对于我们完成游戏至关重要。当玩家移动或旋转时,我们就在坐标系中移动其他每个对象。这听起来有点不可思议,但却是可行的,这并不是说您可能会采取其他方法。在决定前请继续往下阅读。

以下是设计思想。假想您站在房间的中央,顺时针旋转 10 度。虽然您可以肯定地说您已经改变了方向,但同样也可以说房间内的其他对象(包括房间本身)改变了方向,即按逆时针方向旋转了 10 度。房间旋转和您自己旋转并没有什么区别。您和您周围对象的相对角度并没有改变。同样,您向前迈一步与您保持不动而房间内的对象向您移动,效果是一样的。正如爱因斯坦所说的,“一切都是相对的”。

在程序中,这意味着我们无须了解玩家在游戏坐标系中的绝对位置,只知道玩家与空间中其他对象的相对位置即可,这与人的直觉相悖。假定玩家始终位于坐标系的正中心,即 (0,0)。当玩家移动或旋转时,我们相应地移动或旋转现场中的所有对象,即更新用于定义所有其他对象的点的坐标。我们存储了对象相对于坐标系中心的坐标,因此通过旋转对象,可以相应地调整对象的形状和位置。

您或许会问自己,“在类中包含一个旋转对象的方法不是很方便吗”?您错了。如果您认为这是巧合,那么您跟我一样容易受骗。

也许,更明显的方法是保持所有现场对象的坐标不变,然后跟踪玩家的位置和方向。然后,在构造玩家可以看到的视图时,我们可以使用对象坐标和玩家数据来绘制调整后的视图。

现在,来看一下两种方法的优缺点。一方面,通过旋转坐标系来保存每次需要重新绘制对象时所需的所有计算。鉴于玩家随时会移动位置,我们画出已经计算出的坐标,而不计算它们的出现方式。

我们很容易想象这是对处理能力的浪费,假设玩家身后有一个复杂的对象。每次玩家移动时,此对象中的所有点都会更新,即使玩家实际上并未看到。在非常复杂的游戏坐标系中,这不一定是最好的方法。但是,由于我们的坐标系比较简单,最多只包含几百个坐标,因此这种方法比较可行。

因此,在响应玩家发出的命令而让玩家顺时针旋转时,需要依次运行每个对象,即逆时针旋转所有坐标。

其他运动

上述说明适用于相对位置不发生改变的对象。在我们的游戏中,这些对象是一些随意放在地面上的神奇立方体。然而,这还算不上是一个激动人心的游戏 - 如果再有一些其他对象充当敌人来回移动,就会收到更好的效果。

为了处理这种情况,我们需要使对象可以改变方向并向其对面的方向移动。这就需要更多的代码来使对象绕其各自的 Y 轴(而不是坐标系的中心)旋转,并更新坐标以改变位置。同样,这些方法已包含在三维类中了(查看 Spin() 及其与 Rotate() 的区别)。

计时器和按键

Microsoft Windows® 程序和 Windows CE 程序都是事件驱动的。也就是说,发生事件后导致代码执行。事件可以是选择菜单选项、点击屏幕或者按下键盘等。所有这些操作都会生成事件,然后调用一段特定代码。

也就是说,如果一个游戏在您按下按键或选择菜单项时仅更新屏幕,那它实在没有什么价值。如果程序未获取事件,则一直处于等待状态,不执行任何操作。也许这种情形适合扑克牌这样的游戏,但对于激动人心的三维游戏却行不通。

对于这种情形,有一种特殊的称为“计时器”的事件。计时器启动后,每 n 毫秒便激发一次事件,您需要定义 n。这就意味着可以创建一个计时器,每秒激发 10 次,每次激发时便重画屏幕、移动敌人对象等等。这样,即使玩家什么也不做,屏幕仍然更新。

在 C# 中创建计时器非常简单。以下是每秒激发 20 次的计时器代码。

Timer GameTimer;public 3DGame()   {   //启动游戏计时器   GameTimer = new Timer();   GameTimer.Interval = 50;   GameTimer.Tick += new EventHandler(GameLoop);   //GameTimer.Start();    // 不是小型框架的 rqd.   GameTimer.Enabled = true;   }

以下是捕捉该事件的代码,它使您可以调用所需代码:

public void GameLoop(Object sender, EventArgs e)   {      // 在此处编写代码   }

您也可以对按键事件作出响应,如下所示:

protected override void OnKeyDown(KeyEventArgs kea)   {      if (kea.KeyValue==37)   // 37 是表示向左的值      {         // 用户向左移动      }   }

或许您想立刻将用于移动、旋转或射击等的代码放入此处,但这样做的结果并不理想。标准键盘机制生成了到达 OnKeyDown 的按键事件,也就是说,由于键盘重复操作对 Pocket 有用但对游戏没有用,而使得这些代码断断续续地运行。

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/10294527/viewspace-126754/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/10294527/viewspace-126754/

你可能感兴趣的文章