2015-06-23 3 views
5

Я недавно разрабатывал игру для Android. Игра похожа на классические игры Pokemon (довольно сложная). У меня довольно много проблем. Тем не менее, мне сложно разрабатывать диалоговые окна (текст пишущей машинки), которые появляются в нижней части экрана, когда кто-то говорит. Я застрял в ожидании любого ввода, не блокируя методы рендеринга и обновления (поскольку все они работают в одном потоке).Ожидание сенсорного ввода без блокировки игровой нити

Это упрощенная версия моей игровой петли, описывающая структуру и то, что я делаю каждый кадр. Показанный метод обновления вызывается методом View # onDraw.

public static void update(Canvas canvas, GameView view){ 
    //time operations (calculating delta etc.) 
    long cTime = System.currentTimeMillis(); 
    delta = cTime - time; 
    time = cTime; 
    globals.put("time", time); 
    globals.put("delta", delta);//set vars for scripts 

    camera.applyToCanvas(canvas);//apply camera matrix to canvas 
    if(map != null)map.update(); 
    if(battle != null)map.update(); 
    Effect.updateAll();//update everything (game logic) 

    render.load(canvas);//load the canvas into my custom render engine 
    render();//call render method (shown below) 
    view.invalidate();//reset view for redraw 
} 

public static void render(){ 
    render.reset();//clears the canvas using canvas.setColor(Color.BLACK) 
    if(map != null)map.draw(); 
    if(battle != null)battle.draw(); 
    if(dialog != null)dialog.draw(); 
    if(gui != null)gui.draw(); //draw everything using the renderengine 
} 

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

Здесь моя проблема. Я использую в игре gui несколько кнопок. Этим кнопкам назначаются 8 целых чисел (0-8), а при нажатии кнопки «вверх», например, входные данные передаются в игру в существующий диалог или битву или что-то в этом нуждается. Эти кнопки полагаются на события касания основной активности, где MotionEvent, который в результате запуска игрового цикла из метода onDraw настраивается на тот же поток, что и сама игра. Вот как я обрабатывать диалоги:

  1. Я использую Javascript (носорог анализатор) следующим образом (передавая объект диалога для сценария в диалоге «» переменной): вар d = dialog.show ("Hello! Как дела.");

  2. Чтобы получить ввод, я вызываю метод getInput, который принимает в диалоговом окне, и до 4 строк в качестве параметров выбора. Предполагается, что этот метод возвращает целочисленное значение. Это можно назвать через скрипт следующим образом: var response = dialog.getInput(d, "I'm fine, thank you!", "Who wants to know.");

  3. Метод getInput выглядит следующим образом в моем классе диалога:

    public static int getInput(Dialog d, String... args){ 
        d.waitingForInput = true; 
        d.lastInput = -1; 
        while(d.waitingForInput || d.lastInput == -1){ 
         //render options 
         //main thread is obviously blocked here. 
        } 
        return d.getLastInput();//returns the d.lastInput and resets waitingForInput and lastInput. The script can then use this value to decide what to do. 
    } 
    

Теперь мой главный вопрос заключается в том, чтобы запустить этот метод без блокировки поток рендеринга и обновления. Более конкретно, установка значения d.lastInput и d.waitingForInput, когда пользователь касается определенной области экрана (где кнопка выбора gui).

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

EDIT:

Я думал о запуске ввода на отдельном потоке, но это все равно приведет к блокированию других способов ввода от вызова (например, изменение выбранной опции в диалоговом окне).

ответ

0

Я решил подойти к этому через форму обработчиков событий. Когда требуемый ввод не работает, указанный скрипт запускается в игре.

0

Если вы не хотите, чтобы остановить потоки и вы уже на полпути через

method1: Использование ConcurrentLinkedQueue, ArrayBlockingQueue и его семьи, как статических переменных и положить ваши ценности внутри него.

Method2: использовать можно использовать TCP/UDP сокеты с помощью Localhost адаптера как система очередей сообщений и попытаться получить эти значения с тем же ConcurrentLinkedQueue, технику ArrayBlockingQueue

Пытаться передать любой OpenSource java game engine исходные коды и определить, как они это сделали или вы можете использовать эти игровые движки, такие как «jMonkeyEngine» «LWJGL» ... и т. д.

+0

Я ценю помощь и понимаю, что вы говорите, но это не решает проблему ожидания значения без блокировки потока. – rodit