简体   繁体   English

尝试更新Sprite时出现NullPointer异常

[英]NullPointer Exception When Trying to Update Sprite

Hello I am currently programming a LibGDX game based on physics with a ball that must stay on a platform, I have set up the physics components for the ball, but when I try updating the sprite for the ball based on the physic body's position it is giving me a null pointer exception. 您好我正在编写一个基于物理的LibGDX游戏,必须留在平台上的球,我已经设置了球的物理组件,但是当我尝试根据物理体的位置更新球的精灵时它是给我一个空指针异常。

I have spent 1 whole day trying to fix the problem through researching and looking at other peoples' code but cannot find my error. 我花了整整一天试图通过研究和查看其他人的代码来解决问题,但找不到我的错误。 Thank you for your time and any input that you can give. 感谢您抽出时间和任何意见。 Below I have typed the code from my Render class, Ball GameObject class, Asset class, and Exception. 下面我输入了我的Render类,Ball GameObject类,Asset类和Exception中的代码。

Ball GameObject Class: 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;
    }

}

Render Class: 渲染类:

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();

    }

}

Lastly my Assets Class: 最后我的资产类:

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)

It looks like a problem with drawing one of your sprites (based on the exception line number). 绘制一个精灵(基于异常行号)看起来很麻烦。 Try replacing the sprites you have used with other ones (obviously it will look silly), and see if any of them work. 尝试将您使用的精灵替换为其他精灵(显然它看起来很傻),看看它们是否有效。

Once you know which sprites work and which ones don't, you can try and narrow down what might be different about them. 一旦你知道哪些精灵有效,哪些没有,你可以尝试缩小它们可能有什么不同。 I have had similar problems caused by using non-power of two textures, for example. 例如,我遇到了因使用两种纹理的非幂而引起的类似问题。

Looking at your code and stack trace there seems to be a problem on one of this lines: 查看代码和堆栈跟踪,其中一行似乎存在问题:

 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());

From the stack trace that you provided we can see that the error is happening on line 36: 从您提供的堆栈跟踪中,我们可以看到错误发生在第36行:

at com.manumade.tiltr.tiltrhelpers.GameRenderer.render         (GameRenderer.java:36)

Look at your GameRenderer class and see what object gets called on that line. 查看您的GameRenderer类,并查看该行上调用的对象。 When you receive a NullPointerException it means that you are trying to call a method or acess a variable on a object that does not point to anything (The object might never be created.) 当您收到NullPointerException时,这意味着您正在尝试调用方法或访问不指向任何内容的对象上的变量(可能永远不会创建该对象。)

I would assume that either: 我会假设:

  • The SpriteBatch is NULL SpriteBatch为NULL
  • Assets.skySprite is NULL Assets.skySprite为NULL
  • Assets.ballSprite is NULL Assets.ballSprite为NULL
  • Assets.platformerSprite is NULL Assets.platformerSprite为NULL

So look at the way those object get instantiated. 所以看看这些对象实例化的方式。 Also make sure that you are actually initializing them before performing anything on those objects. 还要确保在对这些对象执行任何操作之前实际初始化它们。 Your render() method might be called before you actually initialize the Sprite objects in your Assets class. 在实际初始化Assets类中的Sprite对象之前,可能会调用render()方法。

I see that you call: 我看到你打电话:

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.skySprite,
Assets.ballSprite, Assets.ballSprite,
Assets.platformSprite Assets.platformSprite

but I can not see that you call Assets.load (); 但我看不到你调用Assets.load ();

before using the above why is null, because they are not initialized only declared or I think that's the error. 在使用上面的原因之前为什么是null,因为它们没有初始化只声明或我认为这是错误。

try calling Assets.Load (); 尝试调用Assets.Load (); before that used in render method, for example inside of the your public GameRenderer(...); 在渲染方法中使用之前,例如在你的public GameRenderer(...); method. 方法。

could try to read about it AssetsManager : 可以尝试阅读它AssetsManager

https://github.com/libgdx/libgdx/wiki/Managing-your-assets and create a loading of assets before entering the playing area.(but it's just an idea). https://github.com/libgdx/libgdx/wiki/Managing-your-assets并在进入游戏区域之前创建资源加载。(但这只是一个想法)。

could look at, www some tutorial about it AssetManager . 可以看一下www关于它的一些教程AssetManager

PS: which is the line: (GameRenderer.java:36), sure that the staticas variables used for example in Ball, are initialized before being used in render. PS:这是一行:(GameRenderer.java:36),确保在Ball中使用的staticas变量在用于渲染之前被初始化。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM