简体   繁体   English

libGDX中带有枚举的ExceptionInInitializerError

[英]ExceptionInInitializerError with enums in libGDX

I have the following enum file "DevelopmentCardType": 我有以下枚举文件“ 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;
    }
}

upon a socket event a new DevelopmentCard is created 发生套接字事件时,将创建一个新的DevelopmentCard

"DevelopmentCard" class: “ 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);
  }
}

When a new DevelopmentCard is created, it creates an ExceptionInInitializerError "caused by" there not being an OpenGL context. 创建新的DevelopmentCard时,它将创建一个ExceptionInInitializerError“由...引起”,其中没有OpenGL上下文。

This means the textures that are used in the enum aren't created yet, so that's why I want to do that before first using the enum upon a socket event. 这意味着尚未创建枚举中使用的纹理,因此这就是为什么我要在套接字事件之前首先使用枚举之前执行此操作的原因。 I can fix it by adding an init method to the DevelopmentCardType class like (I understand that calling any method (which may be empty like this one) in the enum while still in the OpenGL context will fix the problem, I'm not sure whether this is the right thing to do): 我可以通过在DevelopmentCardType类中添加一个init方法来解决该问题,例如(我知道在枚举中仍在OpenGL上下文中调用任何方法(可能是空的)都可以解决该问题,我不确定这是正确的做法):

static void init() {}

and calling this in class "Main" like DevelopmentCardType.init(); 并在“ Main”类DevelopmentCardType.init();DevelopmentCardType.init();调用此方法DevelopmentCardType.init(); .

Is this the correct way to get around this problem? 这是解决此问题的正确方法吗? I can also fix the problem by creating a DevelopmentCard while still in the OpenGL context, after that, creating new DevelopmentCard instances does not result in errors. 我还可以通过仍在OpenGL上下文中创建DevelopmentCard来解决问题,此后,创建新的DevelopmentCard实例不会导致错误。

There are two requirements to instantiate a Texture. 实例化纹理有两个要求。 It must be done on the GL thread, and it must be done after LibGDX is initialized. 它必须在GL线程上完成,并且必须在LibGDX初始化后完成。

The first time DevelopmentCardType is referenced anywhere, it will instantiate all its values (KNIGHT and VICTORY_POINT). 首次在任何地方引用DevelopmentCardType时,它将实例化其所有值(KNIGHT和VICTORY_POINT)。 This is likely occurring before the Gdx engine is initialized (which happens when you call initialize in your DesktopLauncher or AndroidLauncher). 这很可能在Gdx引擎初始化之前发生(在您在DesktopLauncher或AndroidLauncher中调用initialize时发生)。 It is also likely occurring in a different thread than the GL thread if DevelopmentCardType is used anywhere outside your create() and render() methods (such as in the constructor, or as a member variable). 如果在您的create()和render()方法之外的任何地方(例如,在构造函数中或作为成员变量使用)都使用DevelopmentCardType,则也可能在与GL线程不同的线程中发生。

Furthermore, it does not make sense for an enum to handle the loading of an asset (the textures), which are transient objects and cause memory leaks when not disposed properly. 此外,枚举没有意义来处理资产(纹理)的加载,资产是临时对象,如果处理不当会导致内存泄漏。

Really you should handle all your assets for your game in one place so you can easily manage loading and unloading, and avoid memory leaks. 确实,您应该在一个地方处理游戏的所有资产,以便可以轻松管理加载和卸载,并避免内存泄漏。 LibGDX already has a powerful class for doing that, AssetManager. LibGDX已经有一个强大的类可以做到这一点,即AssetManager。 If you want to keep a similar structure to your current code, I suggest replacing the Texture member of your enum with a String for the file name of the Texture. 如果要保持与当前代码相似的结构,建议将Enum的Texture成员替换为String作为Texture的文件名。 This can be used to retrieve the Texture from your AssetManager. 这可用于从AssetManager检索纹理。 You can pass your AssetManager instance to your DevelopmentCard constructor so it can retrieve the Texture. 您可以将AssetManager实例传递给DevelopmentCard构造函数,以便它可以检索Texture。

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

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