Search code examples
javaanimationlibgdx2d

How to dynamically combine multiple animated spritesheets in LibGDX?


I'm making a 2D libdgx game in which an animated character starts the gamewith no clothes. then he finds clothes items on each map and by picking them up, he should wear them. Basically, after picking up an item, we should see that animated item (like underwear) on the character. I have different sprite sheets, one for each clothing item. How do I layer them without writing 100+ lines of code for animating textureRegion and frames?


Solution

  • I assume, that every animation has its own position and size.

    I suggest the following solution:

    1) Extend the Animation class, and put in there fields that hold unique parameters for animations, for example:

    public class MyAnimation extends Animation<TextureRegion> {
        private float xOffset; //x relative to the hero
        private float yOffset; //y relative to the hero
        private float width;
        private float height;
        //constructors, getters, etc.
    }
    

    2) store all your animations somewhere, for example:

    ObjectMap<String, MyAnimation> animationsByNames = new ObjectMap<String, MyAnimation>();
    animationsByNames.put(
            "heroWithoutClothes",
            new MyAnimation(0, 0, heroWidth, heroHeight, frameDuration, heroKeyframes)
    );
    animationsByNames.put(
            "underwear",
            new MyAnimation(underwearOffsetX, underwearOffsetY,underwearWidth, underwearHeight, frameDuration, underwearKeyframes)
    );
    //etc...
    

    3) store active animations in a separate Array:

    Array<MyAnimation> activeAnimations = new Array<MyAnimation>();
    //hero animation is probably always active
    activeAnimations.add(animationsByNames.get("heroWithoutClothes"));
    

    4) when hero picks up clothes, add an animation for that clothes into the activeAnimations:

    private void pickUpClothes(String clothesName) {
        activeAnimations.add(animationsByNames.get(clothesName));
    }
    

    5) finally, somewhere in your render method:

    for (int i = 0, n = activeAnimations.size; i < n; i++) {
        MyAnimation animation = activeAnimations.get(i);
        float x = heroX + animation.getXOffset();
        float y = heroY + animation.getYOffset();
        //... retrieve all other parameters, and use them to draw the animation
        //animation stateTime and frameDuration are the same for all of the animations
    }