# TileMap KeyListener - Problem



## Alex_ (25. Apr 2012)

Hallo,

ich versuche mich grade an einem Spiel. Habe davor noch nichts in dieser Richtung gemacht und bin daher in diesem Gebiet noch Neuling 
Ich dachte an ein 2D Strategie Spiel, welches auf einer Tile-Map basiert. Aus Hintergrundbilder, für die einzelnen Felder, wollte ich gif Dateien verwenden.

Zur Zeit beschäftige ich mich noch mit der Tile Map und habe damit ein kleines Problem. (Überprüfungen, ob man am Ende der Map ist, hab ich noch nicht eingebaut und er ist zur Zeit auch mehr provisorisch gedacht, da ich mich erst mal mit der Tilde Map anfreunden will ). Ich bekomme immer folgende Fehlermeldung, wenn ich z.B. eine Pfeiltaste länger gedrückt halte und somit durch die Karte navigiere:

```
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
	at sample.GamePanel.drawCoordinates(GamePanel.java:193)
	at sample.GamePanel.paintComponent(GamePanel.java:168)
	at javax.swing.JComponent.paint(JComponent.java:1054)
	at javax.swing.JComponent.paintChildren(JComponent.java:887)
	at javax.swing.JComponent.paint(JComponent.java:1063)
	at javax.swing.JComponent.paintChildren(JComponent.java:887)
	at javax.swing.JComponent.paint(JComponent.java:1063)
	at javax.swing.JLayeredPane.paint(JLayeredPane.java:585)
	at javax.swing.JComponent.paintChildren(JComponent.java:887)
	at javax.swing.JComponent.paintToOffscreen(JComponent.java:5228)
	at javax.swing.RepaintManager$PaintManager.paintDoubleBuffered(RepaintManager.java:1482)
	at javax.swing.RepaintManager$PaintManager.paint(RepaintManager.java:1413)
	at javax.swing.RepaintManager.paint(RepaintManager.java:1206)
	at javax.swing.JComponent.paint(JComponent.java:1040)
	at java.awt.GraphicsCallback$PaintCallback.run(GraphicsCallback.java:39)
	at sun.awt.SunGraphicsCallback.runOneComponent(SunGraphicsCallback.java:78)
	at sun.awt.SunGraphicsCallback.runComponents(SunGraphicsCallback.java:115)
	at java.awt.Container.paint(Container.java:1967)
	at java.awt.Window.paint(Window.java:3867)
	at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:781)
	at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:728)
	at javax.swing.RepaintManager.prePaintDirtyRegions(RepaintManager.java:677)
	at javax.swing.RepaintManager.access$700(RepaintManager.java:59)
	at javax.swing.RepaintManager$ProcessingRunnable.run(RepaintManager.java:1621)
	at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:251)
	at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:701)
	at java.awt.EventQueue.access$000(EventQueue.java:102)
	at java.awt.EventQueue$3.run(EventQueue.java:662)
	at java.awt.EventQueue$3.run(EventQueue.java:660)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
	at java.awt.EventQueue.dispatchEvent(EventQueue.java:671)
	at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:244)
	at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:163)
	at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:151)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:147)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:139)
	at java.awt.EventDispatchThread.run(EventDispatchThread.java:97)
```




Ok, hier also mein Code:

