c++ - 什么是无模式对话框窗口的良好设计?

标签 c++ oop

我目前正在制作一款 C++ 游戏。 我有我的主循环,在此期间计算逻辑然后绘制 Sprite 等 我想实现“对话窗口”:当你在 NPC 面前按下触摸键时,屏幕底部会弹出一个对话窗口,你会被卡住,直到你按下一个键,但游戏继续运行(其他角色在移动等)所以主循环仍在运行。 我设法做得很好:当一个对象被激活时,它会向对话框管理器发送一条消息,在游戏继续运行时显示文本窗口,所以它看起来像:

object::OnActivated() {
GameManager::doWindow("some text");
//the game is not blocked here, the game continues to run normally and will display a window on the next frame
}

现在,当我希望在对话结束后发生一些关联操作时,或者例如如果您对问题选择"is"时,问题就来了。我想要一个像这样工作的实现:

object::OnActivated() {
GameManager::doWindow("some text");
if(GameManager::Accepted()) addGold(100);
}

问题是一旦创建窗口事件就会执行此检查和操作,而不是在关闭/接受窗口时执行。有什么方法可以做到这一点,同时将相关操作保留在 OnActivated() 函数中?我不知道如何在不使用函数指针的情况下正确地执行此操作,这将迫使我为我可以使用的每个方法都设置一个特定的签名。 谢谢

编辑:我发布了赏金,因为我想知道这个问题最“规范”的答案是什么。我想这是一个非常普遍的问题(对于很多应用程序和每个现代游戏), 我希望有一个尽可能灵活的解决方案,因为截至目前我无法列出对话可能触发的所有可能“后果”。 更多信息: - 每个对话框都将由派生自公共(public)“实体”类的对象触发 - 来自同一类的不同对象几乎总是有不同的对话/ Action 与之相关(例如,所有的 NPC 对象都不会有相同的对话) - 我不关心将“对话逻辑”移出 OnActivated 方法,甚至移出 Entity 类。无论如何都会发生这种情况,因为我希望能够为每个 NPC 添加“随机”对话场景,因此对话等将存储在其他地方 - 但我想让对话逻辑本身尽可能接近单个对话。理想情况下,我希望能够执行以下操作:“result = dialogWindow("question?"); if (result) { ... }"。我不确定这是否可能

最佳答案

很难给出具体的答案,因为您没有指定(或标记)它所针对的平台,所以我会写一个通用的答案。

问题的答案:

“有什么方法可以做到这一点,同时将相关操作保留在 OnActivated() 函数中吗?”

很可能是“否”

有一系列久经考验的模式可以解决您描述的问题。这一系列模式是各种 Model-View-XXX 模式(MVC、MVP、Document-View 等) 这些模式的基本前提是有一个构造,通常是一个对象图,它封装了系统的当前状态(模型)和一组向用户显示此状态的用户界面元素( View )。 每当模型更改时, View 都会更改以匹配新状态。模型如何更改和 View 如何更新的细节将系列中的不同模式区分开来,使用哪一个取决于特定系统如何处理输入的细节。 MVC 非常适合 Internet 应用程序和许多基于循环的游戏,因为用户输入具有进入系统的单一入口点。 MVP、DV 和 MVVM(有人说它们与 MVP 相同)更适合桌面应用程序,其中输入转到 GUI 中的事件控件。

使用这些模式的缺点是创建 View 的代码后面很少有相关操作的代码,但好处远远超过这个缺点。

在您的情况下,您的模型应该有一个对话框文本属性和一个存储当前输入处理程序的属性(状态模式)。 您的主循环将执行以下操作:

  1. 获取当前输入处理程序以根据用户输入(如果有)更新模型(例如更改用户 Sprite 的位置)。
  2. 更新模型的其余部分以反射(reflect)游戏中的其他元素。
  3. 根据当前模型更新 UI

当用户在 NPC 前面按下时,默认输入处理程序更改为处理触发的特定对话框的输入,并且对话框的通用 View 显示文本给用户。

当用户在对话框中选择操作时,处理程序恢复为默认输入处理程序并且对话框的属性返回为空。

步骤1和2构成了MVC模式中的Controller,步骤3是非事件驱动的 View 更新;相反,您可以使用 Observable-Observer 模式,让模型抛出事件, View 观察到相应的变化。

关于c++ - 什么是无模式对话框窗口的良好设计?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8379524/

相关文章:

java - 区分委托(delegate)、组合和聚合(Java OO 设计)

python - 是否可以在实例初始化时向现有对象添加新方法?

PHP OOP 需要建议

JavaScript OOP 和 Chrome 扩展 api 中的异步方法

c++ - 如何从 C++ 中的整数除法返回 double ?

java - 使用 native API : JVM_LoadClass0, JVM_AllocateNewArray 和 JVM_AllocateNewObject 的替代解决方案

c++ - 提取 32 位长的中间 16 位

c++ - 从 std::string 获取第一个字符

javascript - 我在对象实例化到显示 "Uncaught RangeError: Maximum call stack size exceeded"错误时做错了什么以及如何避免它?

c++ - 在 C++ 中将十六进制 IP 转换为十进制 IP