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

Libgdx问题:Actor中绘制的纹理显示过大异常

解决Actor中纹理渲染异常的问题

嘿,这个问题我太熟了!我来帮你拆解一下问题所在,然后一步步解决它~

首先咱们先揪出一个严重的错误习惯:你在render方法里每次都new Texture(Gdx.files.internal("badlogic.jpg")),这绝对不能这么干!Texture是GPU上的资源,每次渲染都创建新的Texture会疯狂消耗内存,还会导致频繁的GPU资源销毁重建,性能爆炸差,而且最终会内存泄漏。不管是在Screen还是Actor里,都要把Texture的初始化放在一次性的生命周期方法里,比如Screen的show()或者Actor的构造函数,然后在dispose()里销毁它。

第一步:正确管理Texture资源

先把Screen里的代码改对:

private Texture texture;

@Override
public void show() {
    // 只初始化一次
    texture = new Texture(Gdx.files.internal("badlogic.jpg"));
}

@Override
public void render(float delta) {
    Gdx.gl.glClearColor(1, 1, 1, 1);
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
    
    batch.begin();
    // 用已经初始化好的texture
    batch.draw(texture, 0f, 0f, 100, 100f);
    batch.end();
}

@Override
public void dispose() {
    // 销毁资源,释放GPU内存
    texture.dispose();
}

第二步:修复Actor中的渲染问题

你在Actor里渲染异常,只看到放大的像素,核心原因有两个:

  1. 你可能在Actor的draw方法里自己调用了batch.begin()/batch.end(),这会打断Stage的SpriteBatch状态——Stage在绘制Actor之前已经把batch的坐标系变换到了Actor的局部空间,你手动begin会重置这个变换,导致绘制坐标混乱。
  2. 你没有给Actor设置尺寸,Actor默认尺寸是0x0,绘制时的坐标和缩放完全不符合预期。

正确的Actor代码示例

public class MyTextureActor extends Actor {
    private Texture texture;

    // 传入已经初始化好的texture,避免重复创建
    public MyTextureActor(Texture texture) {
        this.texture = texture;
        // 给Actor设置尺寸,这里设成你想要的100x100
        setSize(100, 100);
        // 可以设置Actor在Stage中的位置
        setPosition(50, 50);
    }

    @Override
    public void draw(Batch batch, float parentAlpha) {
        // 先调用super.draw,保证Actor的颜色、透明度等状态被正确应用
        super.draw(batch, parentAlpha);
        
        // 绝对不要在这里调用batch.begin()/batch.end()!Stage已经处理好了
        // 在Actor的draw方法中,坐标0,0就是Actor的左下角,直接用Actor的宽高绘制
        batch.draw(texture, 0, 0, getWidth(), getHeight());
    }
}

然后在Screen中把Actor添加到Stage里

private Stage stage;

@Override
public void show() {
    texture = new Texture(Gdx.files.internal("badlogic.jpg"));
    stage = new Stage();
    MyTextureActor actor = new MyTextureActor(texture);
    stage.addActor(actor);
    // 把Stage设为输入处理器(如果需要的话)
    Gdx.input.setInputProcessor(stage);
}

@Override
public void render(float delta) {
    Gdx.gl.glClearColor(1, 1, 1, 1);
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
    
    // 更新并渲染Stage
    stage.act(delta);
    stage.draw();
}

@Override
public void dispose() {
    texture.dispose();
    stage.dispose();
}

为什么之前会只看到一个像素?

当你在Actor的draw方法里手动调用batch.begin(),会重置SpriteBatch的投影矩阵和变换矩阵,此时你用0,0,100,100绘制,其实是在屏幕坐标系下绘制,但如果Stage的camera是默认的(比如viewport是屏幕尺寸),而Actor的位置可能被Stage的变换影响,导致纹理被绘制在一个极小的区域,看起来就像是一个被过度放大的像素。

最后再强调几个关键点

  • 永远不要在渲染循环(render/draw)中创建Texture、Mesh等GPU资源,一定要在初始化阶段创建,销毁阶段释放。
  • Actor的draw方法中不要手动操作SpriteBatch的begin/end,交给Stage来管理。
  • 给Actor设置正确的尺寸和位置,利用Actor的局部坐标系进行绘制,这样能和Stage的系统完美配合。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 04:02:08