Problem with the way I load levels

Hello,
this is the code I load the levels with :


	private void LoadImageLevel(BufferedImage image) {
		int w = image.getWidth();
		int h = image.getHeight();

		for (int xx = 0; xx < h; xx++) {
			for (int yy = 0; yy < w; yy++) {
				int pixel = image.getRGB(xx, yy);
				int red = (pixel >> 16) & 0xff;
				int green = (pixel >> 8) & 0xff;
				int blue = (pixel) & 0xff;

				if (red == 0 && green == 0 && blue == 100) {
					handler.addObject(new Background(0, 0, ObjectId.Background)); // background
					handler.addObject(new Block(xx * 32, yy * 32, 0,
							ObjectId.Block));

				}
				if (red == 100 && green == 60 && blue == 0) { // / block
					handler.addObject(new Block(xx * 32, yy * 32, 0,
							ObjectId.Block));

				}
				if (red == 100 && green == 50 && blue == 0) { // /block 1
					handler.addObject(new Block(xx * 32, yy * 32, 1,
							ObjectId.Block));

  • many more objects.
    As you can see, Im loading the level from a png file and the problem is that the objects that are checked first are rendered first.
    Thats a problem because the character gets rendered under other objects and etc…
    My question is,how can I render the objects in layers? for example, the character is in layer 5,all the blocks are layer 4 and so on.
    Thanks !!

At the moment, is there any difference in how you are using the different colour channels? Because you could, for example, just use the value from the blue channel to signify the layer height.

Assign each object a layer. For example, have an int value in your gameobject class that tells you which layer the object is in. Just before rendering, sort your gameobjects list by that layer int value.

I found a way to do it, this is the handler render method:


	public void render(Graphics g) {
		for (int i = 0; i < object.size(); i++) {
			tempObject = object.get(i);
			if (tempObject.getId() == ObjectId.Background) {
				tempObject.render(g);
			}
		}
		for (int i = 0; i < object.size(); i++) {
			tempObject = object.get(i);
			if (tempObject.getId() == ObjectId.Block) {
				tempObject.render(g);
			}
		}
		for (int i = 0; i < object.size(); i++) {
			tempObject = object.get(i);
			if (tempObject.getId() == ObjectId.Ex) {
				tempObject.render(g);
			}
		}
		for (int i = 0; i < object.size(); i++) {
			tempObject = object.get(i);
			if (tempObject.getId() == ObjectId.Box) {
				tempObject.render(g);
			}
		}
		for (int i = 0; i < object.size(); i++) {
			tempObject = object.get(i);
			if (tempObject.getId() == ObjectId.Player) {
				tempObject.render(g);
			}
		}
		for (int i = 0; i < object.size(); i++) {
			tempObject = object.get(i);
			if (tempObject.getId() == ObjectId.ChangeableBlock) {
				tempObject.render(g);
			}
		}
		for (int i = 0; i < object.size(); i++) {
			tempObject = object.get(i);
			if (tempObject.getId() == ObjectId.Button) {
				tempObject.render(g);
			}
		}
		for (int i = 0; i < object.size(); i++) {
			tempObject = object.get(i);
			if (tempObject.getId() == ObjectId.Bodypart) {
				tempObject.render(g);
			}
		}
	}

Now that works ,every object is rendered in its own layer but I dont think thats a good way with all those loops… for now the game works great and it droped the fps by somthing like 20 so thats not so bad.
Will it cause problems later on or I can just leave it that way?

A 20 FPS drop is rather substantial. I’d recommend instead having a few separate ArrayLists for different layers of tiles, backgroundLayer, foregroundLayer etc and iterate those. Then simply draw your player separately on top. :slight_smile:

There is many solutions to your problem, having one loop for each type of object is obviously not a very dynamic solution :stuck_out_tongue:

The quick solutions are:

If the render-list is fairly static, you can implement “comparable” on layer, and then sort the list after creation.
But if you are going to change it up alot, i would go with something like a binary tree structure that automaticly “sorts” on insert.

Then you can just render everything in a single loop.

A better and more OOP solution would be:

Create a “GameMap” class.
Create a “GameLayer” class.

Make the GameMap hold N GameLayers, ex a list.
Then when you load the map, put the objects in the appropriate GameLayer.

Then you simply render one layer at a time, from bottom to top.
This also allows for better scalability.

Cheers!