游戏架构与方法论(屏幕/效果)
我正在研究如何在不同“屏幕”的管理/转换以及效果时序方面设计我的游戏。我目前在 Android 上使用 AndEngine,它没有明确的游戏循环,尽管我有兴趣了解如何在有或没有游戏循环的情况下处理这些问题。
我已经编写了一个临时系统,用于处理游戏中的不同“屏幕”(启动画面、菜单、游戏、选项等),该系统基于 AndEngine 中的“场景”。我有 3 个基本“场景”,它们充当背景、内容和弹出窗口的图层。每个 Screen 都有 onTransitionIn() 和 onTransitionOut() 方法,当 ScreenManager 自己的方法(例如 closePopup() 之类的)被调用时,它们会被调用。然而,转换方法中的所有代码显然都会立即运行,这意味着所有动画、屏幕状态等都将立即执行。为了克服这个问题,我在Android Handler类中使用了postDelayed(runnable,delay)方法。这样,我就可以在过渡动画完成后更改屏幕状态并运行一个又一个动画。现在整个系统几乎都是基于通过处理程序运行延迟代码。毫不奇怪,它很粗糙,不是特别稳定,而且通常很业余。
关于“效果计时”的第二个问题与我对 Handler 类的使用密切相关。假设我想在用户完成任务时创建一个效果,其中播放一些动画并且屏幕上的数字增加。目前,让一个在另一个之后运行的唯一方法是使用处理程序。如前所述,这在我看来是一种粗糙/不稳定/业余的方法。
我真的很想知道这些问题在游戏中通常是如何处理的(有/没有显式循环)。
I'm looking into how I should design my games in regards to management/transitioning of different "screens" as well as effect timings. I'm currently using AndEngine on Android, which doesn't have an explicit game loop, although I'm interested in hearing how these issues are dealt with both with or without a game loop.
I've already written a temporary system that I'm using to handle the different "screens" in my game (splash, menu, game, options etc), which is based on "scenes" within AndEngine. I've got 3 base "scenes" which act as layers for a background, content and popups. Each Screen has onTransitionIn() and onTransitionOut() methods which are called by the ScreenManager when it's own methods (such as closePopup(), that sort of thing) are called. However, all code in the transition methods would obviously be run at once, meaning all animations, the screen status etc would be executed instantly. To overcome this problem, I used the postDelayed(runnable, delay) method in the Android Handler class. That way, I was able to change the screen status after the transition animations were completed and run one animation after another. Now the entire system is pretty much based on running delayed code via the handler. Unsurprisingly, it's crude, not particularly stable and generally amateurish.
The second issue regarding "effect timings" is closely linked to my usage of the Handler class. Let's just say I want to create an effect when a user completes a task, where some animation is played and a number is increased on the screen. At the moment, the only way of having one run after the other is by using the Handler. As stated previously, this appears to me like a crude/unstable/amateurish method.
I'd really like to know how these issues are generally handled in games (both with/without an explicit loop).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
根据您的描述,听起来当您想要触发一系列操作时,您基本上是立即将它们全部触发,每个操作都有一些固定的延迟。这是非常脆弱的 - 如果您更改其中一项操作的持续时间,它可能不再与其之后发生的事情同步。
更可靠的方法是使用观察者模式。每个操作都可以有一个 onCompleted() 事件(和/或各种其他事件,具体取决于操作的性质),该事件可用于触发下一个操作的开始。
例如,假设当用户按下选择菜单项时,您需要以下事件序列:
听起来你正在做这样的事情:
你可以通过创建 Actions(履行观察者模式中的“主题”角色)和 ActionObservers(履行“观察者”角色)来链接事件:
这样,你就不会“设置 ScreenTransitionOffHandler 时不需要指定 SelectedItemAnimationHandler 的持续时间。
编辑:试图使观察者模式的实现更加清晰。
编辑2:将 runNow(action) 更改为 action.start()
From your description, it sounds like when you want to trigger a chain of actions, you're basically firing them all off at once, each with some fixed delay. This is quite fragile - if you change the duration of one of the actions, it might no longer sync up with something that's supposed to happen after it.
A more robust approach would be to use the Observer Pattern. Each action could have an
onCompleted()
event (and/or various other events, depending on the nature of the action), which could be used to trigger the start of the next action.For example, let's say that when the user presses the selects a menu item, you want this sequence of events:
It sounds like you're doing something like this:
You might chain the events by creating Actions (which fulfil the 'subject' role in the Observer pattern) and ActionObservers (which fulfil the 'observer' role):
This way, you don't need to specify the duration of the SelectedItemAnimationHandler when you set up the ScreenTransitionOffHandler.
EDIT: Tried to make implementation of the Observer pattern clearer.
EDIT 2: Changed runNow(action) to action.start()