You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

LibGDX中Actions随点击累积错误致对话框动画卡顿问题排查

问题根源与解决方案

嘿,这问题我太熟了——你这卡顿完全是重复累积的监听器和未清理的动画动作搞的鬼!咱们一步步拆解:

1. 重复添加点击监听器是核心元凶

你每次触发touchDown时,都给button_close新建一个ClickListener并添加进去:

button_close.addListener(new ClickListener() { ... });

点10次就会有10个监听器绑定在按钮上!每次点击关闭时,这10个监听器会同时触发,导致对话框执行10遍关闭动画,动作队列直接炸了,不卡才怪。

解决办法:
把监听器的绑定逻辑移到touchDown外面——比如在win_dialog_01_1的初始化代码里只加一次,或者每次添加前先移除旧监听器:

// 先清除旧监听器,再添加新的(如果必须在touchDown里加的话)
button_close.clearListeners();
button_close.addListener(new ClickListener() {
    @Override 
    public void clicked(InputEvent event, float x, float y) {
        // 你的关闭逻辑...
    }
});

2. 重复将对话框添加到Stage

每次touchDown都执行stage_dialogs.addActor(win_dialog_01_1),如果对话框已经在Stage里了,重复添加会导致Stage多次渲染同一个Actor,额外消耗性能。

解决办法:
添加前先判断对话框是否已经在Stage中:

if (!win_dialog_01_1.hasParent()) {
    stage_dialogs.addActor(win_dialog_01_1);
}

3. 未清理残留的动画动作

每次打开/关闭对话框时,没有清空之前可能未完成的动画动作,导致新动作和旧动作叠加执行,动作队列越堆越长。

解决办法:
在添加新动作前,先清空对话框的现有动作:

// 打开对话框前清空残留动作
win_dialog_01_1.clearActions();
win_dialog_01_1.addAction(Actions.fadeOut(0));
win_dialog_01_1.addAction(Actions.parallel(Actions.fadeIn(.2f), Actions.scaleTo(1.05f, 1.05f, .2f)));
win_dialog_01_1.addAction(Actions.sequence(Actions.delay(.2f), Actions.scaleTo(1, 1, .2f)));

修改后的简化代码示例

@Override 
public boolean touchDown(int screenX, int screenY, int pointer, int button) {
    vector2 = new Vector2(screenX, Gdx.graphics.getHeight() - screenY);
    if (sprite_1.getBoundingRectangle().contains(vector2)) {
        switch (serverClass.point1) {
            case 0:
                Gdx.app.log("1", "drops");
                win_dialog_alpha_white.clearActions();
                win_dialog_alpha_white.addAction(Actions.fadeIn(.2f));

                // 确保对话框只被添加一次
                if (!win_dialog_01_1.hasParent()) {
                    stage_dialogs.addActor(win_dialog_01_1);
                }
                win_dialog_01_1.setModal(true);

                // 清空残留动作再添加新动画
                win_dialog_01_1.clearActions();
                win_dialog_01_1.addAction(Actions.fadeOut(0));
                win_dialog_01_1.addAction(Actions.parallel(Actions.fadeIn(.2f), Actions.scaleTo(1.05f, 1.05f, .2f)));
                win_dialog_01_1.addAction(Actions.sequence(Actions.delay(.2f), Actions.scaleTo(1, 1, .2f)));

                // 只绑定一次监听器(建议移到初始化代码中)
                if (button_close.getListeners().isEmpty()) {
                    button_close.addListener(new ClickListener() {
                        @Override 
                        public void clicked(InputEvent event, float x, float y) {
                            win_dialog_alpha_white.clearActions();
                            win_dialog_alpha_white.addAction(Actions.fadeOut(.3f));
                            
                            win_dialog_01_1.setModal(false);
                            win_dialog_01_1.clearActions();
                            win_dialog_01_1.addAction(Actions.parallel(Actions.fadeOut(.4f), Actions.scaleTo(1.05f, 1.05f, .2f)));
                            win_dialog_01_1.addAction(Actions.sequence(Actions.delay(.2f), Actions.scaleTo(1, 1, .2f)));
                        }
                    });
                }
                break;
            // 其他case...
        }
    }
    return super.touchDown(screenX, screenY, pointer, button);
}

按照上面的方法改完,你再测试个几十次开关,应该就不会卡顿了——本质就是别让重复的监听器和动作在内存里堆着,每次操作前做好清理和判断就行。

内容的提问来源于stack exchange,提问作者Retron

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 07:12:47