0
\$\begingroup\$

In the main Screen class of my game there is a ListArray<Card> which makes up the deck of cards . The Card's texture is set in the constructor like so :

cardTexture = new Texture(Gdx.files.internal("backface.png"));

and in the Card class there are 2 methods to show and hide the "CardFace"

public void hideCardFace() {
    cardTexture = new Texture(Gdx.files.internal("backface.png"));
}
public void showCardFace() {
    cardTexture = new Texture(("CardTextures/" + this.getFace() + this.getSuit() + ".png"));
}

(in the android\assets\CardTextures there are 52 .png files with a size of 500x726 and rangeing in filesize from 20-220 kb) The problem is that when I have to show or hide the "CardFace" for the entire ArrayList like so :

            for (int i = 0; i < deck.size(); i++) {
                ((Card) deck.get(i)).hideCardFace();
            }

I experience a performance drop both on PC and Android to the point where the Game lags for 1-2 seconds until all the CardFaces are hidden or showed.(I did multiple tests and the FPS dips only when I call the 2 methods) Is there any other way (better for performance) to change the CardFace?

\$\endgroup\$
1
\$\begingroup\$

Read about the AssetManager here: https://github.com/libgdx/libgdx/wiki/Managing-your-assets

You are loading new Texture's objects with each card change which equals DEATH. What you should do is have 52 card textures in memory and 1 back card texture, so 53 textures at max.

Your code allocates new ram with every card change you make. It's unacceptable.

Create a class for all the assets for example:

public class Assets{
    private AssetManager assetMgr;
    private static HashMap<CardType, Texture> cardsTextures = new HashMap<>();
    private static Texture faceDownTexture;
    public Assets(){

        assetMgr = new AssetManager():

        // load all the 53 assets with AssetManager

        // assetMgr load...

        // and now put these values from assetManager into the map
        // make a loop or something !
        cardsTextures.put(ACE_OF_SPACES, aceofspadestexture);
        cardsTextures.put(THREE_OF_SPACES, aceofspadestexture);
        cardsTextures.put(SEVEN_OF_SPACES, aceofspadestexture);

        // load faceDownTexture texture for example
        faceDownTexture = new Texture(Gdx.files.internal("cards/facedown.png"));

        cardsTextures.put(FACE_DOWN, faceDownTexture);
    }

    // a method that will give you your textures from anywhere in the code

    public static Texture getCardTexture(CardType type){
        return cardTextures.get(type);
    }

    public static Texture getBackTexture(){
        return backTexture;
    }

}

Use the class above to load all these textures with AssetManager and create your card class like this:

public class Card{

    private Texture cardTexture, backTexture;
    private boolean isFaceUp;

    public Card(CardType type){

        cardTexture = Assets.getCardTexture(type);
        backTexture = Assets.getBackTexture();

        isFaceUp = false;

        setSize(cardTexture.getWidth(), cardTexture.getHeight());

    }

    @Override
    public void draw(Batch batch, float parentAlpha){
        if(isFaceUp)
            batch.draw(cardTexture, getX(), getY(), getWidth(), getHeight());
        else batch.draw(backTexture, getX(), getY(), getWidth(), getHeight());

    }


    public void showFaceUp(boolean b){
        this.isFaceUp = b;
    }
}

This is all pseudocode, but this is the right way.

Then, your 'switching' code should look like this:

// 10000 nanoseconds and 0 RAM!
for (int i = 0; i < deck.size(); i++) {
    ((Card) deck.get(i)).showFaceUp(false);
}
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.