0
\$\begingroup\$

I am making a top down style game using LibGdx that I want to be randomly generated each new game load.

I already have the algorithm to generate the array for what tile should be what.

But i'm stuck on how I should handle the tile classes.

I have this class called Tile

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


public class Tile extends Sprite{ // Should I use sprite??? Seems wrong..

public byte id;

public static Tile[] tiles = new Tile[256];

public static Tile grass = new GrassTile(0);

public Tile(int id) {
    this.id = (byte) id;
    if (tiles[id] != null)
        throw new RuntimeException("Tile Already Exists....");
    tiles[id] = this;
}

}

And I want to have multiple classes that exened this class for each tile. For example this is grass.

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


public class Tile extends Sprite{

public byte id;

public static Tile[] tiles = new Tile[256];

public static Tile grass = new GrassTile(0);

public Tile(int id) {
    this.id = (byte) id;
    if (tiles[id] != null)
        throw new RuntimeException("Tile Already Exists....");
    tiles[id] = this;
}

}

Should these classes be extended off of a sprite? Or some other class from libgdx?

Also These tiles are going to be 16 x 16 that are made up of 4 smaller 8x8 sprites.

\$\endgroup\$
4
  • \$\begingroup\$ I'm not sure what you are trying to accomplish. What is happening right now? And what do you want to happen? \$\endgroup\$ Apr 29, 2015 at 20:43
  • \$\begingroup\$ Nothing is happening now. I could follow though with the sprite method. I just wanted to know the most efficient way of creating my maps. Should all ground tiles be sprites or some other type of class. \$\endgroup\$
    – Snhp9
    Apr 29, 2015 at 20:44
  • \$\begingroup\$ The tiles for the land also will change based on player interaction . \$\endgroup\$
    – Snhp9
    Apr 29, 2015 at 20:45
  • \$\begingroup\$ Perhaps a better way to put it is I want to generate a tmx without a tmx. \$\endgroup\$
    – Snhp9
    Apr 29, 2015 at 20:48

2 Answers 2

1
\$\begingroup\$

Think about having only one final Tile class and it defines only the data needed to render and update like the id of the Sprite or TextureRegion

public class Tile {

    private int type;
    private int spriteId;

    some other data that you need and that belongs to a Tile
    ...

    public int getType() {
        return type;
    }

    public int getSpriteId() {
        return spriteId;
    }

    public void setSpriteId() {
        this.spriteId = spriteId
    }

}

Then you can have a TileMap class with a array of tiles like this:

public class TileMap implements Iterable<Tile> {

    private int width;
    private int height;
    private Tile[][] tiles;

    public void setTile( Tile tile, int xpos, int ypos ) {
        tiles[ ypos ][ xpos ] = tile;
    }

    public Tile getTile( int xpos, int ypos ) {
        return tiles[ ypos ][ ypos ];
    }

    ...

    public Iterator<Tile> iterator() {
        ... create your iterator for the array
    }

    ....

}

And a TileMapRenderer that has access to a SpriteProvider that contains the sprites in a map within its ids;

public class TileMapRenderer() {

    private SpriteProvider spriteProvider;
    private SpriteBatch spriteBatch;

    public TileMapRenderer( SpriteProvider spriteProvider, SpriteBatch spriteBatch ) {
        this.spriteProvider = spriteProvider;
        this.spriteBatch = spriteBatch;
    }

    public void render( TileMap tileMap ) {
        for ( Tile tile : timeMap ) {
            spriteBatch.draw( spriteProvider.getSprite( tile.getSpriteId() ) );
        }
    }

}

It is always good to avoid static classes or fields! always try to inject things you need in objects within the constructor or setters. This is just a short sketch and the code is not compiling but should give an basic idea.

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

Having all Tiles be Actors that draw their sprite in the Actor's draw() call is an option. Of course there are many ways to draw a map, but this definitely is one of them. However I would warn against using Sprites.

Since you said all tiles are 16x16px you will likely have very many of them in each level of your game. This would mean that you would have very, very many Sprites.

What I would advise is for you to use Textures because these are very basic objects that do not hold any data besides their image, which means you can easily recycle them. What I do for my games is have one local class that handles all of my textures, because I do not want to be creating a new Texture for every Tile, if they are using the same image.

I have a class that looks exactly like this:

class TexturePool implements Disposable {
    private ObjectMap<String, Texture> textures;

    public TexturePool() {
        textures = new ObjectMap<String, Texture>();
    }

    public Texture getTexture(String path) {
        Texture t = textures.get(path);
        if(t == null) {
            t = new Texture(Gdx.files.internal(path));
            textures.put(path, t);
        }

        return t;
    }

    public void clearAll() {
        Entries<String, Texture> e = new Entries<String, Texture>(textures);

        while(e.hasNext()) {
            e.next().value.dispose();
        }
        textures.clear();
    }

    @Override
    public void dispose() {
        clearAll();
    }
}

With this class I can very easily ask it for a Texture, and if the Texture has already been loaded it will give it to me, if it has not yet been loaded, then it will be, and it will also be added to the ObjectMap for later use. This ensures you only load each texture exactly once and can re-use them for every Tile (just store a reference to the Texture in each Tile and draw it at the Tile's position in its draw call).

\$\endgroup\$
2
  • \$\begingroup\$ Seems like a neat way of doing it. So i'm guessing you have a file for each texture then? \$\endgroup\$
    – Snhp9
    Apr 29, 2015 at 20:56
  • \$\begingroup\$ I do where I am right now in my development, but of course you can always adapt this for Texture maps (just add texture coordinates and size to the arguments). Check this out. The wiki page talks about managing your assets with libGdx's AssetManager. \$\endgroup\$ Apr 29, 2015 at 21:02

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .