# Pokemon



## lord239123 (2. Feb 2014)

Hallo, 

ich bin momentan dabei, ein kleines Pokemon Spiel zu programmieren.
Es gibt bereits eine Figur, die man auf einer kleinen Map bewegen kann und die nicht über Hindernisse hinweggehen kann.
Allerdings habe ich das Problem, das die Figur immer über der Map gespawnt wird(Bild ist im Anhang).
Die Figur und die Map sind beide JPanels, die in einem größeren JPanel liegen.


```
package maps;
import java.awt.*;
import javax.swing.*;
import main.*;
import felder.*;

/*
 * Erste Map im Spiel
 */
public class Goldania extends Map
{
	//Aktueller Spieler
	public Player player = new Player("Ash");
	
	//Map im hintergrund
	public JPanel hintergrund = new JPanel();
	
	
	//Konstruktor, Layout setzen und die Methode setMap() aufrufen
	public Goldania()
	{	
		setBackground(Color.BLACK);		
		setLayout(new FlowLayout(0, 0, 0));
		hintergrund.setLayout(new GridLayout(12, 12));

		player.setOpaque(false);

		add(player);           //Spieler der Stadt hinzufügen
		add(hintergrund);	   //Map der Stadt hinzufügen
		
		//Die Zeichenreihenfolge der Komponenten festlegen
		setComponentZOrder(hintergrund, 1);
		setComponentZOrder(player, 0);

		
		setMap();			   //Map generieren
	}
	
	//Alle Elemente der Map erstellen und ihr hinzufügen
	public void setMap()
	{
		felder = new Feld[12][12];
		
		//Alle Felder mit Gras füllen, i = Zeile, j = Spalte
		for (int i = 0; i < 12; i++) 
		{
			for(int j = 0; j < 12; j++)
			{
				felder[i][j] = new Gras();
			}
		}
		
		//Einen Weg zeichnen
		for (int i = 0; i < 12; i++) 
		{
			felder[i][5] = new Weg(0);
			felder[i][6] = new Weg(1);
		}
		
		//Wegabbiegung nach rechts
		felder[5][6] = new Weg(8);
		felder[6][6] = new Weg(10);
		for (int i = 7; i < 12; i++) 
		{
			felder[5][i] = new Weg(2);
			felder[6][i] = new Weg(3);
		}
		
		//Labor
		felder[0][7] = new Labor(9);
		felder[0][8] = new Labor(9);
		felder[0][9] = new Labor(9);
		felder[0][10] = new Labor(9);
		felder[0][11] = new Labor(9);
		felder[1][7] = new Labor(5);
		felder[1][8] = new Labor(5);
		felder[1][9] = new Labor(5);
		felder[1][10] = new Labor(5);
		felder[1][11] = new Labor(5);
		felder[2][7] = new Labor(10);
		felder[2][8] = new Labor(10);
		felder[2][9] = new Labor(10);
		felder[2][10] = new Labor(10);
		felder[2][11] = new Labor(10);
		felder[3][7] = new Labor(0);
		felder[3][8] = new Labor(0);
		felder[3][9] = new Labor(0);
		felder[3][10] = new Labor(0);
		felder[3][11] = new Labor(0);
		felder[4][7] = new Labor(0);
		felder[4][8] = new Labor(0);
		felder[4][9] = new Labor(1);
		felder[4][10] = new Labor(0);
		felder[4][11] = new Labor(0);

		
		//Alle Felder der Stadt hinzufügen
		for (int i = 0; i < 12; i++) 
		{
			for(int j = 0; j < 12; j++)
			{
				hintergrund.add(felder[i][j]);
			}
		}
		
		
	}
}
```


```
package main;
import javax.swing.*;
import felder.Gras;


public class Player extends JPanel
{
	int x = 0;
	int y = 0;
	
	boolean kannLaufen = true;
	String name = "";
	Icon icon = new ImageIcon(Player.class.getResource("../img/trainer/ash/ashoben.png"));
	
	JLabel bild = new JLabel(icon);
	
	//Konstruktor mit Name als Parameter
	public Player(String name)
	{
		this.name = name;			
		add(bild);	
	}
	
	/*
	 * 1 = oben
	 * 2 = unten
	 * 3 = links
	 * 4 = rechts
	 */
	public void laufen(int laufrichtung)
	{
		if(kannLaufen)
		{
			 //Es kann kein weiterer Laufbefehl eingehen
			kannLaufen = false; 
			
			//Player um 40 felder bewegen
			PlayerThread laufThread = new PlayerThread(laufrichtung);
			System.out.println(x + " " + y);
		}
		
	}
}
```


