我的游戏在一段时间后开始冻结(占用太多ram),我想尝试使用循环方法绘制3(后来更多)字符串。我的代码是这样的:
public class Simple implements ApplicationListener {
private OrthographicCamera camera;
private SpriteBatch batch;
private BitmapFont font;
private GlyphLayout layout;
String a1 = "aa";
String a2 = "bb";
String a3 = "cc";
int a = 0;
@Override
public void create() {
camera = new OrthographicCamera();
camera.setToOrtho(false, 800, 480);
batch = new SpriteBatch();
}
@Override
public void render() {
Gdx.gl.glClearColor(0, 0, 0.2f, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
camera.update();
batch.setProjectionMatrix(camera.combined);
batch.begin();
for (int i = 1; i < 4; i++) {
layout = new GlyphLayout();
font = new BitmapFont();
layout.setText(font, "a" + i);
font.draw(batch, layout, 200 + (15 * i), 200);
}
batch.end();
}
}
答案 0 :(得分:2)
想象一下EpicPandaForce在评论中提到的内容:
public class Simple implements ApplicationListener {
private OrthographicCamera camera;
private SpriteBatch batch;
private BitmapFont font;
private GlyphLayout layout;
String a1 = "aa";
String a2 = "bb";
String a3 = "cc";
int a = 0;
@Override
public void create() {
camera = new OrthographicCamera();
camera.setToOrtho(false, 800, 480);
batch = new SpriteBatch();
//Initialize the fields in create()
layout = new GlyphLayout();
font = new BitmapFont();
}
@Override
public void render() {
Gdx.gl.glClearColor(0, 0, 0.2f, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
camera.update();
batch.setProjectionMatrix(camera.combined);
batch.begin();
for (int i = 1; i < 4; i++) {
//Use them like you do.
layout.setText(font, "a" + i);
font.draw(batch, layout, 200 + (15 * i), 200);
}
batch.end();
}
}
我不确定这是否会起作用。你没有在任何地方指定bitmapfont所以当你使用布局绘制它时,你可能得到nullPointerException
。在create方法中,您可能希望使用font = new BitmapFont(Gdx.files.internal("Path to bitmapfont"));
初始化字体。
使用new是一项昂贵的操作。每个帧都调用update()方法,并且每次调用时都要创建新对象。最重要的是BitmapFont()
不是一个小对象。每次为字体和布局创建一个新对象时,它所拥有的上一个对象都需要由垃圾收集器收集。一个基本规则是永远不要在new
方法中使用update()
关键字,而是改变它和/或像我刚才那样使用它。以一种非常简单的方式可视化:
Object o; // <-- a simple container
new Object(); // <-- a object stored in memory in all it's glory
Object o = new Object(); // <-- container o is now pointing to the memory address of new Object()
Object o = new Object(); // container 0 is now pointing to a different object in memory
//But the old one is still chilling at it's own address and needs to be collected
答案 1 :(得分:2)
问题不一定是你在每次渲染调用时创建一个新字体(尽管出于性能原因你当然不应该这样做),但更多的是你没有通过{{从内存中释放字体'。 1}}。
通常垃圾收集会在您之后清理,但在某些情况下您需要自行清理。 Libgdx出于性能原因使用了一些非托管代码,因此需要您手动释放它。该文件清楚地说明了这一点,并阐述了原因。
管理从文件加载的BitmapFont的纹理。处置() 必须调用以在不再需要时释放纹理。一个BitmapFont 如果区域的纹理是,则使用TextureRegion加载 管理。处理BitmapFont会处理区域的纹理 如果纹理仍在其他地方使用,则可能不合适。
因此,在完成字体操作后调用dispose,并在构造函数中初始化字体。否则你的程序将使用越来越多的内存,性能将会非常糟糕。