- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我想使用有限状态机来处理 Entity
我的游戏中的状态。具体来说,就本文而言,我将引用 Player
实体。
我的 Player
将会有空闲、运行、跳跃、下降等状态……并且需要一些方法来管理这些状态以及它们之间的转换。在 OOP 环境中,最简单的解决方案是让每个状态都有自己的类,并有一个名为 handleInput
的方法。接受输入并确定是否应该发生状态更改。例如,在 IdleState
如果 move_right 或 move_left 发生,状态将更改为新的 RunningState
.这很容易也很有意义,因为状态的行为应该封装在状态中。
但是,当您在实体组件系统中使用 FSM 时,一切都会发生变化。状态不再是对象(因为这会违背组件系统的灵 active ),而是组件的不同排列。 JumpState
可能有 JumpComponent
之类的组件, AirbornMovementComponent
等...而 AttackState
可能包含表示攻击的组件,例如 SwingComponent
, DamageComponent
, SwordComponent
等... 这个想法是通过重新排列组件,可以创建新的状态。系统的工作是简单地分别处理这些组件,因为系统不关心状态,它们只关心单个组件。实际的 FSM 位于 FSMComponent
由该实体持有。
这很有意义,除了在处理状态转换时。现在我有一个 InputSystem
查找具有 InputComponent
的实体和 FSMComponent
并尝试根据当前输入更新 FSM 的状态。但是,这并不是那么好用。
FSM 处理输入的最佳方式(在我看来)是让每个状态确定它想要如何处理输入以及如何根据该输入转换到新状态。这又回到了实现 FSM 的 OOP 方式,与 ECS 的设计背道而驰,其中组件只是数据包,系统负责所有逻辑。在 ECS 中,想法是让系统处理状态转换,但这会变得复杂,因为每个 FSM 可能有不同的状态转换条件。
您不能简单地在 InputSystem
中声明“如果输入向右移动,则将状态设置为运行”。这将是特定于玩家的,但可能不适用于 全部 实体。如果有一天我决定让一个敌人变得可控,那么适用于 Player
的输入不会是 Enemy
的相同输入.
我的问题 : 如何让我的 FSM 在 ECS 中足够通用和足够灵活,以允许状态转换的各种实现,而不必在系统本身中进行明确的 if/else 检查?
我是否以完全错误的方式接近这个?如果是这样,在实体组件系统中实现 FSM 的更好解决方案是什么?
最佳答案
只是重复@fallaciousreasoning 的帖子(及其后续评论)。
Ash 实际上有两个在不同级别运行的 FSM。
首先,FSM 在实体级别运行,当您从一种状态转换到另一种状态时,它通过更改实体上组件的组合来管理(实体)状态转换。
其次,FSM 在引擎级别运行,通过更改引擎执行的系统的组成来管理(引擎)状态转换。
它们结合起来形成了一个非常强大的 FSM。
诀窍是确定您需要使用哪种类型的过渡;一种是“数据”组合驱动转换,一种是“逻辑”组合驱动转换。
因此,有了这些新发现的知识,我们就可以推理它是如何工作的。
在更简单的改变组件组成的方法中,我们会使用一些“标记”组件,以及一些冗长的 switch 语句(或 if/else 检查)来处理实体状态的这些变化,最终导致臃肿的系统超过他们应该的。 Ash 的实体 FSM 对此进行了改进,并通过将给定的组件配置映射到标识符并提供可用于触发状态转换的管理器来避免那些冗长的 switch 语句(或 if/else 子句)。此管理器实例可以作为组件内的属性传递,也可以作为系统成员组合/注入(inject)。
或者,采用引擎 FSM 方法,我们将每个特定于状态的逻辑分解到它们自己的系统中,并根据给定的(引擎)状态将它们交换进出。这种方法并非没有缺点,因为缺少系统会影响与其关联的所有实体。但是,将系统专用于单个实体实例(例如,玩家角色)并不少见,因此这在正确的上下文中可以证明是有用的。想想它在某些情况下通过系统交换影响全局实体可能也是可取的。
( 注意:如果您的逻辑修改范围需要更窄,您可以将其限制在系统中而不涉及引擎 FMS。这可以通过在系统中实现状态模式来实现,系统可以通过委托(delegate)来改变其行为到基于状态的不同子系统。)
我已经看到一些 ECS 框架将系统组合标记为“阶段”,但它们从根本上充当 FSM,其中 ECS 引擎使用与给定阶段关联的不同系统集来处理实体。
最后,数据组合只是等式的一半;在尝试在 ECS 中实现 FSM 时,如何组合逻辑位(或 block )同样重要。
关于oop - 实体组件系统中的有限状态机实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39185133/
我正在通读 Windows Phone 7.5 Unleashed,有很多代码看起来像这样(在页面的代码隐藏中): bool loaded; protected override void OnNav
在cgi服务器中,我这样返回 print ('Status: 201 Created') print ('Content-Type: text/html') print ('Location: htt
我正在查看 esh(easy shell)的实现,无法理解在这种情况下什么是 22 和 9 信号。理想情况下,有一个更具描述性的常量,但我找不到列表。 最佳答案 信号列表及其编号(包括您看到的这两个)
我的Oozie Hive Action 永远处于运行模式。 oozie.log文件中没有显示错误。
我正在编写一个使用 RFCOMM 通过蓝牙连接到设备的 Android 应用程序。我使用 BluetoothChat 示例作为建立连接的基础,大部分时间一切正常。 但是,有时由于出现套接字已打开的消息
我有一个云调度程序作业,它应该每小时访问我的 API 以更新一些价格。这些作业大约需要 80 秒才能运行。 这是它的作用: POST https://www.example.com/api/jobs/
我正在 Tomcat 上访问一个简单的 JSP 页面: 但是当我使用 curl 测试此页面时,我得到了 200 响应代码而不是预期的 202: $ curl -i "http://localhos
有时 JAR-RS 客户端会发送错误的语法请求正文。服务器应响应 HTTP status 400 (Bad Request) , 但它以 HTTP status 500 (Internal Serve
我正在尝试通过 response.send() 发送一个整数,但我不断收到此错误 express deprecated res.send(status): Use res.sendStatus(sta
我已经用 Excel 和 Java 做过很多次了……这次我需要用 Stata 来做,因为保存变量更方便'labels .如何将 dataset_1 重组为下面的 dataset_2? 我需要转换以下
我正在创建一个应用程序,其中的对象具有状态查找功能。为了提供一些上下文,让我们使用以下示例。 帮助台应用程序,其中创建作业并通过以下工作流程移动: 新 - 工作已创建但未分配 进行中 - 分配给工作人
我想在 Keras 中运行 LSTM 并获得输出和状态。在 TF 中有这样的事情 with tf.variable_scope("RNN"): for time_step in range
有谁知道 Scala-GWT 的当前状态 项目? 那里的主要作者 Grzegorz Kossakowski 似乎退出了这个项目,在 Spring 中从事 scalac 的工作。 但是,在 interv
我正在尝试编写一个 super 简单的 applescript 来启动 OneDrive App , 或确保打开,当机器的电源设置为插入时,将退出,或确保关闭,当电源设置为电池时。 我无法找到如何访问
目前我正在做这样的事情 link.on('click', function () { if (link.attr('href') !== $route.current.originalPath
是否可以仅通过查看用户代理来检测浏览器上是否启用/禁用 Javascript。 如果是,我应该寻找什么。如果否,检测用户浏览器是否启用/禁用 JavaScript 的最佳方法是什么 最佳答案 不,没有
Spring 和 OSGi 目前的开发状况如何? 最近好像有点安静了。 文档的最新版本 ( http://docs.spring.io/osgi/ ) 来自 2009 年。 我看到一些声明 Sprin
我正在从主函数为此类创建一个线程,但即使使用 Thread.currentThread().interrupt() 中断它,输出仍然包含“Still Here”行。 public class Writ
为了满足并发要求,我想知道如何在 Godog 中的多个步骤之间传递参数或状态。 func FeatureContext(s *godog.Suite) { // This step is ca
我有一个UIButton子类,它不使用UIImage背景,仅使用背景色。我注意到的一件事是,当您设置按钮的背景图像时,有一个默认的突出显示状态,当按下按钮时,该按钮会稍微变暗。 这是我当前的代码。
我是一名优秀的程序员,十分优秀!