35名太空侵略者——实时和模拟

本节说明了如何使用Fudget系统编写实时互动游戏。这表明Fudgets GUI工具包并不局限于传统的、相当静态的图形用户接口,但也允许您使用许多动画对象。通过构建一个并发程序每个动画对象的进程(一个fudget)程序可以被视为模拟一些真实世界对象及其方式的模型沟通。

35.1太空侵略者

我们首先简要介绍经典游戏Space入侵者。只有游戏中最基本的部分实际实施。

图94。太空侵略者——一款典型的交互式实时游戏。

在这个游戏中,来自外太空的入侵者军队接近地球。球员必须把他们全部击倒在他们到达水面之前。一些点被添加到被击落的入侵者的得分。玩家控制枪,枪可以在底部水平移动屏幕(地球表面)和可以点火的屏幕垂直方向。入侵者最初从左向右移动。什么时候?最右边的入侵者到达屏幕的右边入侵者先向下移动一小段距离,然后移动再次水平移动,直到最左边的入侵者到达左边边缘等。

35.2 Space-Invaders实施结构

在本节中,我们描述了Space的实现入侵者,其中每个对象都被实现为一个fudget。这个对象是:
  1. 空格F:太空软糖。这是中的黑色背景所有其他物体都在周围移动。
  2. 炮火:枪。
  3. 鱼雷:枪发射的鱼雷。
  4. 入侵者F:大量入侵者
还有分数F,它显示当前分数和得分很高。炮火鱼雷在内部使用计时器控制他们运动的速度。要协调入侵者,他们被一个位于在一个叫速度F还有一个摘要fudget呼叫呼喊声SP,用于广播定时器警报和其他输入到所有入侵者。

第35.2条说明了软糖是如何相互连接的。这个信息流如下:空间控件输出鼠标和键盘事件炮火。(这允许用户放置鼠标指针指向窗口中的任何位置以控制枪。)这个枪通过启动或停止运动来响应这些事件,或发射鱼雷。当枪开火时,它会输出鱼雷假目标的当前位置。鱼雷随后启动从那个位置向上移动。当它碰到什么东西时向入侵者输出其当前位置。那么每一个入侵者检查命中是否在屏幕上占据的区域内如果是这样,它会移除窗口并死亡。

图95:。过程及其互连Space-Invaders实现。

下面,我们进一步了解入侵者F。其他软糖是只是主题上的变化,所以我们不会进一步讨论。

软糖入侵者F保持由以下部分:当前位置(a),电流方向(左或右),如果该转弯(即移动在下一次计时器报警时向下,然后改变方向)。

入侵者使用以下语言:

数据入侵者消息=滴答|回合|生命值|死亡(智力,智力)
当入侵者听到勾选,它在电流中移动了一步方向。它还检查是否已到达边缘,其中如果它输出转弯它被所有入侵者接收。入侵者听到转弯它记得是时候在下一个勾选.当鱼雷击中某个位置时第页,全部入侵者收到点击第页,并检查第页在他们的屏幕内区域。如果是,则输出死亡n个,其中n个侵略者的身份。此身份由以下人员记录呼喊声SP,这样它就不必大喊大叫了向死去的侵略者致敬。它还用于确定点数增加分数。

事实上,所有对象都是作为组fudget实现的,这意味着每个对象有自己的X窗口。要移动对象,请移动其窗口。需要输出绘图命令。

鱼雷如何知道它是否击中了什么东西?鱼雷是一个在所有其他窗口后面移动的窗口。这意味着当它碰到什么东西时会变得模糊。X服务器发送一个可见性通知事件发生时。这导致鱼雷停止并将其当前位置发送至侵略者。(干得不错,不是吗?但时间不是有问题吗?如果鱼雷被其他应用遮住了怎么办窗户?我们让读者来思考这一点。)

35.3关于Space-Invaders实施的效率

Fudget系统的一个主要点(和功能一般编程)是为了简化和加速程序发展。当然,同样重要的是结果程序的效率是可以接受的。

我们已经测量了Space-Invader的CPU时间消耗上述实现在中的Sparcstation IPX上运行55名入侵者每秒移动两次的情况下,枪支和鱼雷每隔30毫秒移动一次。平均CPU负载为大约60%。其中10%被X服务器消耗掉了。作为比较,程序辛瓦德斯,实现了一个C程序直接在Xlib之上,在类似的情况。

像往常一样,在更高抽象级别上编程会导致效率较低的解决方案。效率低下的部分原因是使用Haskell和Fudget系统。X服务器上的负载来自这样一个事实,即移动对象表示为窗户。毫不奇怪,移动窗口的成本更高操作,而不仅仅是绘制相同大小的图像。但使用在下一节中概述的技术,可以重写Fudget程序以在单个窗口中绘制,如C程序,并且仍然保持相同的良好程序结构,即。,每个移动对象一个进程。

上面,我们比较了高级实现的效率(使用Fudget系统)的低级别游戏实施。比较其他用户也很有趣界面工具包,例如Motif和访谈系统。

上面的CPU时间消耗数据并没有说明什么这两种实现的实时行为。事实是C程序符合实时截止日期,但Fudget程序没有。作为对勾选速度F,全部55侵略者应该前进一步。计算和输出55移动窗口不幸的是,命令耗时超过30毫秒,这意味着移动窗口枪和鱼雷输出太晚,导致抖动运动。这个问题至少可以用两种不同的方法来解决方法:手动,不同时移动所有55名入侵者因此,在超过30毫秒;自动(从应用程序的角度程序员),通过引入并行评估和某种公平、不确定地合并来自不同领域的输出软糖。后一种解决方案当然是更一般的解决方案,我们希望在这个方向上改进Fudget系统。

35.4用流处理器取代软糖以提高效率

上面,我们概述了一个程序结构,其中每个移动对象屏幕上显示为带有关联窗口的fudget在屏幕上。当然,也可以将软糖用于其他对象与用户不对应的模拟类型界面元素。

单个fudget的行为通常实现为使用流处理器操作符的顺序程序putSP,获取SP零SP.提高我们空间的效率入侵者实现,我们可以改为将程序结构为一种通过以下成分描述其行为的软糖流处理器。这从两个方面提高了效率:

第35.2条入侵者的信息被广播给所有入侵者。我们使用列表F(标记为平行组合)和单独的流处理器呼喊声SP.一些使用无标记的并行组合可以避免开销的流处理器:

-*-::服务提供商a b->服务提供商a b->服务提供商a b
这也使得编写流处理器变得容易动态拆分为两个或多个并行进程。什么之中的一个并行组合中的进程可以在没有留下任何开销,因为

零SP-*-服务提供商==服务提供商-*-零SP==服务提供商
对表示为fudgets的流程执行相同操作不会为您提供与低级别相同的效率优势流即使在未标记的并行中也保持标记成分。因此,当一个过程处于平行合成时终止时,将保留一些标记开销。

平行组合可以简化为零SP让我们有机会利用序列合成运算符seqSP(第16.4条)在中有趣的方式。假设启动新级别所需的一切游戏中是创建一支新的侵略者军队。然后游戏的行为可以通过以下方式编程:

playGameSP=播放级别SP 1playLevelSP级别=startNewLevelSP级`seqSP`playLevleSP(级别+1)startNewLevelSP级别=入侵者军队SP级别入侵者军队SP等级=。。。--创造了入侵者的平行组合
当侵略者军队中最后一个入侵者死亡时成分将减少到零SP,这导致seqSP调用下一级。