Gameloop для j2me "пошаговая" игра - PullRequest
6 голосов
/ 26 февраля 2009

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

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

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

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

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

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

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

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

Ответы [ 2 ]

5 голосов
/ 26 февраля 2009

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

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

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

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

3 голосов
/ 26 февраля 2009

Я бы не стал использовать многопоточность для игровой логики, поскольку многопоточность J2ME, в зависимости от производителя, конечно, не позволяет разделить ограниченные ресурсы. Вы часто будете видеть паузы, в то время как поток выполняет тяжелую обработку. Я бы порекомендовал только темы для загрузки или функции сетевого подключения, так как в этом случае вы просто дадите пользователю базовую обратную связь «Загрузка ...».

Чтобы справиться с этим, у меня не было бы подциклов для обновления каждого ИИ в одном кадре. Я бы сделал что-то вроде следующего в функции запуска:

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. Просто подумал, что упомяну об этом и выложу ссылку: Основы игрового холста

...