在动态创建的菜单中避免全局状态

时间:2014-03-27 08:58:14

标签: architecture state software-design state-management

我正在尝试为自己的学习编写游戏,我遇到了一个破坏我大脑的设计问题。这是一个相当简单的回合制游戏,玩家拥有自己的状态,库存和所有状态的家庭;理想情况下,我想在世界其他地方添加一些有状态元素。

我正试图向玩家展示他们随时可以使用的选项。我已经尝试在游戏流程控制中创建每个选项,但它变得无法管理,所以我现在尝试使用更好的设计。我的第一个想法是拥有一个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编写,但目的是为了学习一般的软件设计技能,所以我稍微倾向于非语言特定的答案。

1 个答案:

答案 0 :(得分:0)

我同意走向全球不是一条路。另外,通过在每个可能的对象上添加内部的每个可能的操作来膨胀播放字符的定义是不好的。但是,我不认为使用Action对象是正确的组织方式。除了适用该动作的对象之外,动作通常没有意义。你可以解锁,但不能解锁。

另外,如果你有一个角色在不同的位置移动,你可能有办法让每个位置提供有关该位置存在的对象的信息。对于可移动的物体,位置可以变成人物上的#34;并且您可能有办法为角色请求库存,这将提供对象列表。

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

功能WhatActionsCouldIDo

输入包括

  1. 发出请求的角色(通​​常是玩家角色,但是 如果你有NPC运行,最终可能是一个非玩家角色 与AI)
  2. 当前位置,除非您始终在对象本身内维护当前位置信息
  3. 输出是可以对该对象执行或与该对象一起执行的可能操作的列表。

    在对象内部,对象将考虑其可能定义的每个动作,并执行一个函数来检查是否满足该动作的要求,给定(作为输入)角色和位置。通过角色参数,该函数可以调查角色的属性(例如,他是否足够强大并且没有足够的负担来抬起我?他是否有缺少的部分在我的库存中完成我?我是否在适当的位置进行操作是可能(可能与尝试的行动是否有任何影响不同)?等等。)

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

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

    功能DoAction

    输入包括

    1. 所选行动(来自之前获得的名单)
    2. 发出请求的角色(通​​常是玩家角色,但是 如果你有NPC运行,最终可能是一个非玩家角色 与AI)
    3. 当前位置,除非您始终在对象本身内维护当前位置信息
    4. 即使已完成需求检查以获取操作列表,但最安全的方法是再次检查是否仍满足要求。如果它们是,则该对象调用一个函数来执行该操作。

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

      这种安排应该允许保持角色对象本身非常干净和精简,仅需要暴露界面以允许对其状态的所需改变,例如,向库存添加内容,增强或削弱属性等等。

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

      (另一方面,如果您想添加使用AI的NPC并需要了解不同的操作以制定策略,您可能需要调整修改后的方法。这条路径往往会导致更多与上述设计的无限可能性形成对比,限制了可能性的范围。)