带有libGDX枚举的ExceptionInInitializerError

时间:2017-03-09 12:39:36

标签: java opengl exception enums libgdx

我有以下枚举文件“DevelopmentCardType”:

enum DevelopmentCardType {
    KNIGHT (0, new Texture(Gdx.files.internal("knight_card.png")));
    VICTORY_POINT (1, new Texture(Gdx.files.internal("victory_point_card.png"))),

    private final Texture cardTexture;
    private final int type;
    private static final List<DevelopmentCardType> VALUES = Collections.unmodifiableList(Arrays.asList(values()));

    DevelopmentCardType(int type, Texture cardTexture) {
        this.type = type;
        this.cardTexture = cardTexture;
    }

    public Texture getCardTexture() {
        return cardTexture;
    }

    public static List<DevelopmentCardType> getVALUES() {
        return VALUES;
    }
}

在套接字事件上创建一个新的DevelopmentCard

“DevelopmentCard”课程:

class DevelopmentCard extends Card {

  private float[] vertices = {
        0, 0,
        512, 0,
        512, 512,
        0, 512
  };

  DevelopmentCard (int type) {
    super(0, 0, 70, 100);
    this.type = type;
    createResourceCardSprite(type);
  }

  private void createResourceCardSprite(int resourceType) {
    Texture cardTexture = DevelopmentCardType.getVALUES().get(resourceType).getCardTexture();
    TextureRegion textureRegion = new TextureRegion(cardTexture);
    PolygonRegion polygonRegion = new PolygonRegion(textureRegion, vertices, new EarClippingTriangulator().computeTriangles(vertices).toArray());
    card = new PolygonSprite(polygonRegion);
  }
}

当创建一个新的DevelopmentCard时,它会创建一个ExceptionInInitializerError“由”没有OpenGL上下文引起。

这意味着枚举中使用的纹理尚未创建,因此我想在首次在套接字事件上使用枚举之前执行此操作。我可以通过向DevelopmentCardType类添加一个init方法来修复它(我明白在枚举中调用任何方法(可能是这样的空))仍然在OpenGL上下文中将解决问题,我不确定是否这是正确的做法):

static void init() {}

并在“Main”类中调用它,如DevelopmentCardType.init();

这是解决此问题的正确方法吗?我还可以通过在OpenGL上下文中创建DevelopmentCard来解决问题,之后,创建新的DevelopmentCard实例不会导致错误。

1 个答案:

答案 0 :(得分:1)

实例化纹理有两个要求。它必须在GL线程上完成,并且必须在LibGDX初始化后完成。

第一次在任何地方引用DevelopmentCardType时,它将实例化其所有值(KNIGHT和VICTORY_POINT)。这可能发生在Gdx引擎初始化之前(当您在DesktopLauncher或AndroidLauncher中调用initialize时会发生这种情况)。如果在create()和render()方法之外的任何地方使用DevelopmentCardType(例如在构造函数中,或作为成员变量),它也可能出现在与GL线程不同的线程中。

此外,枚举处理资产(纹理)是没有意义的,这些资源是临时对象,并且在未正确处理时会导致内存泄漏。

实际上,您应该在一个地方处理游戏的所有资产,这样您就可以轻松管理加载和卸载,并避免内存泄漏。 LibGDX已经拥有了一个功能强大的类,即AssetManager。如果你想保持与当前代码类似的结构,我建议用一个String替换你的枚举的Texture成员作为Texture的文件名。这可用于从AssetManager中检索纹理。您可以将AssetManager实例传递给DevelopmentCard构造函数,以便它可以检索纹理。