【问题标题】:Game architecture & methodology (screens/effects)游戏架构和方法(屏幕/效果)
【发布时间】:2012-01-27 20:43:40
【问题描述】:

我正在研究如何设计我的游戏,以管理/转换不同的“屏幕”以及效果时间。我目前在 Android 上使用 AndEngine,它没有明确的游戏循环,尽管我有兴趣了解这些问题在有或没有游戏循环的情况下是如何处理的。

  1. 我已经编写了一个临时系统,用于处理我的游戏中的不同“屏幕”(启动画面、菜单、游戏、选项等),它基于 AndEngine 中的“场景”。我有 3 个基本“场景”,它们充当背景、内容和弹出窗口的图层。每个 Screen 都有 onTransitionIn() 和 onTransitionOut() 方法,当它自己的方法(例如 closePopup() 之类的东西)被调用时,它们由 ScreenManager 调用。但是,转换方法中的所有代码显然会立即运行,这意味着所有动画、屏幕状态等都会立即执行。为了克服这个问题,我在 Android Handler 类中使用了 postDelayed(runnable, delay) 方法。这样,我就能够在过渡动画完成后更改屏幕状态并运行一个又一个动画。现在整个系统几乎都基于通过处理程序运行延迟代码。不出所料,它很粗糙,不是特别稳定并且通常是业余的。

  2. 关于“效果计时”的第二个问题与我对 Handler 类的使用密切相关。假设我想在用户完成任务时创建一个效果,播放一些动画并在屏幕上增加一个数字。目前,让一个接一个运行的唯一方法是使用 Handler。如前所述,这在我看来是一种粗略/不稳定/业余的方法。

我真的很想知道这些问题在游戏中通常是如何处理的(无论有无显式循环)。

【问题讨论】:

    标签: java android architecture methodology


    【解决方案1】:

    根据您的描述,听起来当您想要触发一连串动作时,您基本上是一次将它们全部触发,每个动作都有一些固定的延迟。这非常脆弱 - 如果您更改其中一个操作的持续时间,它可能不再与应该发生的事情同步。

    更强大的方法是使用Observer Pattern。每个动作都可以有一个onCompleted() 事件(和/或各种其他事件,取决于动作的性质),可用于触发下一个动作的开始。

    例如,假设当用户按下选择一个菜单项时,您需要以下事件序列:

    1. 播放所选项目的动画。
    2. 完成 1 后,关闭当前屏幕。
    3. 当 2 完成后,切换到下一个屏幕。

    听起来你正在做这样的事情:

    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(履行观察者模式中的“主体”角色)和 ActionObservers(履行“观察者”角色)来链接事件:

    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) 更改为 action.start()

    【讨论】:

    • 非常感谢,听起来这已经是一个更好的方法了。但是,您是否建议我仍然使用 Android Handler 类?您建议的方法仍然需要在通过 Handler 运行代码之前手动设置每个效果的计时值。
    • 啊,这更有意义!非常感谢,这是一个很大的帮助:)
    • 抱歉,这有点误导。我已经更新了我的答案并更改了令人困惑的命名。我还尝试让观察者模式的实现更加清晰。
    • 您好,我刚刚遇到了一个问题。我已经实现了一个名为 Action 的小型抽象类,它有一个观察者的 ArrayList,并在它自己的 onCompleted() 方法中调用观察者 onCompleted() 方法。但是,我仍然有在所有效果完成后需要调用 onCompleted() 的问题。目前,没有延迟,所以一切都会立即运行。再次感谢
    • 为了更清晰,做了另一个小更新......所以,目前你正在为来自动作的start() 方法的所有观察者调用onCompleted()。你能看出那里的问题吗?
    猜你喜欢
    • 2013-11-21
    • 2020-01-25
    • 2011-07-24
    • 1970-01-01
    • 2013-12-24
    • 1970-01-01
    • 1970-01-01
    • 2017-08-22
    • 2016-09-27
    相关资源
    最近更新 更多