崩溃:com.badlogic.gdx.physics.box2d.World.jniCreateBody
CRASH: com.badlogic.gdx.physics.box2d.World.jniCreateBody
我在尝试游戏时 java 运行时环境发生 EXCEPTION_ACCESS_VIOLATION 崩溃。它是用 LibGdx 编写的(并使用 box2d)。它是 运行 来自 android 工作室的桌面模式。
我在我的超级马里奥游戏中添加了一个 "fireball" 功能,在跳入空中并发射火球时出现此错误。这是崩溃日志:
Java frames: (J=compiled Java code, j=interpreted, Vv=VM code) j
com.badlogic.gdx.physics.box2d.World.jniCreateBody(JIFFFFFFFFZZZZZF)J+0
j
com.badlogic.gdx.physics.box2d.World.createBody(Lcom/badlogic/gdx/physics/box2d/BodyDef;)Lcom/badlogic/gdx/physics/box2d/Body;+80
j com.mygdx.game.sprite.Fireball.define()V+68 j
com.mygdx.game.sprite.Fireball.(Lcom/mygdx/game/screen/PlayScreen;FFZ)V+135
j com.mygdx.game.sprite.Mario.shootFire()V+36 J 1115 C1
com.mygdx.game.screen.PlayScreen.handleInput(F)V (221 bytes) @
0x000000000320f90c [0x000000000320e960+0xfac] J 1073 C1
com.mygdx.game.screen.PlayScreen.update(F)V (188 bytes) @
0x00000000031e14ec [0x00000000031e1440+0xac] J 1074 C1
com.mygdx.game.screen.PlayScreen.render(F)V (252 bytes) @
0x00000000031e493c [0x00000000031e3f20+0xa1c] J 1223 C1
com.mygdx.game.MarioBros.render()V (5 bytes) @ 0x0000000003263ae4
[0x0000000003263920+0x1c4] j
com.badlogic.gdx.backends.lwjgl.LwjglApplication.mainLoop()V+698 j
com.badlogic.gdx.backends.lwjgl.LwjglApplication.run()V+27 v
~StubRoutines::call_stub
这是我的火球 class:
public class Fireball extends Sprite {
private PlayScreen playScreen;
private World world;
private Array<TextureRegion> frames;
private Animation<TextureRegion> animation;
private float stateTimer;
private boolean destroyed;
private boolean destroy;
private boolean fireToRight;
private Body body;
public Fireball(PlayScreen playScreen, float x, float y, boolean fireToRight){
this.playScreen = playScreen;
this.fireToRight = fireToRight;
this.world = playScreen.getWorld();
destroy = false;
destroyed = false;
frames = new Array<TextureRegion>();
for(int i = 0; i < 4; i++)
frames.add(new TextureRegion(playScreen.getAtlas().findRegion("fireball"),i*8,0,8,8));
animation = new Animation<TextureRegion>(0.2f, frames);
setRegion(animation.getKeyFrame(0));
setBounds(x, y, 6/ C.PIXEL_PER_METER, 6/C.PIXEL_PER_METER);
define();
}
private void define(){
BodyDef bodyDef = new BodyDef();
bodyDef.position.set(fireToRight ? getX() + 12 /C.PIXEL_PER_METER : getX() - 12 /C.PIXEL_PER_METER, getY());
bodyDef.type = BodyDef.BodyType.DynamicBody;
if(world.isLocked())
return;
body = world.createBody(bodyDef);
FixtureDef fixtureDef = new FixtureDef();
CircleShape shape = new CircleShape();
shape.setRadius(3 / C.PIXEL_PER_METER);
fixtureDef.filter.categoryBits = C.FIREBALL_BIT;
fixtureDef.filter.maskBits = C.GROUND_BIT |
C.COIN_BIT |
C.BRICK_BIT |
C.ENEMY_BIT |
C.OBJECT_BIT;
fixtureDef.shape = shape;
fixtureDef.restitution = 1;
fixtureDef.friction = 0;
body.createFixture(fixtureDef).setUserData(this);
body.setLinearVelocity(new Vector2(fireToRight ? 2 : -2, 2.5f));
}
public void update(float deltaTime){
if((stateTimer > 3 || destroy) && !destroyed){
world.destroyBody(body);
destroyed = true;
body = null;
return;
}
stateTimer += deltaTime;
setRegion(animation.getKeyFrame(stateTimer, true));
setPosition(body.getPosition().x - getWidth()/2, body.getPosition().y - getHeight()/2);
if(body.getLinearVelocity().y > 2f)
body.setLinearVelocity(body.getLinearVelocity().x,2f);
if((fireToRight && body.getLinearVelocity().x < 0 ) || (!fireToRight && body.getLinearVelocity().x > 0))
destroy();
}
public void destroy(){
destroy = true;
}
public boolean isDestroyed(){
return destroyed;
}
}
我从 PlayScreen class 调用 mario.shootFire()
。
这就是 "mario shoots fireballs" 的方式:
private Array<Fireball> fireballs;
fireballs = new Array<Fireball>();
public void shootFire(){
fireballs.add(new Fireball(playScreen, body.getPosition().x, body.getPosition().y, runRight));
}
@Override
public void draw(Batch batch) {
super.draw(batch);
for (Fireball fireball: fireballs)
fireball.draw(batch);
}
关于我为什么会收到此错误的任何想法?
编辑:它似乎在 Fireball 的 define() 方法中的这一行 body = world.createBody(bodyDef)
处崩溃。
com.badlogic.gdx.physics.box2d.World.jniCreateBody
您正在尝试访问不再可用的内存。有几个关于如何在 box2d 中创建和销毁物体的教程。关于更新物理世界 (step()),您必须在正确的时间执行此操作。
因为你只得到 JNI 调试信息,所以很难准确知道错误在哪里(已经出现过很多次)获得更好异常的一个好方法是将主体设置为 null(紧接 world.destroyBody(正文);)
world.destroyBody(body);
body = null;
destroyed = true;
我在尝试游戏时 java 运行时环境发生 EXCEPTION_ACCESS_VIOLATION 崩溃。它是用 LibGdx 编写的(并使用 box2d)。它是 运行 来自 android 工作室的桌面模式。
我在我的超级马里奥游戏中添加了一个 "fireball" 功能,在跳入空中并发射火球时出现此错误。这是崩溃日志:
Java frames: (J=compiled Java code, j=interpreted, Vv=VM code) j com.badlogic.gdx.physics.box2d.World.jniCreateBody(JIFFFFFFFFZZZZZF)J+0 j com.badlogic.gdx.physics.box2d.World.createBody(Lcom/badlogic/gdx/physics/box2d/BodyDef;)Lcom/badlogic/gdx/physics/box2d/Body;+80 j com.mygdx.game.sprite.Fireball.define()V+68 j com.mygdx.game.sprite.Fireball.(Lcom/mygdx/game/screen/PlayScreen;FFZ)V+135 j com.mygdx.game.sprite.Mario.shootFire()V+36 J 1115 C1 com.mygdx.game.screen.PlayScreen.handleInput(F)V (221 bytes) @ 0x000000000320f90c [0x000000000320e960+0xfac] J 1073 C1 com.mygdx.game.screen.PlayScreen.update(F)V (188 bytes) @ 0x00000000031e14ec [0x00000000031e1440+0xac] J 1074 C1 com.mygdx.game.screen.PlayScreen.render(F)V (252 bytes) @ 0x00000000031e493c [0x00000000031e3f20+0xa1c] J 1223 C1 com.mygdx.game.MarioBros.render()V (5 bytes) @ 0x0000000003263ae4 [0x0000000003263920+0x1c4] j com.badlogic.gdx.backends.lwjgl.LwjglApplication.mainLoop()V+698 j com.badlogic.gdx.backends.lwjgl.LwjglApplication.run()V+27 v ~StubRoutines::call_stub
这是我的火球 class:
public class Fireball extends Sprite {
private PlayScreen playScreen;
private World world;
private Array<TextureRegion> frames;
private Animation<TextureRegion> animation;
private float stateTimer;
private boolean destroyed;
private boolean destroy;
private boolean fireToRight;
private Body body;
public Fireball(PlayScreen playScreen, float x, float y, boolean fireToRight){
this.playScreen = playScreen;
this.fireToRight = fireToRight;
this.world = playScreen.getWorld();
destroy = false;
destroyed = false;
frames = new Array<TextureRegion>();
for(int i = 0; i < 4; i++)
frames.add(new TextureRegion(playScreen.getAtlas().findRegion("fireball"),i*8,0,8,8));
animation = new Animation<TextureRegion>(0.2f, frames);
setRegion(animation.getKeyFrame(0));
setBounds(x, y, 6/ C.PIXEL_PER_METER, 6/C.PIXEL_PER_METER);
define();
}
private void define(){
BodyDef bodyDef = new BodyDef();
bodyDef.position.set(fireToRight ? getX() + 12 /C.PIXEL_PER_METER : getX() - 12 /C.PIXEL_PER_METER, getY());
bodyDef.type = BodyDef.BodyType.DynamicBody;
if(world.isLocked())
return;
body = world.createBody(bodyDef);
FixtureDef fixtureDef = new FixtureDef();
CircleShape shape = new CircleShape();
shape.setRadius(3 / C.PIXEL_PER_METER);
fixtureDef.filter.categoryBits = C.FIREBALL_BIT;
fixtureDef.filter.maskBits = C.GROUND_BIT |
C.COIN_BIT |
C.BRICK_BIT |
C.ENEMY_BIT |
C.OBJECT_BIT;
fixtureDef.shape = shape;
fixtureDef.restitution = 1;
fixtureDef.friction = 0;
body.createFixture(fixtureDef).setUserData(this);
body.setLinearVelocity(new Vector2(fireToRight ? 2 : -2, 2.5f));
}
public void update(float deltaTime){
if((stateTimer > 3 || destroy) && !destroyed){
world.destroyBody(body);
destroyed = true;
body = null;
return;
}
stateTimer += deltaTime;
setRegion(animation.getKeyFrame(stateTimer, true));
setPosition(body.getPosition().x - getWidth()/2, body.getPosition().y - getHeight()/2);
if(body.getLinearVelocity().y > 2f)
body.setLinearVelocity(body.getLinearVelocity().x,2f);
if((fireToRight && body.getLinearVelocity().x < 0 ) || (!fireToRight && body.getLinearVelocity().x > 0))
destroy();
}
public void destroy(){
destroy = true;
}
public boolean isDestroyed(){
return destroyed;
}
}
我从 PlayScreen class 调用 mario.shootFire()
。
这就是 "mario shoots fireballs" 的方式:
private Array<Fireball> fireballs;
fireballs = new Array<Fireball>();
public void shootFire(){
fireballs.add(new Fireball(playScreen, body.getPosition().x, body.getPosition().y, runRight));
}
@Override
public void draw(Batch batch) {
super.draw(batch);
for (Fireball fireball: fireballs)
fireball.draw(batch);
}
关于我为什么会收到此错误的任何想法?
编辑:它似乎在 Fireball 的 define() 方法中的这一行 body = world.createBody(bodyDef)
处崩溃。
com.badlogic.gdx.physics.box2d.World.jniCreateBody
您正在尝试访问不再可用的内存。有几个关于如何在 box2d 中创建和销毁物体的教程。关于更新物理世界 (step()),您必须在正确的时间执行此操作。
因为你只得到 JNI 调试信息,所以很难准确知道错误在哪里(已经出现过很多次)获得更好异常的一个好方法是将主体设置为 null(紧接 world.destroyBody(正文);)
world.destroyBody(body);
body = null;
destroyed = true;