Easy LibGDX sprite creator

I’ve used this class to death in the last couple of my LibGDX projects, and it’s been extremely helpful! I’ve even used it in a pure LWJGL project also, with some reworking. Here’s the class:

package com.nishu.balancedEnergy.entity;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.Sprite;

public class SpriteStore {
		
	public static type getType(String tileType) {
		String str = tileType;
		switch (str) {
		case "Grass":
			return type.Grass;
		case "Base":
			return type.Base;
		case "Stone":
			return type.Stone;
		case "light":
			return type.Light;
		case "bluePlayer":
			return type.bluePlayer;
		case "buttonDefault":
			return type.buttonDefault;
		case "buttonClicked":
			return type.buttonClicked;
		case "bullet-test":
			return type.Bullet;
		case "hotBar":
			return type.hotBar;
		case "hotBarSelection":
			return type.hotBarSelection;
		case "void":
			return type.voidTile;
		case "flowerGrass":
			return type.flowerGrass;
		case "water":
			return type.Water;
		case "lava":
			return type.lava;
		default:
			return type.Grass;
		}
	}

	public static Sprite createSprite(String type) {
		type tiletype = getType(type);
		if (tiletype != null) {
			Sprite s = new Sprite(getTexLoc(tiletype));
			return s;
		}
		return null;
	}

	private static Texture getTexLoc(type TileType) {
		switch (TileType) {
		case Base:
			return new Texture(Gdx.files.internal("res/tiles/base.png"));
		case Grass:
			return new Texture(Gdx.files.internal("res/tiles/grass.png"));
		case voidTile:
			return new Texture(Gdx.files.internal("res/tiles/void.png"));
		case flowerGrass:
			return new Texture(Gdx.files.internal("res/tiles/flowerGrass.png"));
		case Water:
			return new Texture(Gdx.files.internal("res/tiles/water.png"));
		case lava:
			return new Texture(Gdx.files.internal("res/tiles/lava.png"));
		case Stone:
			return new Texture(Gdx.files.internal("res/tiles/stone.png"));
		case bluePlayer:
			return new Texture(Gdx.files.internal("res/players/playerBlue.png"));
		case buttonClicked:
			return new Texture(Gdx.files.internal("res/gui/buttonClicked.png"));
		case buttonDefault:
			return new Texture(Gdx.files.internal("res/gui/buttonDefault.png"));
		case Light:
			return new Texture(Gdx.files.internal("res/tiles/light.png"));
		case Bullet:
			return new Texture(Gdx.files.internal("res/bullets/bullet-test.png"));
		case hotBar:
			return new Texture(Gdx.files.internal("res/ui/hotBar.png"));
		case hotBarSelection:
			return new Texture(Gdx.files.internal("res/ui/selectionSquare.png"));
		default:
			break;
		}
		return null;
	}

	public static enum type {
		Grass, Base, Stone, Light, Water, flowerGrass, lava, voidTile, bluePlayer, buttonDefault, buttonClicked, Bullet, hotBar, hotBarSelection;
	}
}

Basically I sort through a bunch of types in an enum, and then create a new sprite with a texture based off of the enum type. There can be some modifications, but for now, its quick and easy to create a new sprite! For instance, I can create a bunch of tiles like this:

		Sprite tile = SpriteStore.createSprite(type);

And the spritestore will create a new sprite and send the texture back with it! I can definitely do more with it, like sorting textures or using texture atlases, but I like it :slight_smile:

with OpenGL, you want less binding calls, so loading multiple textures is inefficient as you want a sprite sheet to contain all images allowing for 1 binding call.

you also would want a texture that is global and can be used to grab the texture from one image, this will allow for only one image to be loaded for all tiles.

what you would want to return is really just the texture location within the single image.

in OpenGL the max width is a value of 1, and the min width is 0 and the same for height.

EDIT: fixed a slight mistake

I know, honestly I do. I’ve been meaning to get around to it, but this has been fine for me for a while, so I thought I’d share it for other people to change and use if they want. I’m going to sort my draw calls soon so that only one texture is ever bound once, and I’ll be using a spritesheet. Thanks for the feedback!

I like this, I use a simple id system that returns the block when the number is called, but this is way better ;D. I don’t really use Switch/Case statements a lot in my code though

I absolutely love switch statements, especially the String comparison, it makes the code seem cleaner and its so much easier to code with them. No problem, by the way! It needs a serious rework though to optimize it.

I’m probably missing something, but what is precisely the point of this class? How does this work better than:

Sprite tile = new Sprite(new Texture(Gdx.files.internal("res/tiles/"+tile+".png"));

? Why use all the switch statements and the enums?

Also, LibGDX has pretty nice support for asset management through the AssetManager class. This has the added bonus of allowing you to easily preload all textures and reuse textures that were loaded already.

yeah, I’m wondering if you posted on purpose to hear that your code is bad?

Some comments:

  • using enums in your code instead of strings is good of course, but you are doing string->enum->string
  • checking a nonnull value for null
  • returning null
  • using switch case for enum lookup(never heard of valueOf(“blubb”)?)
  • using switch for enum->, just add a string field to the enum.
  • you have to cache the textures
  • just use the things libgdx provides for you

Alright, I’m sorry I just wanted to post something that I had been, ahem, WORKING, on. It wasn’t finished, and I know its not the most efficient, but I’ve used it with other libraries other than LibGDX too, so it is useful. Everyone doesn’t need to come bash on my code because its inefficient, I already know, and openly state it, so come on.

Thank you for the specific things that are wrong with it though, I can use those to make the class better.

If you want to go with an enum type approach another option is to attach the methods directly to the enum itself. Something like:



public enum Sprites {

	Rock("res/tiles/","rock.png"),
	Paper("res/tiles/","paper.png"),
	VoidTile("res/tiles/","void.png");
	
	
	private String imageFilePath;
	
	SpriteType(String path, String fileName) {
		imageFilePath = path + fileName;
	}
	
	
	public Sprite getSprite() {
		return new Sprite(new Texture(imageFilePath));
	}
}

Then you could call it by saying Sprite myRock = Sprites.Rock.getSprite();. This doesn’t negate some of the other criticisms people have with the approach (caching, using pre-built solutions) but it is easier to use and doesn’t involve multiple expanding switch statements.