Вопрос

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

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

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

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

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

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

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

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

Это было полезно?

Решение

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

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

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 вы обычно создаете графический объект, рисуете все на нем, а затем вызываете flushGraphics(), затем ждете.Метод, о котором вы упоминаете, - это способ решения этой проблемы для класса Canvas.Просто подумал, что стоит упомянуть об этом и разместить ссылку:Основы игрового холста

Другие советы

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top