Tilemap NullPointerException

I have a World that contains chunks. When you walk out of the screen the world loads another chunk (like the first Zelda game). But when I try to load a chunk that already exists I get an NullPointerException. My chunks contain 300 tiles (32X32 textures).
Loading a new chunk does not give errors.

Error:

Exception in thread "main" java.lang.NullPointerException
	at com.jakibah.infinyvale.World.Update(World.java:114)
	at com.jakibah.infinyvale.Game.Update(Game.java:39)
	at com.jakibah.infinyvale.Canvas.CreateCanvas(Canvas.java:41)
	at com.jakibah.infinyvale.Game.main(Game.java:17)

World class:





public class World {

	private File file;
	private String world;
	private boolean newworld;
	private int loadedchunk;
	private BufferedWriter worldwriter = null;
	private Chunk ChunktoLoad;
	private boolean First = true;

	public World(String world) throws IOException {
		this.world = world;
		file = new File("worlds/" + world + ".world");
		if (!file.exists()) {
			newworld = true;
			file.createNewFile();
			worldwriter = Files.newBufferedWriter(file.toPath(),
					StandardCharsets.UTF_8, StandardOpenOption.APPEND);

			worldwriter.write("loadedchunk: " + 0);
			worldwriter.flush();

		} else {
			worldwriter = Files.newBufferedWriter(file.toPath(),
					StandardCharsets.UTF_8, StandardOpenOption.APPEND);
			newworld = false;

			List<String> lines = Files.readAllLines(file.toPath(),
					StandardCharsets.UTF_8);
			loadedchunk = Integer.parseInt(lines.get(0).substring(13,
					lines.get(0).length()));

		}

	}

	public void Update() throws IOException {
		HandlePlayerScreen();
		List<String> lines = Files.readAllLines(file.toPath(),
				StandardCharsets.UTF_8);
		if (!lines.contains("chunk: " + loadedchunk + " (")) {
			// one character is 1 byte 1 chunk = 917 bytes = 0,917 kb = 0,000917
			// mb
			// 1 gb world = 1090513 chunks
			// 1 mb world = 1090 chunks

			System.out.println(loadedchunk);
			worldwriter.newLine();
			ChunktoLoad = new Chunk(loadedchunk);
			worldwriter.write("chunk: " + loadedchunk + " (");
			worldwriter.newLine();
			worldwriter.write("map: ");

			for (int i = 0; i < ChunktoLoad.getMap().length; i++) {
				for (int j = 0; j < ChunktoLoad.getMap()[i].length; j++) {
					int towrite = 0;
					Tile t = ChunktoLoad.map[i][j];
					switch (t.getType()) {
					case Test:
						towrite = 0;
						break;
					}
					worldwriter.write(towrite + ", ");
					System.out.println("Loading new Chunk");
				}
			}
			First = false;
			
			worldwriter.flush();
		} else {
			if (First == true) {
				int x = lines.indexOf("chunk: " + loadedchunk + " (");
				x = x + 1;
				String s = lines.get(x);
				s = s.substring(5, s.length() - 2);
				char[] c = s.toCharArray();
				int TilesWide = Display.getWidth() / 32;
				int TileHeight = Display.getHeight() / 32;
				int[][] newMap = new int[TilesWide][TileHeight];
				for (Character character : c) {
					if (character != ',' && character != ' ') {
						int towrite = Integer.parseInt(character.toString());
						for (int i = 0; i < newMap.length; i++) {
							for (int j = 0; j < newMap[i].length; j++) {
								newMap[i][j] = towrite;
							}
						}
					}
				}

				Chunk ChunktoLoad = new Chunk(newMap, loadedchunk);

				First = false;
				
			}
		}
		
		ChunktoLoad.Update();
		System.out.println(ChunktoLoad.getID());
	}

	public void HandlePlayerScreen() {
		if (Game.p.getX() >= Display.getWidth()) {
			Game.p.setX(1);
			loadedchunk++;
			First = true;
		}
		if (Game.p.getX() <= -32) {
			Game.p.setX(Display.getWidth() - 32);
			loadedchunk--;
			First = true;
		}
		if (Game.p.getY() <= -32) {
			Game.p.setY(Display.getHeight() - 32);
			loadedchunk = loadedchunk + 100;
			First = true;
		}
		if (Game.p.getY() >= Display.getHeight()) {
			Game.p.setY(1);
			loadedchunk = loadedchunk - 100;
			First = true;
		}
	}

	public File getFile() {
		return file;
	}

	public void setFile(File file) {
		this.file = file;
	}

	public String getWorld() {
		return world;
	}

	public boolean isNewworld() {
		return newworld;
	}

	public int getLoadedchunk() {
		return loadedchunk;
	}

	public void setLoadedchunk(int loadedchunk) {
		this.loadedchunk = loadedchunk;
	}

}

Chunk class:

public class Chunk {

	public Tile[][] map;
	private int TilesWide, TileHeight;
	public ArrayList<Item> items = new ArrayList<Item>();
	public ArrayList<Item> itemstoremove = new ArrayList<Item>();
	private int ID;
	private int[][] newMap;

	public Chunk(int ID) {
        this.ID = ID;
		this.TilesWide = Display.getWidth() / 32;
		this.TileHeight = Display.getHeight() / 32;
		map = new Tile[TilesWide][TileHeight];
		for (int i = 0; i < map.length; i++) {
			for (int j = 0; j < map[i].length; j++) {
				map[i][j] = new Tile(TileType.Test, i * 32, j * 32, 32);
			}
		}
	}

