Setting Sprites

This next section will be about your sprites and creating SpriteSheets. To work with sprites in LibGDX you need a LibGDX tool called ‘TexturePacker’

Texture Packer

Download it here: https://github.com/crashinvaders/gdx-texture-packer-gui/releases

  • Install the newest .zip version.
  • Make sure that your Java version is 1.8.
    • To check, first run java -version in your Terminal (Terminal can be opened using Spotlight Search)
    • If it says something that has 1.8 in the beginning like so: java version "1.8.0_231", then you’re set.
    • Otherwise type: export JAVA_HOME=/usr/libexec/java_home -v 1.8 to switch your Java version.
Your Terminal will look something like this.

The TexturePacker will take multiple sprite images and combine them together into one full image. It will also generate a reference file called an Atlas. The atlas has a title for each sprite’s images sectioned off with different coordinates in order to make it easier for your code to reference.

Before starting, find all the sprites you need using https://www.spriters-resource.com/, or any other site you want. When downloading the sprites, it is advisable to have the sprites appear on a transparent background. Download the sprites into a new folder, like so:

To start packing textures, nzip your TexturePacker and open the .jar file with ‘Jar Launcher.app’. Then you should see the screen below.

To create a new pack, click the top left button and name the pack something along the line of ‘Sprites’ or ‘game_sprites’.

Then select add input files and choose your folder of sprites.

Add an output directory (where you want the generated files to be stored) and change the file name if you want.

Then click pack all.

This should then generate an image with all the sprites together and also an Atlas in your selected output directory.

Combined Image
Atlas File

Finally, to add them to your game, copy and paste them into your ‘assets’ folder under ‘android’.

Setting a Sprite

In your Constants class, you should add the name of your atlas as well as the name of each sprite in your atlas. For this example, I’ve only added one of the sprites but you may want to just add them all now for convenience later on.

Additionally, you should make sure your Game class has the variable private SpriteBatch batch; and to create the getter method for this variable.

public SpriteBatch getBatch()
{
   return batch;
}

In your Screen class (which might be called LevelOne or something else), create a private TextureAtlas atlas; and initialize it: atlas = new TextureAtlas(Constants.ATLAS_FILENAME);. For a TextureAtlas we have to pass in a String which is the name of the atlas that you packed earlier, however since you should have added it to constants, you can simply call the constant’s variable.

You should also make a getter method for your atlas:

public TextureAtlas getAtlas(){
return atlas;
}

The last thing to do for now in your Screen class is to change the Player variable’s initialization by passing in your Screen in addition to the World. Because Player is initialized within a Screen, you can simply pass in ‘this’.

player = new Player(world, this);

In your Player class, you need to initialize a TextureRegion and some variables to handle the ‘STATE’ your player is in. ‘STATE’ is an enum which is a special data type that enables for a variable to be a set of predefined constants. For now, the only State you need is ‘STANDING’ or ‘IDLE’ where your player isn’t moving. Also, create a currentState variable to track what state the player is currently in and a boolean to track if the player is facing a certain direction (this boolean is only if you want to flip your image when the player is moving to the left).

//texture regions
private TextureRegion playerIdleTexture;

//states
public enum State {STANDING};
public State currentState;
private boolean runningToRight;

Then call super(screen.getAtlas().findRegion(Constants.PLAYER_STRING); where PLAYER_STRING is the name of your player sprite from your Atlas. Because Player extends Sprite, you can set a region of your atlas to your Player’s sprite.

Next, set these as well in the constructor. ‘TextureRegion’ will take in a string of the player’s sprite name and also the (x, y, width, height) of your player sprite. In my case, the player starts at (0, 0) and his sprite is 16 by 16 pixels.

currentState = State.STANDING;
runningToRight = true;
//player idle texture region
playerIdleTexture = new TextureRegion(screen.getAtlas().findRegion(Constants.PLAYER_STRING), 0, 0, 16, 16);

Then it’s time to set the bounds and region for your sprites to show up. ‘setBounds()’ confines the image of your sprite to a specific area, while ‘setRegion()’ sets the TextureRegion to whatever you specify.

//add these 
setBounds(0, 0, 16, 16);
setRegion(playerIdleTexture);

Next, to prepare for animating the sprites, you should create a ‘getFrame()’ method. This method will return the frame, namely a TextureRegion, needed for display depending on the state your Player is in. ‘getState()’ is a method we will make later, it simply returns the State the player is currently in. As of now, we only have one State so there is only one case in the switch case.

Switch Case: For those who might not know, a ‘switch’ case is basically an ‘if’ statement. It takes an argument (in this case the currentState) and checks what it is. Then depending on what it is, the switch case will execute some code. If the switch case doesn’t have a matching condition, it will execute the default code (this is basically the ‘else’ part of the switch statement). Another thing that is special to ‘switch’ statements is that it needs ‘breaks;’ after each case. This might sound annoying but it lets you do something like what’s seen below, where you can have multiple cases end up with the same executed code.

The switch case will return the particular frame you want at that moment for your player. The next thing is to check if your player is facing the left or right so you can flip the texture to match. Essentially, if your player’s velocity is negative in the ‘x’ direction, it’s moving to the left. Additionally, ‘!runningToRight’ will return true if the player is moving to the left. After checking these 2 conditions, if the region texture is not already flipped, then flip the sprite. This idea is the opposite when the player is facing right. After all this is done, this method will return the manipulated texture.

//returns appropriate frame needed to display as sprite's texture region
    private TextureRegion getFrame(float deltaT)
    {
        currentState = getState();
        TextureRegion region;
        switch(currentState)
        {
            //no breaks for next 2 cases because the following code applies to all 3 cases
            case STANDING:
            //no break needed here because STANDING and 'default' will do the same thing.
            default:
                region = playerIdleTexture;
                break;
        }

        //region.isFlipX() = true if texture is flipped i.e. Player running to left
        //if Player is standing facing right, flip them and run to left
        if((box2Body.getLinearVelocity().x < 0 || !runningToRight) && !region.isFlipX())
        {
            region.flip(true, false);
            runningToRight = false;
        }
        //if Player is standing facing left, flip them and run to right
        else if((box2Body.getLinearVelocity().x > 0 || runningToRight) && region.isFlipX())
        {
            region.flip(true, false);
            runningToRight = true;
        }
        return region;
    }

Now to create ‘getState()’. For now, it’s simple because we only have one state but it’s needed later on for animation.

public State getState()
    {
        return State.STANDING;
    }

Lastly, an update method to continually move the sprite every frame.

public void update(float deltaTime)
{
    //set to position of bottom left corner of box2dbody
    setPosition(box2Body.getPosition().x - getWidth() / 2, box2Body.getPosition().y - getHeight() / 2);
    setRegion(getFrame(deltaTime));
}

Then call the Player class’s update() method in your Screen’s update method like so: player.update(deltaTime); also, remember to pass in the deltaTime from your Screen class’s update method.

Lastly, add the line below to your render() method in your Screen class.

player.draw(myGame.getBatch());

Then you should be able to see your character’s sprite! (even though he won’t be animated quite yet)

Mario is here now.

Video Lesson