6

编辑:这对我来说更有意义,因为我已经远离了代码,感谢您的帮助。

前几天通过 Coding Horror 发现堆栈溢出,看起来很棒。图我会向社区询问我目前正在尝试解决的问题。

我正在为 midp 2.0 手机开发一个使用 j2me 的 roguelike 游戏。该项目仍处于开发的基本阶段,因为我正在弄清楚它将如何工作。我目前坚持的部分与线程有关。

该游戏有一个自定义HaxCanvas类,它扩展了 GameCanvas 并实现了可运行。它的 run 方法调用 repaint() 然后休眠 50 毫秒,导致帧速率为 20 FPS。这使我可以编写游戏的其余部分,而不必到处重新绘制,并且应该使动画和效果在以后更容易完成。(至少在理论上)。

游戏流程由 GameManager 类控制,该类循环遍历地图上的所有 NPC,轮流进行,直到轮到玩家。在这一点上,我需要获得输入以允许玩家四处移动和/或攻击东西。我最初是在调用gameManager.runUntilHeroTurn()keyPressedHaxCanvas. 然而,在阅读了 j2me 系统线程之后,我意识到将一个有可能在回调中运行一段时间的方法是一个坏主意。但是我必须使用 keyPressed 进行输入处理,因为我需要访问数字键,并且getKeyStates()不支持这个。

到目前为止,我试图将我的游戏循环放在它自己的线程中已经导致了灾难。游戏运行了几轮后,出现了一个没有堆栈跟踪的奇怪“未捕获的 ArrayIndexOutOfBoundsException”。

所以我想我的问题是这样的:

对于 j2me 中的“回合制”游戏,实现游戏循环的最佳方式是什么,仅在轮到玩家时才允许输入处理?

4

2 回答 2

5

虽然不是 j2me,但您应该捕获用户输入,但一般策略是将输入排队,直到处理输入为止。

input ---> queue <---> Manager(loop)

这样,您甚至可以为调试目的编写脚本输入。

所以你不需要一个新线程。每次用户按键时,您将它们存储在缓冲区中,然后在必要时处理缓冲区的内容。如果玩家缓冲区没有输入,经理应该跳过所有游戏,做动画然后重新开始(因为游戏不是动作游戏)。

于 2009-02-26T05:44:01.927 回答
3

我会避免游戏逻辑的线程化,因为 J2ME 线程化当然取决于制造商,在共享有限资源方面做得不好。当线程执行繁重的处理时,您经常会看到暂停。我只会推荐用于加载或网络连接功能的线程,因为在这种情况下,您只会向用户提供基本的“正在加载...”反馈。

为了处理这个问题,我不会有子循环在一帧中更新每个 AI。我会在运行函数中执行以下操作:

public void run() {
    while(true) {
        // Update the Game
        if(gameManager.isUsersTurn()) {
            // Collect User Input
            // Process User Input
            // Update User's State
        }
        else {
            // Update the active NPC based on their current state
            gameManager.updateCurrentNPC();
        }

        // Do your drawing
    }
}

您希望避免在一帧中更新所有内容,因为 1)更新可能很慢,导致用户无法立即获得视觉反馈 2)您无法在每个 NPC 做出动作时为其设置动画。通过此设置,您可以拥有 NPC 状态、NPC_DECIDE_MOVE 和 NPC_ANIMATING,这将允许您进一步控制 NPC 正在做什么。NPC_ANIMATING 基本上会将游戏置于等待动画发生的状态,避免任何进一步的处理,直到动画完成。然后它可以移动到下一个NPC的回合。

另外,我只需要一个 gameManager.update() 和 gameManager.paint(g)(paint 将从paint 中调用)来处理所有事情并保持 run 方法的精简。

最后,您是否研究过flushGraphics()?使用 GameCanvas,您通常会创建一个 Graphics 对象,将所有内容绘制到该对象上,然后调用 flushGraphics(),然后等待。您提到的方法是处理 Canvas 类的方法。只是想我会提到这一点并发布一个链接: Game Canvas Basics

于 2009-02-26T14:48:42.897 回答