2017-03-09 87 views
0

枚举我有以下枚举文件 “DevelopmentCardType”:在创建一个新的DevelopmentCard插座事件ExceptionInInitializerError,使用在libGDX

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” 类:

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上下文。

这意味着在枚举中使用的纹理还没有创建,所以这就是为什么我想在第一次使用套接字事件时使用enum之前这样做的原因。我可以通过在DevelopmentCardType类中添加一个init方法来解决这个问题,例如(我明白,在枚举中调用任何方法(可能是这样的一个空方法),而仍然在OpenGL上下文中可以解决问题,我不知道是否这是做正确的事):

static void init() {} 

,并调用这个类中的“主”之类DevelopmentCardType.init();

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

回答

1

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

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

此外,枚举无法处理资源(纹理)的加载,这些资源是暂时性对象,当处理不当时会导致内存泄漏。

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

+0

我会看看如果我了解AssetManager,我会回到这个答案。 –

+0

所以我必须通过很多构造函数和DevelopmentCard和其他类的所有实例传递AssetManager实例?这不是很慢吗?或者那是你的意思? –

+0

我已经实施了AssetManager,使用的内存已减半,现在我无需在使用它之前调用方法。谢谢 :) –