16

最近我一直在尝试用 C# 编写游戏。我没有为此使用 XNA,因为我认为如果我从头开始编写游戏代码(尽管我使用的是多媒体引擎),我会学到更多。

我正在尝试设计一个 2D RPG 游戏——我知道有点野心勃勃,但是我至少对游戏的基本部分(即“样板”代码)有相当好的理解,而且我已经达到了一部分我不知道从这里去哪里。

在 2D 游戏中,您通过在不同的“区域”中走动来完成游戏。一旦你击中了一个“门户瓷砖”,你就会被运送到下一个区域等。

我无法理解如何设置这些区域对象。这是我的第一个想法:每个区域都有几个不同的集合结构(例如,可见性四叉树、碰撞四叉树、AI 实体列表等)。因此,如果我要在游戏中添加一个敌方实体,它将被放入可见性四叉树、碰撞四叉树(因为您可以与实体发生碰撞)和 AI 实体列表中。当该区域收到更新请求时,它会告诉这些结构中的每一个进行自我更新,这反过来又告诉实体进行自我更新。一切都很好,到目前为止。

我的问题是:如果这个敌人需要与其他物体交流怎么办?例如,它可能需要知道玩家是否在它的某个范围内。或者它是否被玩家击中。或者所有可碰撞对象都在该区域中的位置(因此它可以寻路)。

这个问题的第一个(也是不好的)解决方案是简单地向每个实体传递对每个集合的引用。但这显然鼓励了紧密耦合的对象,这是不好的。

我想出的第二个解决方案是让每个实体都能够通过消息结构查询该区域。因此,敌人可以说“给我一个在我位置 X 距离内的每个实体的列表”并且该区域会返回答案。但是,这将变得越来越困难,因为我必须在该区域中编写越来越多的可能性(“给我一个不在我 X 距离内的实体的列表”,“给我一个健康状况低于X”等)。

我正在寻找的是一个经过时间考验的解决这个对象间通信问题的解决方案,基本上是如何建立一个区域。我想它也需要某种消息传递系统,尽管我不确定。

谢谢阅读。

4

4 回答 4

5

我认为这种事情的最佳选择是大量使用观察者模式......创建事件(确定另一个设计决策的通用或具体程度)并使您的对象订阅他们需要的对象。

例如,当有 2 个实体靠近时,您的引擎可以触发碰撞或接近事件,但这些事件只会被感兴趣的实体接收。您可以进行一些优化,以仅检查已订阅观察者的那些条件。

我不知道这在游戏中是否常见,而且我从未在任何游戏中实际使用过它(至今),但我已经思考了很多次,这是我最喜欢的选项。

于 2009-11-05T01:10:49.053 回答
5

您可以查看Mediator 模式。它将允许您具有低耦合,但是是的,您在中介对象中有很多代码以促进其他对象之间的通信。但我认为这是其中之一。然后这是更可取的。它还可以让您更自由地执行技巧,例如将某些更新请求排队并在更合适的时间处理请求,或者对大量请求进行批处理,而不是一个一个地处理它们,这将(假设)强加某种高架。

于 2009-11-05T01:31:20.977 回答
4

一种方法是设置客户端/服务器架构。因此服务器将处理所有游戏世界更新和内部逻辑,客户端只会询问服务器是否可以执行某些操作。然后服务器会做出响应,客户端只会绘制和更新游戏屏幕。非玩家实体也会这样做。唯一的区别是客户端是人工控制的,而其他实体是计算机控制的。这将允许您将游戏世界设置、事件和更新与实体逻辑分开。

您提到的“消息系统”称为应用程序协议,可以是复杂的深奥二进制系统,也可以是我推荐的简单的人类可读字符串。当玩家移动时,服务器将向其发送客户端可见的实体列表。非玩家实体将以相同的方式运作。即通过请求服务器允许做某事,或服务器先前在移动并进入实体视图时发送的有关另一个实体的信息,并且服务器以适当的答案或信息进行响应。

如果您要使用套接字来实现这一点,那么您将明显受益于内部网络播放,因为服务器不会关心客户端是否连接到服务器正在运行的同一台机器上,或者客户端是否跨越整个大陆。这可能没有专门用代码回答你的问题,但我希望它至少是值得深思的。

于 2009-11-05T01:59:11.933 回答
3

如果您在实体上方有一个对象进行管理,这通常会容易得多。(例如“世界”或“游戏”。)它可以很容易地看到哪些实体与其他实体接近,并相应地发送事件和通知。

如果实体在更新时需要更多的上下文来做出有意义的决定,您总是可以让世界以某种形式在该上下文中传递。但是让世界管理实体的分区和放置,而不是让实体直接担心。

(另外,为什么要使用四叉树?对于 2D rpg,粗网格可能更容易实现并且同样有用。)

于 2009-11-05T10:58:08.283 回答