LibGDX-使用ShapeRenderer时为NullPointerException

问题描述 投票:1回答:1

[我正在尝试对LibGDX上的类进行一些JUnit测试,但是在尝试初始化所述类时出现NullPointerError,这可以追溯到使用ShapeRenderer。

这是我初始化的班级:

import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.kroy.game.Point;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer.ShapeType;

import java.util.ArrayList;

import static java.lang.Math.abs;

public class Entity{
    int health;
    int range;
    public Point position;
    ShapeRenderer shape = new ShapeRenderer();
    public Sprite drawable;


    public Entity(int health, int range, Point position,Texture img){
        this.health = health;
        this.range = range;
        this.position = position;
        this.drawable = new Sprite(img);
        drawable.setPosition(position.x - drawable.getWidth()/2,position.y - drawable.getHeight()/2);
    }

    public boolean inRange(Entity target){
        if(abs(target.position.x - this.position.x) < this.range &&
                abs(target.position.y - this.position.y) < this.range){
            return true;
        }
        return false;
    }


    public void drawBox(ArrayList<Entity> target, OrthographicCamera camera, Sprite sprite) {
        shape.setProjectionMatrix(camera.combined);
        shape.begin(ShapeType.Line);
        boolean redBox = false;
        for(Entity entity : target) {
            if (this.inRange(entity)) {
                redBox = true;
            }
        }
        if (redBox) {
            shape.setColor(Color.RED);
        }
        else {
            shape.setColor(Color.GREEN);
        }
        shape.rect(position.x - range, position.y - range, range * 2, range * 2);
        shape.end();
    }

}

这里是EntityTest的相关代码:

 import com.kroy.entities.Entity;
 import com.kroy.game.Point;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.Assertions;

class EntityTest {

@Test
    public void testInRangeBoundary() {
        Entity e = new Entity(0,5, new Point(5,5));
        Assertions.assertTrue(e.inRange(new Entity(0,0,new Point(9,0))));
    }
}

这是我得到的错误:

java.lang.NullPointerException
    at com.badlogic.gdx.graphics.glutils.ShaderProgram.loadShader(ShaderProgram.java:209)
    at com.badlogic.gdx.graphics.glutils.ShaderProgram.compileShaders(ShaderProgram.java:188)
    at com.badlogic.gdx.graphics.glutils.ShaderProgram.<init>(ShaderProgram.java:171)
    at com.badlogic.gdx.graphics.glutils.ImmediateModeRenderer20.createDefaultShader(ImmediateModeRenderer20.java:233)
    at com.badlogic.gdx.graphics.glutils.ImmediateModeRenderer20.<init>(ImmediateModeRenderer20.java:56)
    at com.badlogic.gdx.graphics.glutils.ShapeRenderer.<init>(ShapeRenderer.java:116)
    at com.badlogic.gdx.graphics.glutils.ShapeRenderer.<init>(ShapeRenderer.java:111)
    at com.badlogic.gdx.graphics.glutils.ShapeRenderer.<init>(ShapeRenderer.java:107)
    at com.kroy.entities.Entity.<init>(Entity.java:22)
    at EntityTest.testInRangeBoundary(EntityTest.java:10) <19 internal calls>
    at java.base/java.util.ArrayList.forEach(ArrayList.java:1540) <9 internal calls>
    at java.base/java.util.ArrayList.forEach(ArrayList.java:1540) <21 internal calls>

(对于参考线22是'ShapeRenderer shape = new ShapeRenderer();'行)

我知道NullPointerException通常意味着尚未初始化,但是我不确定该怎么做。

任何帮助将不胜感激!

java gradle nullpointerexception libgdx renderer
1个回答
0
投票
与所有其他Gdx.gl字段一样,在测试过程中

Gdx为空。这里发生的是您正在Entity构造函数中创建一个新的ShapeRenderer对象。然后,ShapeRenderer尝试访问libGDX的渲染API,但是它们没有初始化,因此会出现异常。

由于您并未真正测试实体是否正确绘制,但是inRange方法是否正常工作,所以您希望避免在测试期间调用任何libGDX的API。

有许多解决方案。您可以重新排列代码:

  • @ Code-Apprentice指出,将游戏逻辑和渲染逻辑分为两类。您可以具有Entity类和EntityRenderer类。您只测试前者。
  • 或者不通过在构造函数中实例化ShapeRenderer。相反,可以将ShapeRenderer作为参数传递给drawBox方法。如果我没记错的话,ShapeRenderer是相当重的对象,因此如果您有很多实体,您可能还是想这样做。

另一种可能性是在测试期间模拟libGDX的API。

  • 使用Mockito,您可以执行Gdx.gl = mock(GL20.class)
  • 或者您可以创建将正确初始化HeadlessApplication类的Gdx

这两个选项均为described here。但是,最好在可能的情况下重构代码,这是将游戏逻辑和渲染分开的一种好习惯。

© www.soinside.com 2019 - 2024. All rights reserved.