Gameloop для пошаговой игры на j2me

Изменить: теперь это имеет для меня больше смысла, когда я отошел от кода, спасибо за помощь.

Недавно обнаружил переполнение стека через Coding Horror, и это выглядит потрясающе. Представьте, что я спрошу сообщество о проблеме, над которой сейчас пытаюсь справиться.

Я разрабатываю roguelike-игру с использованием j2me для телефонов midp 2.0. Проект все еще находится на основных стадиях разработки, и я прикидываю, как он будет работать. Часть, на которой я сейчас застрял, связана с резьбой.

В игре есть собственный класс HaxCanvas, который расширяет GameCanvas и реализует runnable. Этот метод run вызывает repaint (), а затем отключается на 50 мс, в результате чего частота кадров составляет 20 кадров в секунду. Это позволяет мне писать остальную часть игры без необходимости перекрашивать везде, и должно упростить анимацию и эффекты в дальнейшем. (по крайней мере, теоретически).

Ход игры контролируется классом GameManager, который просматривает всех NPC на карте по очереди, пока не наступит очередь игрока. На этом этапе мне нужно получить вход, чтобы позволить игроку перемещаться и / или атаковать предметы. Изначально я вызывал gameManager.runUntilHeroTurn() в keyPressed методе моего HaxCanvas. Однако после прочтения системных потоков j2me я понял, что помещать метод с потенциалом для работы в течение некоторого времени в обратном вызове - плохая идея. Однако я должен использовать keyPressed для обработки ввода, так как мне нужен доступ к цифровым клавишам, а getKeyStates() не поддерживает это.

Софар мои попытки поместить мой игровой цикл в отдельную ветку закончились катастрофой. Странное «неперехваченное исключение ArrayIndexOutOfBoundsException» без трассировки стека появляется после того, как игра длится несколько ходов.

Итак, я предполагаю, что мой вопрос таков:

Для «пошаговой» игры в j2me, как лучше всего реализовать игровой цикл, позволяющий обрабатывать ввод только тогда, когда наступает очередь игрока?


person LoginError    schedule 26.02.2009    source источник
comment
Кстати, хороший вопрос. +1   -  person Fostah    schedule 26.02.2009


Ответы (2)


Я бы избегал потоковой передачи для игровой логики, поскольку многопоточность 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), которые обрабатывают все и сохраняют метод run тонким.

Наконец, вы заглянули в flushGraphics ()? С помощью GameCanvas вы обычно создаете объект Graphics, рисуете все на нем, затем вызываете flushGraphics () и ждете. Упомянутый вами метод - это способ решения этой проблемы для класса Canvas. Просто подумал, что упомяну об этом и опубликую ссылку: Основы игрового холста

person Fostah    schedule 26.02.2009

Хотя это и не j2me специально, вы должны захватывать ввод пользователя, общая стратегия состоит в том, чтобы поставить его в очередь до тех пор, пока не наступит время его обработки.

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

Таким образом, вы даже можете вводить скрипт для целей отладки.

Так что вам не нужна новая ветка. Каждый раз, когда пользователь нажимает клавишу, вы сохраняете их в буфере, а затем обрабатываете содержимое буфера, когда это необходимо. Если буфер игрока не имеет ввода, менеджер должен пропустить весь игровой процесс, выполнить анимацию, а затем начать заново (поскольку игра не является игрой в жанре экшн).

person Robert Gould    schedule 26.02.2009