我正在研究如何设计我的游戏,以管理/转换不同的“屏幕”以及效果时间。我目前在Android上使用AndEngine,它没有明确的游戏循环,虽然我有兴趣听听这些问题是如何处理有或没有游戏循环。
我已经编写了一个临时系统,用于处理游戏中不同的“屏幕”(启动,菜单,游戏,选项等),这是基于AndEngine中的“场景”。我有3个基础“场景”,作为背景,内容和弹出窗口的层。每个Screen都有onTransitionIn()和onTransitionOut()方法,当调用它自己的方法(例如closePopup(),那种东西)时,ScreenManager会调用这些方法。但是,转换方法中的所有代码显然都会立即运行,这意味着所有动画,屏幕状态等都会立即执行。为了解决这个问题,我在Android Handler类中使用了postDelayed(runnable,delay)方法。这样,我就可以在过渡动画完成后更改屏幕状态并运行一个又一个动画。现在整个系统几乎都基于通过处理程序运行延迟代码。不出所料,它是粗糙的,不是特别稳定,通常是业余的。
关于“效果时间”的第二个问题与我对Handler类的使用密切相关。让我们说我想在用户完成任务时创建一个效果,在该任务中播放一些动画并在屏幕上增加一个数字。目前,一个接一个地运行的唯一方法是使用Handler。如前所述,这在我看来像粗糙/不稳定/业余的方法。
我真的很想知道这些问题通常是如何在游戏中处理的(有/没有显式循环)。
答案 0 :(得分:1)
根据你的描述,这听起来就像你想要触发一系列动作一样,你基本上都会立刻解雇它们,每个都有一些固定的延迟。这非常脆弱 - 如果你改变其中一个动作的持续时间,它可能不再与之后应该发生的事情同步。
更强大的方法是使用Observer Pattern。每个操作都可能有一个onCompleted()
事件(和/或其他各种事件,具体取决于操作的性质),可用于触发下一个操作的开始。
例如,假设当用户按下选择菜单项时,您需要这一系列事件:
听起来你正在做这样的事情:
void onItemSelected(MenuItem menuItem) {
runNow(new SelectedItemAnimationHandler(menuItem)); // Takes 500ms
// Delay for 500ms to wait until end of selection anim.
postDelayed(new ScreenTransitionOffHandler(currentMenu), 500); // Takes 1000ms
// Delay for 1500ms to wait until end of transition off.
postDelayed(new ScreenTransitionOnHandler(nextMenu), 1500);
}
您可以通过创建Actions(在Observer模式中实现'subject'角色)和ActionObservers(履行'observer'角色)来链接事件:
void onItemSelected(MenuItem menuItem) {
// Set up the actions
// Actions call onCompleted() on any observers when they complete.
SelectedItemAnimationAction sa = new SelectedItemAnimationAction(menuItem);
ScreenTransitionOffAction stoff = new ScreenTransitionOffAction(currentMenu);
ScreenTransitionOnAction ston = new ScreenTransitionOnAction(nextMenu);
// Add some observers to the actions
sah.addOnCompletedHandler(new ActionObserver() {
public void onCompleted() {
stoff.start();
}
});
stoff.addOnCompletedHandler(new ActionObserver() {
public void onCompleted() {
ston.start();
}
});
// Start the first action
sa.start();
}
这样,您在设置ScreenTransitionOffHandler时无需指定SelectedItemAnimationHandler的持续时间。
编辑:尝试使观察者模式的实现更加清晰。 编辑2:将runNow(动作)更改为action.start()