```
package maps;
import javax.swing.*;
import felder.*;


public class Map extends JPanel
{
	public Feld[][] felder;
	
	public void setMap(){};
}
```


----------



## wolfgang63 (2. Feb 2014)

worin besteht das Problem?


----------



## lord239123 (2. Feb 2014)

Die Map spawnt nicht bei den Koordinaten 0/0 sondern bei 40/40.
Die eigentliche Map heißt in der Klasse hintergrund.


----------



## lord239123 (3. Feb 2014)

Das Problem müsste am FlowLayout liegen, aber bei anderen Layouts habe ich leider das 
Problem, dass nur eines der beiden JPanels angezeigt wird.

Danke schonmal im Vorraus.


----------



## Ruzmanz (3. Feb 2014)

Du musst dir ein paar Tutorials zur Java-2D-Spieleprogrammierung durchlesen. Mit deinem Ansatz kommst du nicht sehr weit, wie du bereits gesehen hast. Siehe Beitrag von MrClave ...



> In der Spieleprogrammierung verwendet man keine Labels oder Panels. Höchstens einmal als "Unterlage", wie ein Stück Papier. Du klebst ja auch nicht ein neues Blatt Papier auf den Hintergrund, um einen Menschen darzustellen.
> Das Graphics Objekt bietet verschiedene Möglichkeiten, Bilder und Figuren zu zeichnen.
> Dazu gibt es auch mehr als genug Tutorials auf YouTube und Google.


----------



## gnarf (3. Feb 2014)

wenn du ein jpanel als hintergrund verwenden willst kannst du entweder die grösse mit dem absolutelayout problemlos einstellen,
dann kannst du aber andere elemente nicht mit dynamischer grösse einstellen,

oder du stellst in deinem jpanel "setRequiredSize(x,y)" die mindest freigehaltene fläche für dein panel ein.

aber ja die figur würd ich auch nicht als panel anzeigen sondern mit dem graphics object direkt auf das spielfeld zeichnen


----------



## gnarf (3. Feb 2014)

oh hab scheinbar das problem ein bisschn missverstanden in dem fall kann ich mich nur Ruzmanz anschliessen


----------



## Thunderstorm (3. Feb 2014)

Schließe mich meinen Vorgängern an. Schon dass dein Player von JPanel erbt, erscheint mir wenig sinnvoll. Somit würde ich auch erstmal zu Tutorials raten.

Java 2D games tutorial

Hier kannst du ja mal reinschauen, war so das erste was ich bei google gefunden habe :rtfm:


----------



## lord239123 (3. Feb 2014)

Ich habe mir jetzt mal das Tutorial von Thunderstorm durchgelesen, aber leider stand da nicht, wie man mit den verschiedenen Ebenen(Hintergrund, Spieler, Vordergrund) arbeiten kann, da dort immer nur eine Ebene benutzt wird, aber trotzdem danke.


----------



## Ruzmanz (3. Feb 2014)

Thunderstorm hatte nicht die Absicht ein Tutorial zur Verfügung zu stellen, wie man das mit mehreren Ebenen löst. So etwas wird nicht gemacht. Dafür sind die Swing-Komponenten nicht gedacht.


----------



## lord239123 (3. Feb 2014)

Wie kann man das denn dann machen?


----------



## Thunderstorm (4. Feb 2014)

Setze dich mit den Grundkonzepten der Spieleprogrammierung auseinander.

Versuche dich erstmal an einfachen Spielen wie Pong oder Tetris. Da wirst du schon auf einige Hürden stoßen. Aber um auf deine Frage zu antworten.

Das hier ist ein kleiner Ausschnitt aus einem meiner ersten Spiele : 
(Habe es aber auf deinen Bedarf gekürzt)

[JAVA=0]

	private Graphics2D g2d;
	private BufferedImage image;

	private TileMap tileMap;
	private Player player;

	public void init(){
		image = new BufferedImage(GAMEWIDTH,GAMEHEIGHT,BufferedImage.TYPE_INT_RGB);
		g2d = (Graphics2D)image.getGraphics();
	}

