Search code examples
javamobilelibgdxrotationsprite

LibGDX Rotating Sprites from a Hashmap


I'm pretty new to libGDX and java in general so I've been following a plethora of tutorials. so FEEL FREE TO CORRECT ME AT EVERY TURN! (yes even in code inefficiencies as well!!)

I currently have the issue of rotating all of the sprites of a single type instead of just a single sprite.

I'll show you how I mean:

libGDX sprite rotation issue

Here are the specifics:

  1. There are 3 different size of sprites.

  2. I use a hashmap to store the 3 sprites so I don't have to Sprite sprite = new Sprite(); every time (supposedly it's a heavy task)

  3. I create a sprite by referencing the one from the hashmap(I think?)

  4. PROBLEM: When I tell a specific sprite to rotate, it rotates each other sprite of its size.

I have a suspicion that I'm rotating the hashmap reference... If that's the right way to say it.

This is the process I've been using:

hashpmap:

final HashMap<String, Sprite> spriteMap = new HashMap<String, Sprite>();

texture atlas:

spriteAtlas = new TextureAtlas("sprites.txt");

fill hashmap with regions from texture atlas:

private void init spriteMap() {
    Array<AtlasRegion> regions = spriteAtlas.getRegions();

    for (int i = 0; i < regions.size; i++) {
        AtlasRegion region = regions.get(i);
        Sprite sprite = spriteAtlas.createSprite(region.name);

        float width = sprite.getWidth() / SCALE;
        float height = sprite.getHeight() / SCALE;

        sprite.setSize(width, height);
        sprite.setOrigin(0, 0);
        sprite.scale(1f);
        spriteMap.put(region.name, sprite);
    }
}

create sprite "instance" from hashmap:

private void createNewSprite() {
    Sprite sprite;
    sprite = spriteMap.get(name);
    sprite.setPosition(x, y);
    sprite.rotate(rotation);
    spriteArray.add(sprite);
}

Maybe I'm not actually extrapolating the sprite from the hashmap well enough? Let me know if you need anything else to figure out this conundrum.

Thank you so much!


Solution

  • You have only created a single sprite for each region name, referencing it multiple times in spriteArray. Create a new one each time:

    private void createNewSprite() {
        Sprite sprite = new Sprite(spriteMap.get(name)); //creates a new sprite that is a copy of the one in your map.
        sprite.setPosition(x, y);
        sprite.rotate(rotation);
        spriteArray.add(sprite);
    }
    

    They are only slightly heavy. Each Sprite instance has an array of 20 floats for the vertex data, which contains redundant UV data for the underlying TextureRegion, and a redundant Color object and Rectangle object. So it is heavier than creating your own class that references all these things without the redundancies.

    They are too heavy to be creating and destroying many of them during game play without using pooling.

    What would really be heavy is loading new Textures to create your Sprites instead of them all sharing a single Texture instance.

    In my opinion Libgdx Sprites are generally not good for game design because they conflate state with drawing too much, aside from the redundancies. They are useful for particles (and maybe UI elements) where the conflation is not really a design issue. In fact, I think these are the only two places Sprites are used internally in Libgdx.