0

我正在尝试为自己的学习编写游戏,但遇到了一个让我脑筋急转弯的设计问题。这是一个相当简单的回合制游戏,玩家拥有自己的状态、物品栏和拥有状态的家;理想情况下,我想在世界其他地方添加一些有状态的元素。

我试图向玩家展示他们可以随时使用的选项。我已经尝试在游戏流程控制中创建每个选项,但它变得无法管理,所以我现在正在尝试使用更好的设计。我的第一个想法是有一个 Action 类,它的每个实例都编码了某种状态测试。这样我就可以在一个大的配置文件中定义可能的操作,当向用户展示选项时,我可以迭代 Action.available 测试并呈现返回 true 的测试。

#obligatory pseudopython
class Action:
    def __init__ (self, available_test, other_args):
        #available is a function passed in, or perhaps some SQL query
        self.available = available_test

....
for a in action_array:
    if a.available():
    #or maybe if test_handler(a.available)
        options.append(a.option)

gui.show_menu(options)

这样做的问题似乎是 Action 对象(或者可能是处理程序)需要全局访问所有游戏状态才能查看它们是否可以执行。这立即在我的脑海中升起了警告标志,但我看不到绕过它的方法。拥有一个拥有所有访问权限的处理程序听起来并没有那么糟糕,但这引发了如何指定测试的问题,除非我将所有数据放入数据库并用 SQL 编写测试。但是,如果我这样做,我将绕过整个程序中的每个数据访问方法,这似乎也违背了良好的设计。

我的想法做错了什么?有更好的方法吗?我并不特别喜欢这种做事方式,我在这个版本中没有写太多代码,我很高兴从头开始(已经这样做过一次)。我正在仔细研究借来的 Code Complete 副本,试图给我一些想法,但是虽然这一切听起来很扎实,但我仍然在摸索到底要做什么

明确一点:我正在设计同时存储状态的方式;我希望 Action 系统和状态存储能够和谐地协同工作。在某种程度上,我想围绕通过 Actions 进行的健壮但简单的访问来设计状态管理。我正在用 Python 写作,但目的是学习一般的良好软件设计技能,所以我更喜欢非语言特定的答案。

4

1 回答 1

1

我同意走向全球并不是一条出路。此外,通过在每个可能的对象上添加每个可能的动作来使游戏角色的定义膨胀也是不好的。但是,我认为使用 Action 对象也不是正确的组织方式。除了动作适用的对象之外,动作通常没有意义。你可以解锁一把锁,但不能解锁一块石头。

另外,如果你有一个角色在不同的位置四处走动,你可能有一种方法可以让每个位置都提供有关该位置中存在的对象的信息。对于可移动的对象,位置可以变为“在人身上”,您可能有办法为角色请求库存,这将提供对象列表。

我建议组织动作的最简洁的方法是让每个 ActionableObject 知道可以对其执行哪些操作或使用它执行哪些操作,包括了解每个操作的要求。对于本地的每个对象,或者对于一个人库存中的任何对象,角色应该有可能通过对对象本身的请求获得可以在该对象上/对该对象执行的操作。

功能 WhatActionsCouldIDo

输入包括

  1. 发出请求的角色(通​​常是玩家角色,但如果你有运行 AI 的 NPC,最终可能是非玩家角色)
  2. 当前位置,除非您始终在对象本身内维护当前位置信息

输出是可以对该对象执行或使用该对象执行的可能操作的列表。

在内部,对象将考虑其每个可能定义的动作并执行一个函数来检查该动作的要求是否得到满足,给定(作为输入)角色和位置。通过 character 参数,该函数可以调查角色的属性(例如,他是否足够强壮并且没有足够的负担来举起我?他的清单中是否有使我完整的缺失部分?我是否在正确的位置进行操作?是可能的(这可能与尝试的行为是否会产生任何影响不同)?等)

如果满足要求,则检查函数将返回 true,并将操作添加到将作为输出返回的操作列表中。

同样,该对象还将提供执行所选操作的功能。

功能 DoAction

输入包括

  1. 选择的动作(来自先前获得的列表)
  2. 发出请求的角色(通​​常是玩家角色,但如果你有运行 AI 的 NPC,最终可能是非玩家角色)
  3. 当前位置,除非您始终在对象本身内维护当前位置信息

即使进行了需求检查以获取操作列表,最安全的方法是再次检查需求是否仍然得到满足。如果它们是,对象调用一个函数来执行动作。

请注意,在此设计中,当请求一个动作时,对象将操纵角色和环境的状态,这乍一看可能很奇怪。然而,这是对角色选择执行动作的响应,从而产生动作对角色或环境的影响对象通过提供所有要求的必要内部知识(包括那些不明显的要求)和导致所有效果作为结果发生的能力(包括角色可能不知道或不打算的微妙效果,例如触发一些陷阱或对角色产生非广告效果)。

这种安排应该允许保持角色对象本身非常干净和精简,只需要公开接口以允许对其状态进行所需的更改,例如在其库存中添加一些东西,增强或削弱一个属性等。

这种安排还允许您更自由地添加具有您最初没有预料到的可能动作和效果的新对象。通常,需要添加的所有内容都可以放置在新对象类型本身中,使用角色和环境位置的现有接口。为了最大限度地提高这一点,我建议使用通用术语来表达动作列表,例如使用整数和/或文本的组合。角色类别不应该依赖于对所有可能的对象或所有可能的动作的认识。它只是在通用级别进行交互,为用户提供足够的信息以供选择。

(另一方面,如果你想添加使用 AI 的 NPC 并且需要了解不同的行为以制定策略,则可能需要采用修改后的方法。这条路径往往会导致更受限制的与上述设计的无限可能性形成对比的可能性。)

于 2014-10-02T12:31:55.403 回答