	public Chunk(int[][] newMap, int ID) {
		this.ID = ID;
		this.TilesWide = newMap[0].length;
		this.TileHeight = newMap.length;
		this.newMap = newMap;
		map = new Tile[TilesWide][TileHeight];
		for (int i = 0; i < map.length; i++) {
			for (int j = 0; j < map[i].length; j++) {
				switch (newMap[j][i]) {
				case 0:
					map[i][j] = new Tile(TileType.Test, i * 32, j * 32, 32);
					break;
				}

			}
		}
	}

	public void HandleItems() {
		items.removeAll(itemstoremove);
		itemstoremove.clear();
		if (!items.isEmpty()) {
			for (Item i : items) {
				i.Update();
			}
		}
	}

	public Tile GetTile(int xplace, int yplace) {

		if (xplace < TilesWide && yplace < TileHeight && xplace > -1
				&& yplace > -1)
			return map[xplace][yplace];
		else
			return null;
	}

	public void Update() {
		for (int i = 0; i < map.length; i++) {
			for (int j = 0; j < map[i].length; j++) {
				Tile t = map[i][j];
				t.Update();
			}
		}
		HandleItems();
	}

	public Tile[][] getMap() {
		return map;
	}

	public void setMap(Tile[][] map) {
		this.map = map;
	}

	public int getTilesWide() {
		return TilesWide;
	}

	public void setTilesWide(int tilesWide) {
		TilesWide = tilesWide;
	}

	public int getTileHeight() {
		return TileHeight;
	}

	public void setTileHeight(int tileHeight) {
		TileHeight = tileHeight;
	}

	public ArrayList<Item> getItems() {
		return items;
	}

	public void setItems(ArrayList<Item> items) {
		this.items = items;
	}

	public int getID() {
		return ID;
	}

	public void setID(int iD) {
		ID = iD;
	}

	public int[][] getNewMap() {
		return newMap;
	}

	public void setNewMap(int[][] newMap) {
		this.newMap = newMap;
	}

}

World file: http://pastebin.com/u3t9CsSP

Line 30, Chunk.java looks suspiciously:


switch (newMap[j][i]) {

What is with that line?

Since all the imports are missing and the package declaration is missing: which line of the exception (World.java:114) is it exactly?
Apparently something is null there :wink:

line 114: ChunktoLoad.Update();

Just newMap[i] [j] is expected. Just a warning.

Now I get this error.

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 15
	at com.jakibah.infinyvale.Chunk.<init>(Chunk.java:38)
	at com.jakibah.infinyvale.World.Update(World.java:107)
	at com.jakibah.infinyvale.Game.Update(Game.java:38)
	at com.jakibah.infinyvale.Canvas.CreateCanvas(Canvas.java:41)
	at com.jakibah.infinyvale.Game.main(Game.java:16)

Line 38: switch (newMap[i][j]) {
Line 107: Chunk ChunktoLoad = new Chunk(newMap, loadedchunk);

Btw, why you’re using ‘switch’ in a such way?


for (int i = 0; i < ChunktoLoad.getMap().length; i++) {
            for (int j = 0; j < ChunktoLoad.getMap()[i].length; j++) {
               int towrite = 0;
               Tile t = ChunktoLoad.map[i][j];
               switch (t.getType()) {
               case Test:
                  towrite = 0;
                  break;// Warning: this break is for the switch, not for a loop statement
               }
               worldwriter.write(towrite + ", ");
               System.out.println("Loading new Chunk");

I am using switch there because I am gonna add more tiles soon. And that piece of code you quoted is to load a new chunk. The problem is when I load a already existing chunk. That is this piece of code:

} else {
         if (First == true) {
            int x = lines.indexOf("chunk: " + loadedchunk + " (");
            x = x + 1;
            String s = lines.get(x);
            s = s.substring(5, s.length() - 2);
            char[] c = s.toCharArray();
            int TilesWide = Display.getWidth() / 32;
            int TileHeight = Display.getHeight() / 32;
            int[][] newMap = new int[TilesWide][TileHeight];
            for (Character character : c) {
               if (character != ',' && character != ' ') {
                  int towrite = Integer.parseInt(character.toString());
                  for (int i = 0; i < newMap.length; i++) {
                     for (int j = 0; j < newMap[i].length; j++) {
                        newMap[i][j] = towrite;
                     }
                  }
               }
            }

            Chunk ChunktoLoad = new Chunk(newMap, loadedchunk);

            First = false;
            
         }
      }

try to replace your code fragment from prev post with this. may be it helps


 } else {
         if (First == true) {
            int x = lines.indexOf("chunk: " + loadedchunk + " (");
            x = x + 1;
            String s = lines.get(x);
            s = s.substring(5, s.length() - 2);
            int TilesWide = Display.getWidth() / 32;
            int TileHeight = Display.getHeight() / 32;
            int[][] newMap = new int[TilesWide][TileHeight];
            for (int k = 0; k < s.length(); k++) {
                char character = s.charAt( k );
                assert Character.isDigit( character );
               if (character != ',' && character != ' ') {
                  int towrite = Character.digit(character, 10);
                  for (int i = 0; i < newMap.length; i++) {
                     for (int j = 0; j < newMap[i].length; j++) {
                        newMap[i][j] = towrite;
                     }
                  }
               }
            }

            Chunk ChunktoLoad = new Chunk(newMap, loadedchunk);

            First = false;

         }
      }

Also when you’re using Flushable and Closeable use try/finally as well

In the world file I’ve found chunk with -1 value. Is it correct?

I just accidentaly solved the problem by moving this line: Chunk ChunktoLoad = new Chunk(newMap, loadedchunk);
into this loop

 for (int i = 0; i < newMap.length; i++) {
                     for (int j = 0; j < newMap[i].length; j++) {
                        newMap[i][j] = towrite;
                        //right here
                     }
                  }

I do not know why but everything works as it has to work now. XD