c++ - 在相同状态类型的各种屏幕之间切换?

标签 c++ oop events state fsm

我一直对我正在处理的程序的基本结构有疑问。我是一个非常缺乏经验的程序员,试图自学使用多个状态的程序的基础知识。

现在,我有一个非常简单的游戏式程序,带有一个游戏循环,可将事件、逻辑和渲染重定向到我的 StateManager 类,该类将状态推送和弹出到 . StateManager 类然后将事件、逻辑和呈现重定向到 vector 的 back() 上的任何状态。这个想法是为程序的每个阶段设置不同的状态(在本例中是一个带有启动画面、菜单、游戏玩法、死亡画面等的简单游戏)...

但是,我是一个非常新手的编码员(尽我最大的努力学习),而且我的程序从第一个状态类开始就遇到了一个基本问题......

我创建的第一个类是 SplashScreenState。基本概念是有一个状态,基本上只显示一系列“闪屏图像”(例如,假设 3 个),每次用户按下一个键,它就会切换到下一个图像,并且最后(当它没有要循环显示的初始屏幕图像时)切换到下一个状态(菜单状态)。

我的问题是我很难弄清楚如何构建它。最初,我错误地将每个不同的初始屏幕图像视为 SplashScreenState 的一个实例。但是,我认为这样做是不正确的,因为从技术上讲,所有 3 个初始屏幕都属于同一“状态”。

所以现在我有两个主要问题:

  • 第一个问题是我不确定如何/在何处存储所有启动画面图像。如果我想在程序启动时在 3 个不同的屏幕图像之间循环,我是否应该让它们都成为 SplashScreenState 类的成员?还是简单地为“currentImage”设置一个类成员,并且每次用户按下一个键时,它都会运行一个 load() 函数来将下一张图像加载到 currentImage 指针中,这是否更聪明?制作图像数组或 vector 并循环遍历它们更好吗?我只是不确定...

  • 我的第二个问题是 SplashScreenState 的 eventhandling()。我知道我希望屏幕上的图像像这样改变; *image1 -> image 2 -> image 3 -> changeState(menuState).. 这样每次用户按下键盘上的一个键,它就会切换到下一个启动画面,直到最后一个启动画面,然后它会改变状态到主菜单。我也不确定这样做的最佳方法是什么。我是否应该为每个初始屏幕创建一个枚举并递增它们(直到它改变状态的最终屏幕)?我还认为,如果我确实将所有不同的屏幕存储在一个数组中,那么我可以轻松地递增它们,但是那样会不会优化,因为所有屏幕都必须始终存储在内存中?

无论如何,我知道这个问题可能非常基础和笨拙,但不幸的是,这就是我现在所处的位置!我没有接受过任何正规的编程教育,我一直在自学,所以我真的非常感谢这个网站上提供的所有帮助和专业知识! ^^

谢谢!

最佳答案

您似乎在处理状态转换的面向对象和过程范式之间左右为难。另一个建议使用 switch 语句来处理枚举状态更改的答案是一种很好的程序化方法。这样做的缺点是您最终可能会得到一个单一的游戏类,其中包含所有代码和所有多余的特定于状态的数据,用于处理所有可能状态的事件/逻辑/渲染。面向对象的方式来处理这个更清晰,并将它们封装到它们自己单独的状态对象中,它们可以通过共享接口(interface)以多态方式使用。然后,你的游戏类不需要保存处理所有状态的所有细节,你的游戏类只需要存储一个状态指针,而不用担心具体状态对象的实现细节。这将处理状态转换的责任从游戏类转移到它所属的状态类。您应该从设计模式书中阅读状态/策略模式。处理状态的变化应该是状态对象本身的责任。这是一些阅读:

http://www.codeproject.com/Articles/14325/Understanding-State-Pattern-in-C

http://sourcemaking.com/design_patterns/state

http://sourcemaking.com/design_patterns/state/cpp/1

http://codewrangler.home.comcast.net/~codewrangler/tech_info/patterns_code.html#State

http://en.wikipedia.org/wiki/State_pattern

http://www.codeproject.com/Articles/38962/State-Design-Pattern

引用设计模式和面向模式的软件架构书籍: 基于模式的方法使用代码而不是数据结构来指定状态转换,但在适应状态转换操作方面做得很好。状态模式没有指定必须在何处定义状态转换。它可以在上下文对象中完成,也可以在每个单独的派生状态类中完成。让状态子类指定它们的后继状态以及何时进行转换通常更加灵活和合适。

您可以选择提前创建状态对象并且从不销毁它们,这在状态变化迅速发生并且您希望避免销毁可能很快再次需要的状态时非常有用。另一方面,这可能会带来不便,因为上下文必须保留对可能进入的所有状态的引用。

当将进入的状态在运行时未知并且上下文不经常更改状态时,最好根据需要创建状态对象并在之后销毁它们。在确定使用哪个时,您需要考虑成本和转换频率。

关于c++ - 在相同状态类型的各种屏幕之间切换?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11921007/

相关文章:

c++ - 无法编译 C++ 构造函数

c++ - setter 和 getter 中的引用和指针。需要例子

C++继承,如何在基类方法中调用子类方法?

.net - 重载、覆盖和隐藏?

jquery - 当灯箱打开时停止 fullpage.js 滚动,然后在灯箱关闭时重新启用

c++ - "pure virtual function call"崩溃从何而来?

c++ - std::thread 在 DLLMain 中导致死锁

angular - Angular 和内容可编辑

vba - Worksheet_Change 事件中的目标范围不正确

c++ - 计算 thrust::device_vector 上的梯度