/**
	 * 60 updates per second and unlimited frames per second
	 */
	@Override
	public void run(){
		init();

		long lastTime = System.nanoTime();
		double delta = 0;
		amountofUpdates = 60.0;
		ns = 1000000000 / amountofUpdates;
		long timer = System.currentTimeMillis();

		while(running){
			long now = System.nanoTime();
			delta += ( now - lastTime ) / ns;
			lastTime = now;
			if(delta > 1){
				update();
				delta--;
			}
			render();

			if( System.currentTimeMillis() - timer > 1000 ){
				timer += 1000;
			}
		}
		stop();
	}

	private void update(){
		if(initialized && !gameMenuActiv){
			tileMap.update();
			player.update();
		}
	}

	private void render(){
		tileMap.renderGroundLayer(g2d);
		player.renderPlayer(g2d);
		tileMap.renderObjects(g2d);
		tileMap.renderTopLayer(g2d);
		player.renderAttributes(g2d);

		getGraphics().drawImage(image, 0, 0, image.getWidth(), image.getHeight(), null);
	}

[/code]

Wenn du Fragen dazu hast, werde ich sie dir gerne beantworten opcorn:

lg Thunder


----------



## lord239123 (4. Feb 2014)

Vielen Dank für dein Beispiel.
Ich habe den Code jetzt etwas geändert, sodass der Spieler und die Map kein JPanel mehr sind.
Das Spielfeld wird jetzt einheitlich in der Methode paintComponent dernKlasse Maps gezeichnet.


```
package maps;

import java.awt.*;
import javax.swing.*;
import main.Player;

//CKontainer, in dem sich die aktuell Map befindet
public class Maps extends JPanel
{
	public Player player = new Player("Ash");//Spieler
	public Map aktuelleMap = new Map();		 //Dies ist die Map, auf der sich der Spieler befindet
	
	public Maps(Map aktuelleMap)
	{
		this.aktuelleMap = aktuelleMap; //legt eine neue Map fest
	}
	
	public void setMap(Map aktuelleMap)
	{
		this.aktuelleMap = aktuelleMap; //legt eine neue Map fest
	}
	
	//aktuelle Map zeichnen
	public void paintComponent(Graphics g) 
	{
	    Graphics2D g2 = (Graphics2D)g;
	    
	    /*
	     * Ebene: 0
	     * Zeichnen der Felder
	     */
		for (int i = 0; i < aktuelleMap.felder.length; i++) 
		{
			for (int j = 0; j < aktuelleMap.felder[i].length; j++) 
			{
				//Bild des Feldes in einem Bild speichern und ausgeben
				Image feldBild = aktuelleMap.felder[j][i].getIcon().getImage(); 
				g2.drawImage(feldBild, i*40, j*40, null);
			}
		}
		
		/*
		 * Ebene: 1
		 * Zeichnen des Players
		 */
		Image playerBild = ((ImageIcon) player.getIcon()).getImage(); 
		g2.drawImage(playerBild, player.getX(), player.getY(), null);
		
	}
}
```


