简体   繁体   English

用于 j2me“回合制”游戏的 Gameloop

[英]Gameloop for j2me “turn-based” game

Edit: This makes alot more sense to me now that i've taken a step away from the code, thanks for the help.编辑:这对我来说更有意义,因为我已经远离了代码,感谢您的帮助。

Just found stack overflow the other day through Coding Horror and it looks awesome.前几天通过 Coding Horror 发现堆栈溢出,看起来很棒。 Figure that i'd ask the community about a problem i'm currently trying to work out.图我会向社区询问我目前正在尝试解决的问题。

I'm developing a roguelike sortof game using j2me for midp 2.0 phones.我正在为 midp 2.0 手机开发一个使用 j2me 的 roguelike 游戏。 The project is still in the basic stages of development as I figure out how it's going to work.该项目仍处于开发的基本阶段,因为我正在弄清楚它将如何工作。 The part i'm currently stuck on has to do with threading.我目前坚持的部分与线程有关。

The game has a custom HaxCanvas class which extends GameCanvas and Implements runnable.该游戏有一个自定义HaxCanvas class,它扩展了 GameCanvas 并实现了可运行。 It's run method calls repaint() and then sleeps for 50 ms, resulting in a frame rate of 20 FPS.它的 run 方法调用 repaint() 然后休眠 50 毫秒,导致帧速率为 20 FPS。 This allows me to write the rest of the game without having to put repaint everywhere and should make animations and effects easier to do later on.这让我可以编写游戏的 rest,而不必在任何地方重新绘制,并且应该使动画和效果在以后更容易完成。 (at least in theory). (至少在理论上)。

The flow of the game is controlled by a GameManager class, which loops through all the NPC's on the map, taking their turns, until it's the player's turn.游戏流程由 GameManager class 控制,它循环遍历 map 上的所有 NPC,轮流进行,直到轮到玩家。 At this point I need to get input to allow the player to move around and/or attack things.在这一点上,我需要获得输入以允许玩家四处移动和/或攻击东西。 I originally was calling gameManager.runUntilHeroTurn() in the keyPressed method of my HaxCanvas .我最初是在我的HaxCanvaskeyPressed方法中调用gameManager.runUntilHeroTurn() However after reading up on j2me system threads I realized that putting a method with the potential to run for a while in a callback is a bad idea.然而,在阅读了 j2me 系统线程之后,我意识到在回调中放置一个可能运行一段时间的方法是一个坏主意。 However I must used keyPressed to do input handeling, since i need access to the number keys, and getKeyStates() does not support this.但是我必须使用 keyPressed 进行输入处理,因为我需要访问数字键,而getKeyStates()不支持这一点。

Sofar my attempts to put my gameloop in it's own thread have resulted in disaster.到目前为止,我试图将我的游戏循环放在它自己的线程中已经导致了灾难。 A strange "uncaught ArrayIndexOutOfBoundsException" with no stack trace shows up after the game has run for several turns.游戏运行了几轮后,会出现一个没有堆栈跟踪的奇怪“未捕获的 ArrayIndexOutOfBoundsException”。

So i suppose my question is this:所以我想我的问题是这样的:

For a "turn based" game in j2me, what's the best way to implement the game loop, allowing for input handeling only when it's the player's turn?对于 j2me 中的“回合制”游戏,实现游戏循环的最佳方式是什么,仅在轮到玩家时才允许输入处理?

Although not j2me specifically you should capture user input, the general strategy is to queue the input it until its time to process the input.虽然不是 j2me,但您应该捕获用户输入,但一般策略是将输入排队,直到处理输入为止。

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

This way you can even script input for debug purposes.这样,您甚至可以为调试目的编写脚本输入。

So you don't need a new thread.所以你不需要一个新线程。 Each time the user presses key you store them in a buffer, and then process the contents of the buffer when necessary.每次用户按键时,您将它们存储在缓冲区中,然后在必要时处理缓冲区的内容。 If the player buffer has no input, the manager should skip all gameplay, do animations and then start over (since the game is not an action game).如果玩家缓冲区没有输入,经理应该跳过所有游戏,做动画然后重新开始(因为游戏不是动作游戏)。

I would avoid threading for the game logic as J2ME threading, depending on manufacturer of course, does not do a great job of sharing the limited resources.我会避免游戏逻辑的线程化,因为 J2ME 线程化当然取决于制造商,在共享有限资源方面做得不好。 You will often see pauses while a thread does heavy processing.当线程执行繁重的处理时,您经常会看到暂停。 I would only recommend threads for loading or network connectivity features as in this case you will just be giving the user basic "Loading..." feedback.我只会推荐用于加载或网络连接功能的线程,因为在这种情况下,您只会向用户提供基本的“正在加载...”反馈。

To handle this, I would not have sub-loops to update each of the AI in one frame.为了处理这个问题,我不会有子循环在一帧中更新每个 AI。 I would do something like following in the run function:我会在运行 function 中执行以下操作:

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
    }
}

You want to avoid having everything updated in one frame as 1) the updating might be slow, resulting in no immediate visual feedback for the user 2) you can't animate each individual NPC as they make their action.您希望避免在一帧中更新所有内容,因为 1)更新可能很慢,导致用户无法立即获得视觉反馈 2)您无法在每个 NPC 做出动作时为其设置动画。 With this setup you could have NPC states, NPC_DECIDE_MOVE and NPC_ANIMATING, that would allow you further control of what the NPC is doing.通过此设置,您可以拥有 NPC 状态、NPC_DECIDE_MOVE 和 NPC_ANIMATING,这将允许您进一步控制 NPC 正在做什么。 NPC_ANIMATING would basically put the game in a waiting state for the animation to take place, avoiding any further processing until the animation is complete. NPC_ANIMATING 基本上会将游戏置于等待 state 以等待 animation 发生,避免任何进一步的处理,直到 animation 完成。 Then it could move on to the next NPC's turn.然后它可以移动到下一个NPC的回合。

Also, I would just have a gameManager.update() and gameManager.paint(g) (paint would be called from paint) that would handle everything and keep the run method thin.另外,我只需要一个 gameManager.update() 和 gameManager.paint(g)(paint 将从paint 中调用)来处理所有事情并保持 run 方法的精简。

Finally, did you look into flushGraphics()?最后,您是否研究过flushGraphics()? With the GameCanvas you usually create a Graphics object, draw everything to that and then call flushGraphics(), then wait.使用 GameCanvas,您通常会创建一个图形 object,将所有内容绘制到该位置,然后调用 flushGraphics(),然后等待。 The method you mention is the way of tackling it for the Canvas class.您提到的方法是针对 Canvas class 处理它的方法。 Just thought I would mention this and post a link: Game Canvas Basics只是想我会提到这一点并发布一个链接:游戏 Canvas 基础知识

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM