Я недавно разрабатывал игру для 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 настраивается на тот же поток, что и сама игра. Вот как я обрабатывать диалоги:
Я использую Javascript (носорог анализатор) следующим образом (передавая объект диалога для сценария в диалоге «» переменной): вар d = dialog.show ("Hello! Как дела.");
Чтобы получить ввод, я вызываю метод getInput, который принимает в диалоговом окне, и до 4 строк в качестве параметров выбора. Предполагается, что этот метод возвращает целочисленное значение. Это можно назвать через скрипт следующим образом:
var response = dialog.getInput(d, "I'm fine, thank you!", "Who wants to know.");
Метод 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:
Я думал о запуске ввода на отдельном потоке, но это все равно приведет к блокированию других способов ввода от вызова (например, изменение выбранной опции в диалоговом окне).
Я ценю помощь и понимаю, что вы говорите, но это не решает проблему ожидания значения без блокировки потока. – rodit