```
package maps;
import java.awt.*;
import javax.swing.*;
import main.*;
import felder.*;

/*
 * Erste Map im Spiel
 */
public class Goldania extends Map
{	
	//Konstruktor, Layout setzen und die Methode setMap() aufrufen
	public Goldania()
	{		
		setMap();	//Map generieren
	}
	
	//Alle Elemente der Map erstellen und ihr hinzufügen
	public void setMap()
	{
		felder = new Feld[25][25];
		
		/*
		 * Alle Felder mit Gras füllen
		 *  i = Zeile
		 *  j = Spalte
		 */
		for (int i = 0; i < 25; i++) 
		{
			for(int j = 0; j < 25; j++)
			{
				felder[i][j] = new Gras();
			}
		}
		
		/*
		 * Einen Platz zeichnen
		 */

		for (int i = 8; i < 13; i++) 		//Zentrum des Platzes
		{
			for (int j = 5; j < 7; j++) 
			{
				felder[i][j] = new Weg(13);
			}
		}
		felder[7][4]  = new Weg(5);	//Oberer Rand
		felder[7][5]  = new Weg(2);
		felder[7][6]  = new Weg(2);
		felder[7][7]  = new Weg(4);
		felder[8][4]  = new Weg(0);	//Linker Rand
		felder[9][4]  = new Weg(0);
		felder[10][4] = new Weg(0);
		felder[11][4] = new Weg(0);
		felder[12][4] = new Weg(0);
		felder[13][4] = new Weg(7); //Unterer Rand
		felder[13][5] = new Weg(11);
		felder[13][6] = new Weg(10);
		felder[13][7] = new Weg(3);
		felder[8][7]  = new Weg(1); //Rechter Rand
		felder[9][7]  = new Weg(1);
		felder[10][7] = new Weg(1);
		felder[11][7] = new Weg(1);
		felder[12][7] = new Weg(8);
		
		/*
		 * Wegsystem zeichnen
		 */
		//Weg wagerecht rechts des Platzes
		for (int i = 8; i < 19; i++)
		{
			felder[12][i] = new Weg(2);
			felder[13][i] = new Weg(3);
		}
		
		//Weg wagerecht rechts oben
		for (int i = 21; i < 25; i++) 
		{
			felder[7][i] = new Weg(2);
			felder[8][i] = new Weg(3);
		}
		felder[7][19] = new Weg(5);
		felder[7][20] = new Weg(2);
		felder[8][19] = new Weg(0);
		felder[8][20] = new Weg(10);
		
		//Weg senkrecht rechts
		for (int i = 9; i < 21; i++) 
		{
			felder[i][19] = new Weg(0);
			felder[i][20] = new Weg(1);
		}
		felder[12][19] = new Weg(9);
		felder[13][19] = new Weg(11);
		felder[21][19] = new Weg(9);
		felder[21][20] = new Weg(1);
		felder[22][19] = new Weg(3);
		felder[22][20] = new Weg(6);
		
		//Weg senkrecht mitte
		for (int i = 14; i < 21; i++) 
		{
			felder[i][15] = new Weg(0);
			felder[i][16] = new Weg(1);
		}
		felder[13][15] = new Weg(11);
		felder[13][16] = new Weg(10);
		
		//Weg senkrecht links
		for (int i = 14; i < 21; i++) 
		{
			felder[i][5] = new Weg(0);
			felder[i][6] = new Weg(1);
		}
		felder[21][5] = new Weg(0);
		felder[21][6] = new Weg(8);
		felder[22][5] = new Weg(7);
		felder[22][6] = new Weg(3);
		
		//Weg wagerecht unten
		for (int i = 7; i < 19; i++) 
		{
			felder[21][i] = new Weg(2);
			felder[22][i] = new Weg(3);
		}
		felder[21][15] = new Weg(9);
		felder[21][16] = new Weg(8);
		
		
		/*
		 * Labor
		 */
		felder[0][7] = new Labor(9);
		felder[0][8] = new Labor(9);
		felder[0][9] = new Labor(9);
		felder[0][10] = new Labor(9);
		felder[0][11] = new Labor(9);
		felder[1][7] = new Labor(5);
		felder[1][8] = new Labor(5);
		felder[1][9] = new Labor(5);
		felder[1][10] = new Labor(5);
		felder[1][11] = new Labor(5);
		felder[2][7] = new Labor(10);
		felder[2][8] = new Labor(10);
		felder[2][9] = new Labor(10);
		felder[2][10] = new Labor(10);
		felder[2][11] = new Labor(10);
		felder[3][7] = new Labor(0);
		felder[3][8] = new Labor(0);
		felder[3][9] = new Labor(0);
		felder[3][10] = new Labor(0);
		felder[3][11] = new Labor(0);
		felder[4][7] = new Labor(0);
		felder[4][8] = new Labor(0);
		felder[4][9] = new Labor(1);
		felder[4][10] = new Labor(0);
		felder[4][11] = new Labor(0);
	}
}
```

Dabei ergibt sich nur leider ein kleines Problem:
Da die Map größer ist, als der JFrame(480*480 Pixel), wird leider nur ein kleiner Teil der Map angezeigt.
Beim Laufen des Spielers wird eigentlich nur die Map verschoben, wodurch man sehen kann, dass der Rest der map nicht gezeichnet wird.


----------



## lord239123 (4. Feb 2014)

Das Problem ist hat sich jetzt gelöst.
Der setSize Befehl hat nur im Konstruktor der Klasse Maps nicht funktioniert.


----------

