单击按钮以 Libgdx 重复执行代码

Button click to execute a code repeatedly in Libgdx

我开发了一个 Android 应用程序,使用 Libgdx 3D space 来渲染一些带有交互按钮的建筑物,以帮助用户在环境中导航。例如,左右按钮可以在左右方向上移动相机。当按下按钮导致执行一次代码时,我使用这个技巧在用户按住按钮时继续执行代码。

private void createStage() {

    stage = new Stage();
    intervalTime = 15L;
    buttonLeft = new TextButton("", leftStyle);
    buttonLeft.addListener(new InputListener() {

        // repeat an action with ScheduledExecutorService
        final Runnable leftRunnable = new Runnable() {
            @Override
            public void run() {
                Vector3 dir = new Vector3();
                dir.fromString(cam.direction.toString()).scl(0.5f);
                cam.position.add(dir.z, 0, -dir.x); // camera moves to left
                cam.update();
            }
        };
        // add on thread to object
        final ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
        ScheduledFuture<?> future; // future schedule to run and stop task

        @Override
        public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {

            future = executor.scheduleAtFixedRate(leftRunnable, 0L, intervalTime, TimeUnit.MILLISECONDS);
            return true;
        }

        @Override
        public void touchUp(InputEvent event, float x, float y, int pointer, int button) {
            super.touchUp(event, x, y, pointer, button);
            //leftFlag = false;
            if (future != null) {
                future.cancel(true);
            }
        }
    });

该方法在AndroidListener的create()函数中调用,舞台也会在render()函数中绘制。大约有 12 个按钮使用相同的方法,但当用户按住按钮几秒钟或同时按下两个按钮时,它让我在渲染过程中有些滞后。方法有问题还是适合频繁执行代码的结构?

相机不是 thread-safe class,因此如果从后台线程修改相机,则需要使用同步。

也就是说,更新相机是一项微不足道的操作,因此 multi-threading 增加了很多不必要的复杂性。您正在生成大量垃圾,但我不知道这是否是您看到一些滞后的唯一原因。

以下是我更简单的做法。

stage = new Stage();
float camSpeed = 0.5f / 15; // Units per ms
float camDisp = camSpeed * Gdx.graphics.getDeltaTime();
buttonLeft = new TextButton("", leftStyle){
    public void act(float delta){
        super.act(delta);
        if (isPressed()){
            camera.position.add(camera.direction.z * camDisp, 
                                0, 
                                -camera.direction.x * camDisp);
            camera.update();
        }
    }
}

不太确定你对相机方向做了什么,但我试图复制相同的行为。如果我只是想将相机向左平移,我会这样做。 temp变量是为了避免实例化对象而触发GC。

private static final Vector3 TMP = new Vector3();

//...

TMP.set(camera.direction).crs(camera.up); // right vector of camera
camera.position.add(TMP.scl(-camDisp));