单击按钮以 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));
我开发了一个 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));