您好我正在编写一个基于物理的LibGDX游戏,必须留在平台上的球,我已经设置了球的物理组件,但是当我尝试根据物理身体更新球的精灵时它给我一个空指针异常的位置。
我花了整整一天试图通过研究和查看其他人的代码来解决问题,但找不到我的错误。感谢您抽出时间和任何意见。下面我输入了我的Render类,Ball GameObject类,Asset类和Exception。
Ball GameObject类:
public class Ball {
public static World physicsWorld;
public static BodyDef ballBodyDef;
public static Body ballBody;
public static CircleShape ballShape;
public static FixtureDef ballFixtureDef;
public static Fixture ballFixture;
public Ball() {
physicsWorld = new World(new Vector2(0, -9.8f), true);
ballBodyDef = new BodyDef();
ballBodyDef.position.set(Assets.ballSprite.getX(),
Assets.ballSprite.getY());
ballBodyDef.type = BodyDef.BodyType.DynamicBody;
ballBody = physicsWorld.createBody(ballBodyDef);
ballShape = new CircleShape();
ballShape.setRadius(6f);
ballFixtureDef = new FixtureDef();
ballFixtureDef.density = 1.0f;
ballFixtureDef.friction = 0.2f;
ballFixtureDef.restitution = 0.4f;
ballFixture = ballBody.createFixture(ballFixtureDef);
}
public void dispose() {
physicsWorld.dispose();
ballShape.dispose();
}
public BodyDef getBallBodyDef() {
return ballBodyDef;
}
public void setBallBodyDef(BodyDef ballBodyDef) {
this.ballBodyDef = ballBodyDef;
}
public Body getBallBody() {
return ballBody;
}
public void setBallBody(Body ballBody) {
this.ballBody = ballBody;
}
public CircleShape getBallShape() {
return ballShape;
}
public void setBallShape(CircleShape ballShape) {
this.ballShape = ballShape;
}
public FixtureDef getBallFixtureDef() {
return ballFixtureDef;
}
public void setBallFixtureDef(FixtureDef ballFixtureDef) {
this.ballFixtureDef = ballFixtureDef;
}
public Fixture getBallFixture() {
return ballFixture;
}
public void setBallFixture(Fixture ballFixture) {
this.ballFixture = ballFixture;
}
}
渲染类:
public class GameRenderer {
private GameWorld myWorld;
private OrthographicCamera cam;
int width = Gdx.graphics.getWidth();
int height = Gdx.graphics.getHeight();
private SpriteBatch batch;
public GameRenderer(GameWorld world, int gameHeight, int midPointY) {
myWorld = world;
cam = new OrthographicCamera();
cam.setToOrtho(true, width, height);
batch = new SpriteBatch();
batch.setProjectionMatrix(cam.combined);
}
public void render(float delta) {
Gdx.app.log("GameRenderer", "render");
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
Ball.physicsWorld.step(Gdx.graphics.getDeltaTime(), 6, 2);
Assets.ballSprite.setPosition(Ball.ballBody.getPosition().x,
Ball.ballBody.getPosition().y);
batch.begin();
batch.draw(Assets.skySprite, 0, 0, 1920, 1080);
batch.draw(Assets.ballSprite, Assets.ballSprite.getX(),
Assets.ballSprite.getY());
batch.draw(Assets.platformSprite, Assets.platformSprite.getX(),
Assets.platformSprite.getY());
batch.end();
}
}
最后我的资产类:
public class Assets {
public static Texture skyTexture;
public static Sprite skySprite;
public static Texture ballTexture;
public static Sprite ballSprite;
public static Texture platformTexture;
public static Sprite platformSprite;
public static Button rightTiltButton;
public static TextureAtlas rightButtonAtlas;
public static TextButtonStyle rightButtonStyle;
public static Skin rightButtonSkin;
public static void Load() {
skyTexture = new Texture(Gdx.files.internal("Assets/skybackground.png"));
skyTexture.setFilter(TextureFilter.Linear, TextureFilter.Linear);
skySprite = new Sprite(skyTexture);
skySprite.flip(false, true);
ballTexture = new Texture(
Gdx.files.internal("Assets/ballcharacter.png"));
ballTexture.setFilter(TextureFilter.Linear, TextureFilter.Linear);
ballSprite = new Sprite(ballTexture);
ballSprite.flip(false, true);
ballSprite.setPosition(
Gdx.graphics.getWidth() / 2 - ballSprite.getWidth()/2,
Gdx.graphics.getHeight() / 2 - ballSprite.getHeight()-4);
platformTexture = new Texture(Gdx.files.internal("Assets/platform.png"));
platformTexture.setFilter(TextureFilter.Linear, TextureFilter.Linear);
platformSprite = new Sprite(platformTexture);
platformSprite.flip(false, true);
platformSprite.setPosition(
Gdx.graphics.getWidth() / 2 - platformSprite.getWidth()/2,
Gdx.graphics.getHeight() / 2 - platformSprite.getHeight()/2);
rightButtonSkin = new Skin();
rightButtonAtlas = new TextureAtlas(
Gdx.files.internal("Assets/right_tilt_button.pack"));
rightButtonSkin.addRegions(rightButtonAtlas);
rightButtonStyle = new TextButtonStyle();
rightButtonStyle.up = rightButtonSkin.getDrawable("right_tilt_button");
rightButtonStyle.up = rightButtonSkin
.getDrawable("right_tilt_button_pressed");
rightButtonStyle.up = rightButtonSkin.getDrawable("right_tilt_button");
rightButtonStyle.over = rightButtonSkin
.getDrawable("right_tilt_button_pressed");
rightButtonStyle.down = rightButtonSkin
.getDrawable("right_tilt_button_pressed");
rightTiltButton = new Button(rightButtonStyle);
}
public static void dispose() {
skyTexture.dispose();
rightButtonAtlas.dispose();
rightButtonSkin.dispose();
ballTexture.dispose();
}
}
NullPointerException:
Exception in thread "LWJGL Application" java.lang.NullPointerException at com.manumade.tiltr.tiltrhelpers.GameRenderer.render (GameRenderer.java:36) at com.manumade.tiltr.screens.GameScreen.render(GameScreen.java:39) at com.badlogic.gdx.Game.render(Game.java:46) at com.badlogic.gdx.backends.lwjgl.LwjglApplication.mainLoop(LwjglApplication.java:208) at com.badlogic.gdx.backends.lwjgl.LwjglApplication$1.run(LwjglApplication.java:114)
答案 0 :(得分:0)
绘制一个精灵(基于异常行号)看起来很麻烦。尝试将您使用的精灵替换为其他精灵(显然它看起来很傻),看看它们是否有效。
一旦你知道哪些精灵有效,哪些没有,你可以尝试缩小它们可能有什么不同。例如,我使用了两种纹理的非幂,导致了类似的问题。
答案 1 :(得分:0)
查看您的代码和堆栈跟踪,其中一行似乎存在问题:
batch.draw(Assets.skySprite, 0, 0, 1920, 1080);
batch.draw(Assets.ballSprite, Assets.ballSprite.getX(),
Assets.ballSprite.getY());
batch.draw(Assets.platformSprite, Assets.platformSprite.getX(),
Assets.platformSprite.getY());
从您提供的堆栈跟踪中我们可以看到错误发生在第36行:
at com.manumade.tiltr.tiltrhelpers.GameRenderer.render (GameRenderer.java:36)
查看你的GameRenderer类,看看在该行上调用了什么对象。当您收到NullPointerException时,这意味着您正在尝试调用方法或访问不指向任何内容的对象上的变量(可能永远不会创建该对象。)
我会假设:
所以看一下这些对象实例化的方式。还要确保在对这些对象执行任何操作之前实际初始化它们。在实际初始化Assets类中的Sprite对象之前,可能会调用render()方法。
答案 2 :(得分:0)
我看到你打电话:
Assets.ballSprite.setPosition(Ball.ballBody.getPosition().x,
Ball.ballBody.getPosition().y);
batch.begin();
batch.draw(Assets.skySprite, 0, 0, 1920, 1080);
batch.draw(Assets.ballSprite,
Assets.ballSprite.getX(),
Assets.ballSprite.getY());
batch.draw(Assets.platformSprite,
Assets.platformSprite.getX(),
Assets.platformSprite.getY());
batch.end();
Assets.skySprite,
Assets.ballSprite,
Assets.platformSprite
但我看不到您拨打Assets.load ();
在使用上面的原因之前为什么是null,因为它们没有初始化只声明,或者我认为是错误。
尝试在渲染方法中使用之前调用Assets.Load ();
,例如在public GameRenderer(...);
方法内部。
可以尝试阅读 AssetsManager :
https://github.com/libgdx/libgdx/wiki/Managing-your-assets 并且在进入游戏区域之前创建资源加载。(但这只是一个想法)。
可以查看www一些关于它的教程 AssetManager 。
P.S:这是一行:(GameRenderer.java:36), 确保在Ball中使用的staticas变量在用于渲染之前已初始化。