java - 在不阻塞游戏线程的情况下等待触摸输入

标签 java android game-engine

我最近一直在开发一款安卓游戏。该游戏的格式类似于经典的口袋妖怪游戏(非常复杂)。我已经走了很远没有任何问题。但是,我发现很难开发有人说话时出现在屏幕底部的对话(打字机文本)框。我一直在等待任何输入而不阻塞渲染和更新方法(因为它们都在同一个线程上运行)。

这是我的游戏循环的简化版本,概述了结构以及我在每一帧中所做的事情。显示的更新方法是通过 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
}

如您所见,这些操作会更新所有游戏组件( map 、战斗、GUI 等),然后将它们渲染到屏幕上。通过查看代码,很明显我在同一个线程上运行这些操作,所以这个线程显然不能被阻塞(否则游戏将停止)。

这就是我的问题所在。我使用带有几个按钮的游戏图形用户界面。这些按钮被分配给 8 个整数 (0-8),例如,当按下向上按钮时,该输入数据将通过游戏传递到现有对话或战斗或任何需要它的地方。这些按钮依赖于主 Activity 的触摸事件,其中 MotionEvent 作为从 onDraw 方法运行游戏循环的结果,在与游戏本身相同的线程上运行。以下是我处理对话的方式:

  1. 我按如下方式使用 javascript(rhino 解析器)(将对话框对象传递给变量“dialog”中的脚本): var d = dialog.show("你好!你好吗。");

  2. 为了获取输入,我调用了接受对话框的 getInput 方法,最多 4 个字符串作为选择选项。此方法应该返回一个整数值。这可以通过脚本调用如下: var response = dialog.getInput(d, "我很好,谢谢!", "谁想知道。");

  3. 我的Dialog类中的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.
    }
    

现在我的主要问题是如何在不阻塞渲染和更新线程的情况下运行这个方法。更具体地说,当用户触摸屏幕的某个区域(gui 选择按钮所在的位置)时,设置 d.lastInput 和 d.waitingForInput 的值。

如果对我在这个问题中想问的问题有任何疑问,请发表评论,因为我很累并且花了一些时间试图解决这个问题。

编辑:

我考虑过在单独的线程上运行输入,但这仍然会导致阻止其他输入法被调用(例如更改对话框中的选定选项)。

最佳答案

如果你不想停止线程并且你已经完成了一半

方法 1:使用 ConcurrentLinkedQueue、ArrayBlockingQueue 及其系列作为静态变量并将您的值放入其中。

方法 2:您可以使用 TCP/UDP 套接字,使用 localhost 适配器作为消息队列系统,并尝试通过同样的 ConcurrentLinkedQueue,ArrayBlockingQueue 技术

尝试引用任何开源 java 游戏引擎源代码并确定它们是如何工作的,或者您可以使用这些游戏引擎,例如“jMonkeyEngine”、“LWJGL”...等

关于java - 在不阻塞游戏线程的情况下等待触摸输入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31014010/

相关文章:

java - 如何比较黑莓上的2时间?

java - Java中的关闭窗口事件

android - 需要 Gradle 版本 2.2。当前版本是 4.4 错误

java - JavaFX 应用程序中的 iFrame 在 Linux 上运行时不加载某些页面

java - 平移后更新android中的图像坐标

android - 使用来自letsencrypt的证书与 flutter

java - Android 选项卡式 Activity 底部关闭屏幕

swift - 尝试手动将 2d 触摸转换为 spritekit 坐标时出现问题

ios - Cocos2d-x 背景图片显示不正确

java - 为什么我的 0-16129 索引数组不为空,但其余索引为空?