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

Libgdx中stage.draw与stage.getBatch.draw的关系及代码写法合理性咨询

你的代码存在问题,不属于规范写法

首先得明确:Stage的draw()方法内部已经会自动管理它的SpriteBatch的begin()和end()调用。你现在在stage.draw()之后又手动调用stage.getBatch().begin(),很可能会触发GdxRuntimeException——因为Stage在执行完draw()后已经调用了batch.end(),如果此时再手动开启batch,要么会因为状态冲突报错,要么会导致后续绘制的内容无法正确应用Stage的相机矩阵。

关于stage.draw()和stage.getBatch().draw()的关系

  • stage.draw():Stage会遍历所有已添加的Actor,按顺序调用每个Actor的draw()方法。每个Actor在绘制时,会自动使用Stage的SpriteBatch(前提是你没有给Actor设置自定义Batch),Stage会统一处理Batch的开启、关闭,以及相机投影矩阵的应用,完全不需要你手动干预。
  • stage.getBatch().draw():这是直接使用Stage的Batch来手动绘制纹理/精灵,但你必须严格管理Batch的begin()和end()生命周期,还要注意同步Stage的相机矩阵——因为Stage的Batch默认绑定了Stage自身的Camera,如果你手动绘制时忽略这一点,内容可能会显示在错误的位置。

规范的写法建议

方式一:把动画封装成Actor(最推荐)

Libgdx的核心设计就是用Actor来管理所有可视化元素,这样Stage可以统一处理更新和绘制,彻底避免手动管理Batch的麻烦:

// 先自定义一个动画Actor
public class AnimatedActor extends Actor {
    private Animation<TextureRegion> animation;
    private float elapsedTime;

    public AnimatedActor(Animation<TextureRegion> animation) {
        this.animation = animation;
        // 设置Actor的大小为动画帧的尺寸
        TextureRegion firstFrame = animation.getKeyFrame(0);
        setSize(firstFrame.getRegionWidth(), firstFrame.getRegionHeight());
    }

    @Override
    public void act(float delta) {
        super.act(delta);
        elapsedTime += delta; // 用Stage传入的delta即可,无需额外获取
    }

    @Override
    public void draw(Batch batch, float parentAlpha) {
        super.draw(batch, parentAlpha);
        TextureRegion currentFrame = animation.getKeyFrame(elapsedTime, true);
        batch.draw(currentFrame, getX(), getY(), getWidth(), getHeight());
    }
}

// 初始化阶段:
private AnimatedActor animatedActor;

// 在create()或者show()里:
animatedActor = new AnimatedActor(texture.animation);
animatedActor.setPosition(locationX, locationY);
stage.addActor(animatedActor);

// 最终的render方法:
public void render(float delta) { 
    // 注意:glClearColor的参数是0-1的浮点数,你原来的101、10会被截断为1,需要除以255转换
    Gdx.gl.glClearColor(101/255f, 10/255f, 0, 1); 
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); 
    stage.act(delta); 
    stage.draw(); 
}

方式二:手动使用Stage的Batch绘制(仅适合特殊场景)

如果你确实有手动绘制的需求,必须确保Batch状态正确,比如在stage.draw()之前完成手动绘制,并且同步Stage的相机矩阵:

public void render(float delta) { 
    Gdx.gl.glClearColor(101/255f, 10/255f, 0, 1); 
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); 

    stage.act(delta); 

    // 先手动绘制,再让Stage处理自身Actor的绘制
    stage.getBatch().begin();
    // 绑定Stage的相机投影矩阵,确保绘制位置正确
    stage.getBatch().setProjectionMatrix(stage.getCamera().combined);
    elapseTime += delta;
    stage.getBatch().draw(texture.animation.getKeyFrame(elapseTime,true),locationX,locationY); 
    stage.getBatch().end();

    stage.draw(); 
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 03:34:42