[LibGDX] Storing Leveldata in 2D Arrays

I am pretty new to LibGDX and game developing in general and i am currently writing my first game (a breakout clone) with LibGDX.

I have tried to store the Leveldata (positions of Blocks) in a 2-dimensional array like this:


// 1 = block, 0 = empty
levelArray = new int[][] {
		{0,0,0,0,0,0,0,0,0,0,0,0},
		{0,0,0,0,0,0,0,0,0,0,0,0},
		{0,0,0,0,0,0,0,0,0,0,0,0},
		{0,0,0,0,0,0,0,0,0,0,0,0},
		{0,0,0,0,0,0,0,0,0,0,0,0},
		{0,0,0,0,0,0,0,0,0,0,0,0},
		{0,0,0,0,0,0,0,0,0,0,0,0},
		{0,0,0,0,0,0,0,0,0,0,0,0},
		{0,0,0,0,0,0,0,0,0,0,0,0},
		{0,0,0,0,0,0,0,0,0,0,0,0},
		{0,0,0,0,0,0,0,0,0,0,0,0},
		{0,0,0,0,0,0,0,0,0,0,0,0},
		{0,0,0,0,0,0,0,0,0,0,0,0},
		{0,0,0,0,0,0,0,0,0,0,0,0},
		{0,0,0,0,0,0,0,0,0,0,0,0},
		{0,0,0,0,0,0,0,0,0,0,0,0},
		{0,0,0,0,0,0,0,0,0,0,0,0},
		{1,1,1,1,1,1,1,1,1,1,1,1},
		{0,0,0,0,0,0,0,0,0,0,0,0},
		{0,0,0,0,0,0,0,0,0,0,0,0}
};

Currently there are only normal blocks, that can be destroyed by the ball. In the future i will implement unbreakable blocks and blocks that drop upgrades like more balls or balls that break through blocks.

When a new game (or level) is created i iterate over the Array and create the blocks like this:


brickStorage = BrickStorage.getInstance();
for(int y = 0; y < levelArray.length; y++) {
	for(int x = 1; x < levelArray[y].length; x++) {
		if(levelArray[y][x] == 1)
			brickStorage.add(
				new Brick((x*BRICK_WIDTH+MAP_EDGE)/PIXEL_TO_METER,(y*BRICK_HEIGHT-MAP_EDGE)/PIXEL_TO_METER));
	}
}

My question now is, if i want to create a new level i have to write another array. Is there a better way to store Block positions and types when loading a new level?

If further code is needed i will of course edit it here :slight_smile:

I use classes to denote levels. For example,


public class Map01 extends MapInfo
{
    public Map01()
    {
        MapData = "BBBBBBBBBBBBBBBBB\n" +
                  "B               B\n" +
                  "B  S  S   S  S  B\n" +
                  "B S S S S S S S B\n" +
                  "B S S S S S S S B\n" +
                  "B S S S S S S S B\n" +
                  "B  S  S   S  S  B\n" +
                  "B               B\n" +
                  "B       o       B\n" +
                  "B        b      B\n" +
                  "BBBBBBBBBBBBBBBBB";
        MapLoader = Game.MapLoader;
    }
}

And MapLoader has method called [icode]getObject()[/icode] in which I hardcode the objects.


public class MapLoader extends BasicMapLoader
{
    public GObject getObject(char id, int tileX, int tileY)
    {
        switch (id)
        {
            case 'B':  return new Block(tileX, tileY); break;
            case ' ':  return null; break;
            case 'S':  return new Stone(tileX, tileY); break;
            case 'o':  return new Ball(tileX, tileY); break;
            case 'b':  return new Bat(tileX, tileY); break;
        }
    }
}

And here is my [icode]loadMap()[/icode] method.


public void loadMap(MapInfo map)
{
    int tileX = 0;  int tileY = 0;
    int tileSize = 32;   // Fixed for my game

    currentMap.destroyAllObjects();

    for (char ch : map.MapData.toCharArray())
    {
        if (ch == '\n')
        {
            tileY += tileSize;
            tileX = 0;
            continue;
        }

        GObject obj = map.MapLoader.getObject(ch, tileX, tileY);

        if (obj != null)
            currentMap.addObject(obj);

        tileX += tileSize;
    }
}

This works and is easier for me to change maps. You can guess what the other objects has.

Thank you for pointing my to a better direction. I will come up with my own solution to this and then post it here as a refernce for other ppl :).

I would use files to store the level data. You could then load a certain file based on the level you want.

@Longarmx

Using files is easier too. But I prefer classes because I don’t want others to edit my levels.

If people really wanted to, they could edit your classes :wink:

@Longarmx

That’s a possibility too. But it may be a bit enough from getting edited by common players. I can still obfuscate my code using progaurd.

I now have my own solution (well pretty much as it has been very inspired by SHCs solution^^)

I create a class for each Level:


public class Level1 extends BasicLevel {
	public Level1() {
		levelData = "MMMMMMMMMMMMMM\n" +
					"MMMMMMMMMMMMMM\n" +
					"EEEEEEEEEEEEEE\n" +
					"E            E\n" +
					"E BBBBBBBBBB E\n" +
					"E BBBBBBBBBB E\n" + 
					"E BBBBBBBBBB E\n" +
					"E BBBBBBBBBB E\n" +
					"E            E\n" +
					"EEEEEEEEEEEEEE\n";
	}
}

After trying it with 2D-Arrays i figured SHCs solution is much easier to handle so i use chars to figure out where to put everything…

Every Level is initialised when the game is started in a Storage and there put into an ArrayList. That way i can get every level by just calling:


levelStorage.getLevel(1) //returns level 1

The current level is also saved as an int value in the Storage class, so that i can change to the next level by just adding 1 :).

@sirkarpfen

You can also make a MapManager. You can see mine here MapInfo.java. You can even extend it to make layered maps. Make sure you read that package’s every class.

Well for my purpose the storage is enough. If i will sometimes create more complex maps i will think about actually writing a MapManager :).