Level tree method?

Hello everyone!
I am still developing my game and i got another problem. Is there any way to create a level “tree” like the one i have in image? A am loading every level from another image. Here is the example i need.

http://imageshack.us/photo/my-images/812/85362882.png

http://imageshack.us/photo/my-images/812/85362882.png/

The green zones are the zones i already linked. The linking between chambers are some “portals” that load a specific level (for example, the left portal on “start” map teleports you to the left map(the linking is done manually) and the right portal in the left map teleports you to the “start” map).

Your “chambers” class could have 4 references to “portals”, one for each side. This way, it’s very dynamic.

I am already doing this, but i don’t know how to make it dynamic. Now i use these to make portals:


                if(currentLevel == levels.get(0)) {
                	 Level.others.add(new Teleporter((w-1)/2*32, (h-2)*32, (Level) levels.get(1)));
	                Level.others.add(new Teleporter(w/2*32, (h-2)*32, (Level) levels.get(1)));
                	
	                Level.others.add(new Teleporter(32, (h-1)/2*32, (Level) levels.get(2)));
	                Level.others.add(new Teleporter(32, h/2*32, (Level) levels.get(2)));

	                Level.others.add(new Teleporter((w-1)/2*32, 32, (Level) levels.get(3)));
	                Level.others.add(new Teleporter(w/2*32, 32, (Level) levels.get(3)));
	                
	                Level.others.add(new Teleporter((w-2)*32, (h-1)/2*32, (Level) levels.get(4)));
	                Level.others.add(new Teleporter((w-2)*32, h/2*32, (Level) levels.get(4)));
                } else if(currentLevel == levels.get(1)) {
                	Level.others.add(new Teleporter((w-1)/2*32, 32, (Level) levels.get(0)));
	                Level.others.add(new Teleporter(w/2*32, 32, (Level) levels.get(0)));
                } else if(currentLevel == levels.get(2)) {
                	Level.others.add(new Teleporter((w-2)*32, (h-1)/2*32, (Level) levels.get(0)));
	                Level.others.add(new Teleporter((w-2)*32, h/2*32, (Level) levels.get(0)));
                } else if(currentLevel == levels.get(3)) {
                	Level.others.add(new Teleporter((w-1)/2*32, (h-2)*32, (Level) levels.get(0)));
	                Level.others.add(new Teleporter(w/2*32, (h-2)*32, (Level) levels.get(0)));
                } else if(currentLevel == levels.get(4)) {
                	Level.others.add(new Teleporter(32, (h-1)/2*32, (Level) levels.get(0)));
	                Level.others.add(new Teleporter(32, h/2*32, (Level) levels.get(0)));
                }

Why is “others” static?!

Also, I see you are casting when retrieving from an ArrayList; you’re not using generics properly.

I’m not using ArrayList, i implemented a bag to store everything.

Then use generics on that Bag so you won’t have to cast everywhere.

Why do you have a static “others” bag in Level? As I mentioned before, you should have 4 Teleporter variables named north,south,east,west in Level and this way you can dynamically create Level.

What is the static class Level?

In my game, Level is an object that contains some Bags of tiles, levelImage and levelTexture. I am going to change the statics to normal variables.

EDIT: Okay, so i think that i don’t know when to use static. When a player steps into a portal, i use my levelLoader to load a new level. Now my question: When i want to refer to this levelLoader class in…let’s say…entity class, is it okay to make a new reference to levelLoader in this class? I think, no, so i have to make a static variable in my GameLauncher class with the current level. I am right?

You could apply the singleton pattern, when you wan’t to have exactly one instance of the class… I use something like this:


class LevelLoader
{
  private static LevelLoader levelLoader;

  public static LevelLoader get()
  {
    if(levelLoader == null)
      levelLoader = new LevelLoader();
    return levelLoader;
  }

  private LevelLoader()
  {
  }
}

with the private constructor, you make sure that the class cannot be constructed anywhere else. Then If you want to use the loader, you simply call LevelLoader.get() to get the instance. You could also add some initialization code into the if block in the get method, so the loader is initialized with the correct parameters… hope that helps

Thanks!

So, how could i store the levels so i can dynamically create the linkings to portals???

Currently i have this:

package com.game.level;

import java.awt.image.BufferedImage;

import com.game.entity.Player;
import com.game.level.buildings.Teleporter;
import com.game.level.tiles.Tile;
import com.game.util.Bag;

public class Level {
	int levelWidth, levelHeight;
	Tile[] tiles;
	int maxEnemy;
	Bag enemy, unpassableTiles, passableTiles, others;
	Player player;
	BufferedImage levelImage;
	String levelName;
	BufferedImage[][] levelTexture;
	public Teleporter north, south, west, east;
	
	public Level(BufferedImage image, int enemies, BufferedImage[][] texture) {
		levelImage = image;
		maxEnemy = enemies;
		levelTexture = texture;
		levelWidth = levelImage.getWidth();
		levelHeight = levelImage.getHeight();
		
		north = new Teleporter((levelWidth-1)/2*32, 32, 64, 32, null/*WHERE???*/);
		south = new Teleporter((levelWidth-1)/2*32, (levelHeight-2)*32, 64, 32, null/*WHERE???*/);
		west = new Teleporter(32, (levelHeight-1)/2*32, 32, 64, null/*WHERE???*/);
		east = new Teleporter((levelWidth-2)*32, (levelHeight-1)/2*32, 32, 64, null/*WHERE???*/);
	}
	
	//GETTERS AND SETTERS
	public int getMaxEnemy() { return maxEnemy; }
	public int getLevelWidth() { return levelWidth; }
	public int getLevelHeight() { return levelHeight; }
	public Tile[] getTiles() { return tiles; }
	public Bag getEnemy() { return enemy; }
	public Bag getUnpassableTiles() { return unpassableTiles; }
	public Bag getPassableTiles() { return passableTiles; }
	public Bag getOthers() { return others; }
	public Player getPlayer() { return player; }
	public BufferedImage[][] getLevelTexture() { return levelTexture; }
	//GETTERS AND SETTERS
}

either specifie for each level only a strict nummber of portals to other levels, like ranking said.
and then just do something like


Level current;

...found out that the player wants to travel to east..

current = current.getEastLevel();

or you could do it totaly generic where you just place portal entitys in your levels and when a player enters/uses one teleporter ask that teleporter were to go.


class Portal
{
  Level destination;

  use()
  {
    game.setCurrentLevel(destination);
  }

}

In either case you somehow must setup this Level graph at the beginnning of the game, normally you would want to create your levels with some level editor and save them in some configuration file.
This file can be read at the start of the game and set up all the levels and their connections.

sorry accidental appreciate. Enjoy! :stuck_out_tongue:

Concerning levels, your game manager holds the reference of the current level. When the user goes east, it loads the level that is reference in the current level’s east variable.


public class Level {
    private Level north, south, east, west;

    /* getters and setters for levels */
}

/* in player class's update method */
If goes north
    gameManager.load(Direction.NORTH); //Direction would be an enumerated type
....

/* in GameManager.load */
public void load(Direction dir) {
    switch(dir) {
        case NORTH: currentLevel = currentLevel.getNorth(); break;
        case SOUTH: currentLevel =  currentLevel.getSouth(); break;
        .....
        default: return;
    }
    
    currentLevel.init();
}

sry ranking,
but i think , this is not such a good idea.

You are outsourceing resposibility and implementations details out of the level class to the gameloader.

just get the needed next level from the current level and initialize it.

The manager is responsible for managing the levels. The only thing in Level should only concern Level.