gpt4 book ai didi

java - 内存泄漏。不断上升直至游戏崩溃

转载 作者:行者123 更新时间:2023-12-01 23:42:41 25 4
gpt4 key购买 nike

我是 Android 开发新手,我在游戏使用的内存方面遇到了问题。它不断上升,直到崩溃。如果您能帮助我,我将不胜感激。谢谢。

此外,关于 Spritebatch,我是否需要在扩展为游戏的 java 类中调用 this.dispose 才能将其处置?如果可以的话我可以在哪里调用它?谢谢

public class Zero implements Screen, InputProcessor {
Pmacgame game;
private Stage stage;
private Skin skin;
private Sound sound ,laser;
private Music musicbg;
private Sprite spritebg, playerImage;
private ImageButton imgbtnLeft, imgbtnRight, fire, color1, color2, color3, color4,
bullet1, bullet2, bullet3, bullet4;
public static final float fireDelay = 0.3f;
String rr2;
private static int o = 0;

Rectangle player;
ArrayList<Bullet> bullets;
ArrayList<Target> targets;
ArrayList<Explode> explodes;
//long lastDrop;
int score;
boolean a, b;
public static final float minSpawnTime = 0.5f;
public static final float maxSpawnTime = 1.25f;
float shootTimer, targetSpawnTimer;
Random random;
public static int select;
public static int dis = 0;
public float health = 1;
private Sprite greenBar, redBar, blueBar, pinkBar, greenBarO, redBarO, blueBarO, pinkBarO;
public Zero(Pmacgame game){



@Override
public void render(float delta) {

shootTimer += Gdx.graphics.getDeltaTime();
ArrayList<Bullet> bulletsToRemove = new ArrayList<>();

if (fire.isPressed() && shootTimer >= fireDelay) {
shootTimer = 0;
bullets.add(new Bullet(player.x + 32f));
}


for (Bullet bullet : bullets) {
bullet.update(Gdx.graphics.getDeltaTime());
if (bullet.remove)
bulletsToRemove.add(bullet);
}

targetSpawnTimer -= Gdx.graphics.getDeltaTime();
if (targetSpawnTimer<=0){
targetSpawnTimer = random.nextFloat() * (maxSpawnTime -minSpawnTime) + minSpawnTime;
targets.add(new Target(MathUtils.random(267, Gdx.graphics.getWidth()-350f)));
}
ArrayList<Target> targetsToRemove = new ArrayList<>();
for (Target target: targets){
target.update(delta);
if (target.remove)
targetsToRemove.add(target);
if (target.getY()<=0){
health -= 0.1f;
if (health<=0){
select = 0;
dis = 1;
this.dispose();
game.setScreen(new GameOverScreen(game, score));
return;
}
}
}


ArrayList<Explode> explodesToRemove = new ArrayList<>();
for (Explode explode: explodes){
explode.update(delta);
if (explode.remove)
explodesToRemove.add(explode);
}
explodes.removeAll(explodesToRemove);

for (Bullet bullet: bullets){
for (Target target: targets){
if (bullet.getCollisionRect().collidesWith(target.getCollisionRect())){

targetsToRemove.add(target);
bulletsToRemove.add(bullet);
score+=5;
explodes.add(new Explode(target.getX(), target.getY()));
sound.play(1f, 1.3f, 0f);
}
}
}

targets.removeAll(targetsToRemove);
bullets.removeAll(bulletsToRemove);

//Gdx.gl.glClearColor(0f, 0f, 0f, 1f);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
game.batch.begin();
spritebg.draw(game.batch);
game.batch.draw(blueBarO, 0, 575, blueBarO.getWidth(), blueBarO.getHeight());
game.batch.draw(redBarO, 0, 550, redBarO.getWidth(), redBarO.getHeight());
game.batch.draw(greenBarO, 0, 525, greenBarO.getWidth(), greenBarO.getHeight());
game.batch.draw(pinkBarO, 0, 600, pinkBarO.getWidth(), pinkBarO.getHeight());
game.font.draw(game.batch, "SCORE: " + score, 40, Gdx.graphics.getHeight() - 40 );
for (Bullet bullet: bullets){
bullet.render(game.batch);
}
for (Target target: targets){
target.render(game.batch);
}
for (Explode explode: explodes){
explode.render(game.batch);
}
if (health == 0) greenBar.setSize(greenBar.getWidth(), 0f);
game.batch.draw(greenBar, 0, 525, greenBar.getWidth() * health, greenBar.getHeight());
game.batch.draw(redBar, 0, 550, redBar.getWidth(), redBar.getHeight());
game.batch.draw(blueBar, 0, 575, blueBar.getWidth(), blueBar.getHeight());
game.batch.draw(pinkBar, 0, 600, pinkBar.getWidth(), pinkBar.getHeight());
game.batch.draw(playerImage, player.x, player.y, player.width, player.height);
game.batch.end();


stage.act(Gdx.graphics.getDeltaTime());
stage.draw();
if (a) player.x -= 450 * Gdx.graphics.getDeltaTime();
if (b) player.x += 450 * Gdx.graphics.getDeltaTime();
if (player.x < 65f + imgbtnLeft.getWidth() + imgbtnRight.getWidth())
player.x = 65f + imgbtnLeft.getWidth() + imgbtnRight.getWidth();
if (player.x > Gdx.graphics.getWidth() - 350f)
player.x = Gdx.graphics.getWidth() - 350f;
}

@Override
public void dispose () {
musicbg.dispose();
laser.dispose();
stage.dispose();
skin.dispose();
sound.dispose();

}

}

public class Pmacgame extends Game {
SpriteBatch batch;
BitmapFont font;

@Override
public void create () {
batch = new SpriteBatch();
font = new BitmapFont(Gdx.files.internal("r.fnt"));

this.setScreen(new Zero(this));


}


@Override
public void render () {
super.render();

}

@Override
public void dispose() {
font.dispose();
batch.dispose();
}


}

最佳答案

我正在阅读字里行间,但看起来您必须在 Bullet/Target/Explosion 的构造函数中加载纹理,因为我没有看到您将纹理或纹理区域引用传递给它们的构造函数或 渲染方法。

您应该在单个类中加载所有纹理,并传递对游戏对象的引用,以便它们“借用”和绘图。否则,您将无缘无故地加载相同图像的许多副本。

此外,纹理是一次性的,这意味着它使用 native 内存,并且在让垃圾收集器获取它之前必须对其调用 dispose() 。否则, native 内存会泄漏。

就您而言,所有这些子弹、目标和爆炸都会一遍又一遍地加载许多纹理,并且在您删除它们时永远不会处理它们。

关于您有关 SpriteBatch 的问题。是的,您应该在实例化它的同一个类中处置它,并且 dispose() 是执行此操作的正确位置。

编辑,准系统示例:

public class Assets implements Disposable {

public final Texture horse;
public final Texture bullet;
// etc.

public Assets (){
horse = new Texture("horse.png");
//...
}

public void dispose(){
horse.dispose();
//...
}
}

public class Zero implements Screen, InputProcessor {
private final Assets assets;
//...

public Zero (){
assets = new Assets();
//...
}

//...

public void dispose(){
assets.dispose();
//...
}
}

public class Bullet {
//...

public void render(SpriteBatch batch, Assets assets){
batch.render(assets.bullet, /*...*/);
}
}

关于java - 内存泄漏。不断上升直至游戏崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58252511/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com