Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Oop 这可以在状态机模式中建模吗?_Oop_Design Patterns - Fatal编程技术网

Oop 这可以在状态机模式中建模吗?

Oop 这可以在状态机模式中建模吗?,oop,design-patterns,Oop,Design Patterns,我想使用涉及以下状态的状态机设计模式对游戏进行建模(出于实践原因): 初始:游戏主机使用一些配置参数设置游戏 发布:游戏对其他玩家可见,以便他们可以加入 准备就绪:游戏一满(达到最大玩家数),主人就可以开始游戏了 跑步:游戏开始了 完成:游戏结束,玩家可以看到一些关于游戏的统计数据 然而,在阅读了状态机模式之后,我觉得它只适用于所有状态都公开公共接口的情况(例如本文中的handleInput-方法:) 我打算让游戏在初始状态下有一个publish方法,该方法将引导它进入Published状态

我想使用涉及以下状态的状态机设计模式对游戏进行建模(出于实践原因):

  • 初始:游戏主机使用一些配置参数设置游戏
  • 发布:游戏对其他玩家可见,以便他们可以加入
  • 准备就绪:游戏一满(达到最大玩家数),主人就可以开始游戏了
  • 跑步:游戏开始了
  • 完成:游戏结束,玩家可以看到一些关于游戏的统计数据
然而,在阅读了状态机模式之后,我觉得它只适用于所有状态都公开公共接口的情况(例如本文中的
handleInput
-方法:)

我打算让游戏在初始状态下有一个
publish
方法,该方法将引导它进入
Published
状态,然后它有一个
join
方法,一旦有足够的玩家加入,该方法将引导它进入
Ready
,以此类推

这里的目标是分离关注点,我不希望一个庞大的
游戏
类必须处理收集所有玩家以及处理实际游戏逻辑


这可以通过状态机实现吗?或者有没有其他设计模式可以用于此?

声明
公开了一个通用界面,但这与您的实际游戏无关

最低要求是拥有一组从一个
状态到下一个
状态的
转换
,以及一种基于上一个
状态
转换
创建结果
状态的机制。公共接口仅处理这一方面

对于初始的
状态
,主机在
GameConfig
对象上设置一些值。按下“发布”按钮即转换到下一个状态。在转换处理程序上,您需要创建一个
GameLobble
对象

GameLobby
是使用游戏名称和预期玩家数量创建的,严格处理添加玩家和其他与大厅相关的功能(如玩家聊天,也应该在他们自己的类中实现)

在这里,每次玩家加入大厅时都会调用转换处理程序。只有当玩家总数达到时,你才能转换到下一个状态“游戏准备就绪”。(如果游戏数量还不满足要求,如果您想保持不变,可以使用一个额外的玩家转换到一个新的
GameLobby
对象。)

GameConfig
对象一起,这个新状态包含
Player
对象的列表

从该状态开始,当主机单击“就绪”时,在转换处理程序中,您最终根据
GameConfig
对象和
Player
对象列表创建
GameLogic
对象

当游戏获胜时,您将过渡到包含游戏统计信息的“完成”状态,并最终过渡到“结束程序”

这些主要状态中的每一个都可以包含它们自己的状态机

因此,与状态机相关的接口不会限制有效负载的接口


我还建议您将与在屏幕上显示项目相关的部分与确定显示“内容”的部分分开。因此,这些状态对象中的每一个都有类似于
Init
的方法,它们在其中生成需要显示的
sprite
列表(并附加转换所需的任何事件处理程序)。然后,一个单独的对象将获取该列表并将其显示在屏幕上,并在用户输入时调用偶数处理程序。

您的状态逻辑似乎非常线性。也就是说,您没有可以在初始状态下启动并进入运行状态的奇怪情况。当您有复杂的状态转换逻辑时,它可能会导致单一情况或if/then块来决定如何处理转换。州模式是一种更干净的选择。既然你没有那么复杂,我认为状态模式太过分了。如果OP想要实践状态模式,我想这是可以的。但我看不到增加状态模式复杂性的好处。由于状态转换看起来是线性的,所以您可以使用枚举变量GAME_state,并在每个阶段将其推进。代码更少,更容易理解。接吻也是一种模式。这里有很多关于游戏中更复杂状态的例子,使用状态模式可能更好:@Fuhrmanator“简单”的定义常常随着项目的进展而变化。没有一个项目是没有范围蠕变的,即使是实践项目也是如此。这种模式在使将来的更改更容易的同时,也迫使您组织项目并分离责任。这反过来又增加了项目成功的几率。你熟悉吗?在状态图中对状态进行建模没有错。