```
package sample;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.image.BufferedImage;

import javax.swing.JFrame;
import javax.swing.JPanel;

public class GamePanel extends JPanel {

	private static final long serialVersionUID = 1L;

	public Tile[][] map; // Zweidimendionales Array, mit dem man alle Felder der
							// Karte ueber ihre x und y Koordinate ansprechen
							// kann

	public Tile[][] currentView; // Array, welches die momentan zu sehenden
									// Felder speichert.

	private final int tileSize = 40;
	int visionSize = 15; // Die Anzahl der Felder, die zu sehen sind (Sowohl in
							// Richtung der x- als auch der y-Achse)

	// Die aktuelle Position der Figur (blaues Kaestchen)
	int xPos = 0;
	int yPos = 0;

	private final JFrame frame;

	public static void main(String[] args) {
		new GamePanel(new Rectangle(0, 0, 600, 620), 70, 15);
	}

	/**
	 * 
	 * @param rect
	 *            Groesse des Panels.
	 * @param mapSize
	 *            Anzahl der Felder, die erstellt werden sollen. (Ein Feld hat
	 *            eine festgelegte Groesse von 40)
	 * @param visionSize
	 *            Anzahl der Felder die angezeigt werden sollen.
	 */
	public GamePanel(Rectangle rect, int mapSize, int visionSize) {
		super();
		setBounds(rect);

		this.visionSize = visionSize;

		// Beide Variablen mit der festgelegten Groesse der Felder (40)
		// multiplizieren.
		mapSize *= tileSize;
		visionSize *= tileSize;

		this.map = new Tile[mapSize][mapSize];
		this.currentView = new Tile[visionSize][visionSize];

		// Karte erstellen
		for (int y = 0; y < mapSize; y += tileSize) {
			for (int x = 0; x < mapSize; x += tileSize) {
				Tile t = new Tile(x, y, null);
				map[x][y] = t;
			}
		}

		// Frame zur Anzeige des Panels
		frame = new JFrame();
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setBounds(rect);
		frame.setLayout(null);

		// Panel dem frame hinzufuegen
		frame.add(this);

		calculateCurentView();

		frame.setLocationRelativeTo(null);
		frame.setVisible(true);

		// KeyListener hinzufuegen
		frame.addKeyListener(new KeyListener() {

			@Override
			public void keyTyped(KeyEvent e) {
			}

			@Override
			public void keyReleased(KeyEvent e) {
			}

			// Wenn Richtungstaste gedrueckt, bewegung ausfuehren
			@Override
			public void keyPressed(KeyEvent e) {

				if (e.getKeyCode() == KeyEvent.VK_LEFT) {
					goLeft();
				}

				if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
					goRight();
				}

				if (e.getKeyCode() == KeyEvent.VK_UP) {
					goUp();
				}

				if (e.getKeyCode() == KeyEvent.VK_DOWN) {
					goDown();
				}
			}
		});
	}

	private void goRight() {
		xPos += tileSize / 2;
		calculateCurentView();
		frame.repaint();
	}

	private void goLeft() {
		xPos -= tileSize / 2;
		calculateCurentView();
		frame.repaint();
	}

	private void goUp() {
		yPos -= tileSize / 2;
		calculateCurentView();
		frame.repaint();
	}

	private void goDown() {
		yPos += tileSize / 2;
		calculateCurentView();
		frame.repaint();
	}

	// paintComponent Methode des GamePanels ueberschreiben.
	@Override
	public void paintComponent(Graphics g) {
		super.paintComponent(g);

		drawCoordinates(g);

		// Spielfigur (blaues Kaestchen ) malen
		g.setColor(Color.BLUE);
		int xy = ((visionSize * tileSize) / 2) - (tileSize / 2);
		g.fillRect(xy, xy, tileSize, tileSize);
		g.setColor(Color.BLACK);
	}

	private void calculateCurentView() {

		// Das aktuelle Sichtfeld, je nach Bewegungsrichtung neu berechnen
		// (Zuweisen von den jeweiligen Tiles-Objekten aus 'map', welche die
		// komplette Karte beinhaltet, nach 'currentView')
		for (int y = 0; y < currentView.length; y += tileSize) {
			for (int x = 0; x < currentView.length; x += tileSize) {
				currentView[x][y] = map[x + xPos][y + yPos];
			}
		}
	}

	// Koordinaten der einzelnen Felder malen
	private void drawCoordinates(Graphics g) {
		for (int y = 0; y < currentView.length; y += tileSize) {
			for (int x = 0; x < currentView.length; x += tileSize) {
				int x1 = currentView[x][y].x;
				int y1 = currentView[x][y].y;

				g.drawString("" + x1, x + 5, y + 15);
				g.drawString("" + y1, x + 5, y + 30);

				g.drawRect(x, y, 40, 40);
			}
		}
	}
}

class Tile {
	int x, y; // x, y-Position des Feldes
	BufferedImage[] image; // Spaeter .gif Datei als Hintergrundbild laden

	public Tile(int x, int y, BufferedImage[] image) {
		this.x = x;
		this.y = y;
		this.image = image;
	}
}
```

Grüße,
Alex


----------



## eRaaaa (25. Apr 2012)

Steht doch immer alles schön in der Fehlermeldung, gucke dir die einzelnen Zeilen mal an:

```
at sample.GamePanel.drawCoordinates(GamePanel.java:193)
    at sample.GamePanel.paintComponent(GamePanel.java:168)
```
Leider passen die Zeilennummern mit deinem geposteten Code nicht überein -> schlecht!
Wenn ich raten müsste würde ich auf die Zeile _int x1 = currentView[x][y].x;_ tippen und sagen, dass currentView[x][y] = null ist, kann mich aber auch irren :bae:


----------



## Alex_ (25. Apr 2012)

Danke  
Hab die Zeilenangaben in der Fehlermeldung gestern wohl überlesen

Das die Zeilenangaben der Fehlermeldung nicht ganz mit dem Code übereinstimmen, liegt daran, dass ich noch paar Zeilen, die eigentlich nur zum debuggen dienen vor dem Post entfernt habe, aber noch die alte Fehlermeldung benutzt habe

Ok, dann guck ich mal warum mein currentView an der Stelle _int x1 = currentView[x][y].x;_ null ist. Das komische ist aber, dass die Fehlermeldung zwar kommt, die Karte aber trotzdem richtig scrollt. Vielleicht ein Performance-Problem in der Berechnung des currentViews? (auch wenn ich mir das nicht so richtig vorstellen kann)

Grüße,
Alex


----------

