# Snake programmieren?



## Abu (14. Jan 2009)

Hallo leutz!

Ich muss Snake programmieren und hänge an einer stelle......das ist die aufgabe...

"Weisen Sie dem Attribut field ein neues zweidimensionales Array vom Typ
States der Größe FIELD SIZE*FIELD SIZE zu und initialisieren Sie jeden
Array-Eintrag mit States.EMPTY. Dieses Array stellt die Spiel
fläche dar."

und mein Ansatz.....

  field= new States[FIELD_SIZE][FIELD_SIZE];


			 for(int a =0; a<=FIELD_SIZE; a++){


			   for(int b =0; b<=FIELD_SIZE; b++){

				   field[a]*= States.EMPTY;

			   }  

			  }


aber er zeigt immer ein "ArrayIndexOutOfBoundsException" fehler an?

kann mir bitte jemand helfen?
Danke im vorraus.*


----------



## Ice-Tea (14. Jan 2009)

```
field= new States[FIELD_SIZE][FIELD_SIZE];


for(int a =0; a<FIELD_SIZE; a++){


for(int b =0; b<FIELD_SIZE; b++){

field[a][b]= States.EMPTY;

}

}
```


----------



## Abu (14. Jan 2009)

Danke für die schnelle antwort


----------



## Campino (14. Jan 2009)

Auf den ersten Blick sehe ich keinen Fehler. Deshalb: 

a) Bist du dir sicher, dass die Exception an der Stelle fliegt?
b) Steht das so hintereinander oder ist da anderer Code dazwischen? Wenn anderer Code dazwischen ist: Kann es sein das irgendwie FIELD_SIZE oder der Array verändert werden? 
c) Hast du dich vielleicht im Programm irgendwo vertippt? Vergleich das aus dem Forum mal Zeichen für Zeichen (Groß-/Klein- Schreibung, Klammern, Punkte, usw.) mit der Variante im Programm. 
d) Tausch mal FIELD_SIZE gegen field.length bzw. field[a].length. Hilft das?
e) Für gewöhnlich wird bei einer ArrayIndexOutOfBounds- Exception der erreichte Index und die Feldgröße mit ausgegeben. Prüf mal, ob die beiden Werte stimmen (und wie sie zustande kommen). 
f) Kompletten Stacktrace (d.h. alles was bei dem Fehler in der Konsole landet) zeigen. Vielleicht sehen wir da dran ja was (bei Exceptions ist der generell immer vorteilhaft).


----------



## 0x7F800000 (14. Jan 2009)

Campino hat gesagt.:
			
		

> Auf den ersten Blick sehe ich keinen Fehler. Deshalb:


Deshalb gug genauer hin ---> :shock:


----------



## diggaa1984 (14. Jan 2009)

:lol: flüchtigkeitsfehler passieren auch beim lesen :d


----------



## Abu (14. Jan 2009)

```
public void paint(Graphics g) {
		  super.paint(g);
		 
		  
		  for(int i = 0; i<=(field.length)-1;i++){
		   for(int j = 0; j<=(field.length)-1;j++){
			  
			   
			   if(field[i][j]==States.EMPTY){
				   
		    g.setColor(Color.white);
		    g.fillRect(i*20,j*20,(i+1)*20, (j+1)*20);
		   }
		   
		  
		  if(field[i][j]==States.SNAKE){
		  g.setColor(Color.BLACK);
		  g.fillOval(i,j,20,20);
		  g.fillOval(i,j,20,20);
		  g.fillOval(i,j,20,20);
		  }
		  if(field[i][j]==States.APPLE){
			  
			  g.setColor(Color.RED);
			  g.fillOval(50, 50, 20, 20);
			  
			  
		  }
		  if(field[i][j]==States.BLOCK){
			  
			  g.setColor(Color.GREEN);
			  g.fillRect(30, 30, 20, 20);
			  g.fillRect(90, 90, 20, 20);
			  g.fillRect(30, 90,20,20);
			  g.fillRect(60, 10, 20, 20);
			  
		  }
		 
}

		  }
		  
		  g.drawRect(0, 0, 20*(field.length), 20*(field.length));
	
	}
```

das programm zeichnet bei mir nur eine weiße fläche mit einem schwarzen kreis bei punkt 0,0.....
Der sollte aber alles andere wie den Apfel, die blöcke  und die umrandung zeichnen.....sowie der snake, der bei bewegung selbst die felder ausfüllt......
Ich komm nicht drauf?


----------



## 0x7F800000 (14. Jan 2009)

ich weiß nicht was da genau los ist (kompilierbares minimalbeispiel wäre praktisch)
aber zumindest mal würde ich vermuten, dass die ganzen kreise irgendwo zusammengequätscht in der oberen linke ecke bleiben.
Was zum Beispiel soll 

```
g.fillOval(i,j,20,20);
```
ergeben? du zeichenst einen 20x20 kreis irgendwo sehr weit oben links, weil i und j ja keine abstände, sondern lediglich indizes der Kästchen sind. versuche das irgendwie alles sinnvoll zu strecken, etwa

```
g.fillOval(i*20,j*20,20,20);
```
damit es eben alles irgendwie zusammenpasst.

Und achte demnächst auf formatierung des codes.


----------



## Abu (14. Jan 2009)

Danke für deine antwort Andrey......hast du icq?
dann könnte ich dir das programm ganz schicken, weil es schon lang ist....?


----------



## 0x7F800000 (14. Jan 2009)

bitte sehr erstmal...
nö, icq hab ich keins da. Außerdem bin ich grad eh ziemlich unter Zeitdruck, du hast wesentlich bessere Chancen eine Antwort zu erhalten, wenn du die Frage an das ganze Forum stellst, dazu ist es ja da.

Aber eigentlich ist das wahrscheinlich gar nicht nötig: versuche dir an einem einfacheren beispiel klarzumachen, wie du kreise auf einem karierten feld korrekt plazierst, dann läuft es auch mit dem snake :toll:


----------



## Abu (14. Jan 2009)

```
public class Snake extends JPanel implements KeyListener, Runnable {
	// Deklarieren der Attribute Field_Size,field,snake, direction,finished und
	// paused
	private int FIELD_SIZE = 20;
	private LinkedList<Point> snake = new LinkedList<Point>();
	private States[][] field;
	private int direction = KeyEvent.VK_UP;
	private boolean paused = false;
	private boolean finished = false;

	/**
	 * enum States enthaelt die 4 moeglichen Zustaende fuer ein Feld auf dem
	 * Spielfeld.
	 */
	private enum States {
		EMPTY, SNAKE, APPLE, BLOCK;
	}

	public static void main(String[] args) {
		new Snake();
	}

	/**
	 * Methode init() setzt alle Attribute der Klasse auf default-Werte, legt
	 * das Spielfeld an, platziert die Schlange darauf und verteilt 3 Aepfel.
	 */

	private void init() {
		int highscore = 1;
		int applesInGame = 2;
		int applesEaten = 2;
		int level = 1;
		int points = 2;

		// Zuweisung 2deminsionales array vom typ States
		field = new States[FIELD_SIZE][FIELD_SIZE];

		for (int a = 0; a < FIELD_SIZE; a++) {
			for (int b = 0; b < FIELD_SIZE; b++) {

				field[a][b] = States.EMPTY;

			}

		}

		field[1][1] = States.SNAKE;
		field[1][2] = States.SNAKE;
		field[1][3] = States.SNAKE;
		snake.addFirst(new Point(1, 1));
		snake.addFirst(new Point(1, 2));
		snake.addFirst(new Point(1, 3));
	}

	/**
	 * Methode reset() setzt das Spiel auf den Anfang zurück
	 */
	private void reset() {

	}

	/**
	 * Konstruktor für die Snake-Klasse
	 */
	public Snake() {
		init();
		paused = false;
		JFrame frame = new JFrame("MySnake");
		frame.setSize(200 + FIELD_SIZE * 20, 100 + FIELD_SIZE * 20);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.addKeyListener(this);
		frame.add(this);
		frame.setVisible(true);

		new Thread(this).start();
	}

	/**
	 * Notwendig zum Ablauf des Spiels, nicht veraendern!
	 */
	// @Override
	public void run() {
		long time = System.currentTimeMillis();
		while (true) {

			while (!paused && !finished) {
				long time_elapsed = System.currentTimeMillis() - time;
				try {
					long sleep = Math.max(100 - time_elapsed, 60);
					Thread.sleep(sleep);
				} catch (InterruptedException e) {
				}
				time = System.currentTimeMillis();
				nextTurn();
			}

			while (paused || finished) {
				try {
					Thread.sleep(100);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
	}

	/**
	 * Verteilt zufaellig ein Element vom angegeben State auf dem Spielfeld.
	 * 
	 * @param type
	 */
	public void addRandomised(States type) {

	}

	/**
	 * In der Methode nextTurn() werden alle Anweisungen ausgefuehrt, die fuer
	 * den naechsten Schritt im Spiel notwendig sind.
	 */
	public void nextTurn() {
			// Lesen des Schlangen kopfes

		private Snake head=null;
		
		
	}

	/**
	 * Zeichnet die aktuelle Spielsituation auf den Bildschirm.
	 */
	@Override
	public void paint(Graphics g) {
		super.paint(g);

		for (int i = 0; i <= (field.length) - 1; i++) {
			for (int j = 0; j <= (field.length) - 1; j++) {

				if (field[i][j] == States.EMPTY) {

					g.setColor(Color.white);
					g.fillRect(i * 20, j * 20, (i + 1) * 20, (j + 1) * 20);
				}

				if (field[i][j] == States.SNAKE) {
					g.setColor(Color.BLACK);
					g.fillOval(i * 70, j * 80, 20, 20);
					g.fillOval(i * 70, j * 80, 20, 20);
					g.fillOval(i * 20, j * 20, 20, 20);
				}
				if (field[i][j] == States.APPLE) {

					g.setColor(Color.RED);
					g.fillOval(50, 50, 20, 20);

				}
				if (field[i][j] == States.BLOCK) {

					g.setColor(Color.GREEN);
					g.fillRect(30, 30, 20, 20);
					g.fillRect(90, 90, 20, 20);
					g.fillRect(30, 90, 20, 20);
					g.fillRect(60, 10, 20, 20);

				}

			}

		}

		g.drawRect(0, 0, 20 * (field.length), 20 * (field.length));

	}

	/**
	 * keyPressed() wird aufgerufen, wenn eine Taste gedrueckt wurde
	 */
	@Override
	public void keyPressed(KeyEvent e) {
		switch (e.getKeyCode()) {
		case KeyEvent.VK_UP: {
			if (direction != KeyEvent.VK_DOWN) {
				direction = KeyEvent.VK_UP;
			}
		}
		case KeyEvent.VK_DOWN: {
			if (direction != KeyEvent.VK_UP) {
				direction = KeyEvent.VK_DOWN;
			}
		}
		case KeyEvent.VK_RIGHT: {
			if (direction != KeyEvent.VK_LEFT) {
				direction = KeyEvent.VK_RIGHT;
			}
		}
		case KeyEvent.VK_LEFT: {
			if (direction != KeyEvent.VK_RIGHT) {
				direction = KeyEvent.VK_LEFT;
			}
		}
		}

	}
```

soweit bin ich schon.......paint(graphics g) funktioniert nicht, wie es soll....es muss ein Quadrat schwarz umrandet sein und darin ist snake( drei kreise hintereinander) der bei bewegung dementsprechend die anderen felder ausfüllt, ein Apfel der auch irgendwo ist aber seine positionen später ändern muss, und dann noch die blöcke....
Bei den Rest bin ich mir einigermaßen sicher das es klappt......

Danke für eure hilfe......


----------



## 0x7F800000 (14. Jan 2009)

```
@Override
	public void paint(Graphics g) {
		super.paint(g);

		// schwarze grundierung malen
		g.setColor(Color.BLACK);
		g.fillRect(0,0,getWidth(), getHeight());
		
		// alles mit einer grünen wiese füllen, 
		// einen pixel breiten schwarzen streifen zwischen kästchen lassen
		g.setColor(Color.GREEN.darker());
		for (int i = 0; i < field.length; i++) {
			for (int j = 0; j < field[0].length; j++) {
				g.fillRect(i*20, j*20, 19, 19);
			}
		}
		
		// alle objekte auf die wiese malen
		boolean shape=true; //true für block false für kreis (um's einfach zu halten)
		for (int i = 0; i < field.length; i++) {
			for (int j = 0; j < field[0].length; j++) {
				switch(field[i][j]){
					case SNAKE: g.setColor(Color.YELLOW); 	shape=false; 	break;
					case APPLE: g.setColor(Color.RED); 		shape=false;	break;
					case BLOCK: g.setColor(Color.LIGHT_GRAY);		shape=true; 	break;
					case EMPTY: continue;
				}
				if(shape){
					g.fillRect(i*20+2, j*20+2, 15, 15);
				}else{
					g.fillOval(i*20+2, j*20+2, 15, 15);
				}
			}

		}
	}
```
so besser?


----------



## Abu (14. Jan 2009)

Viiiiieeeeeeelllll besser!:shock: 
Danke!


----------



## Abu (14. Jan 2009)

// Lesen des Schlangen kopfes

 LinkedList<Point> Head = new LinkedList<Point>();

wie lege ich einen neuen Head an der auf den alten Head zeigt?


----------



## 0x7F800000 (14. Jan 2009)

mir ist nicht ganz klar was du da machen willst. Wieso erstellst du irgendeine neue Liste und nennst sie auch noch "Head" (sehr missverständlich und dazu grpßgeschrieben  )

Erstelle dir doch ein einziges mal eine Liste, in der die Segmente deiner Schlange gespeichert werden, wenn dann ein neues hinzukommt, fügst du es mit add() hinzu und fertig.


----------



## Abu (14. Jan 2009)

Ich muss die aufgabenstellung durcharbeiten und das problem ist das ich von listen gar keine ahnung habe, speziel was lesen des Schlangen kopfes betrifft......1.ich soll den schlangen kopf lesen also mit Head und dann einen neuen Head erstellen der auf den alten head verweist....??
2.Bestimmen Sie abhängig von der aktuellen Position aus Head und der gesetzten Richtung der Schlangenbewegung, welche Indizes der neue Head haben muss und weisen Sie diese dem neuen Head zu.

Ich verstehe erstmal die aufgabenstellung nicht ganz....


----------



## 0x7F800000 (14. Jan 2009)

1. wäre sinnvoll, wenn du eine eigene datenstruktur für die schlangensegmente schreiben müsstest (wäre eine stinknormale verkettete liste, 20 minuten aufwand) aber ich sehe da irgendwie keine notwendigkeit dazu, gibts doch schon alles fertig in java.util.* Oder steht da explizit da, dass du für die schlange eigene struktur schreiben musst? Eine Queue ("Schlange"  ) wäre da imho sogar angebrachter.

2. Ich würd's ganz einfach machen: ein segment ist durch seine x/y-Position definiert, mehr braucht er nicht zu wissen. Du hast eine Queue von segmenten. Das erste segment darfst du meinetwegen in den kommentaren als "head" bezeichnen, aber extra variable ist dafür unnötig.

Bewegt sich die schlange, so schmeißt du das letzte element einfach weg, und vorne fügst du ein neues element hinzu, das die koordinaten des alten "kopfes" +-1 in irgendeiner richtung enthält. Frisst du einen Apfel, so machst du genau dasselbe, aber schmeißt das letzte element nicht weg, sondern lässt es da wo es ist (die schlange soll ja länger werden)

Ist mit einer queue eigentlich alles sehr einfach und übersichtlich.


----------



## Abu (15. Jan 2009)

```
public void nextTurn() {
			// Lesen des Schlangen kopfes

		
		  snake.addFirst(new Point(10,15));
		 LinkedList<Point> Head = new LinkedList<Point>(); 
		  snake=Head;
		  
		  
	}
```

jetzt habe das oben geschilderte (andrey) problem....ich komm einfach nicht weiter? 
wie sorge ich für die fortbewegung der schlange, ich hab das verstanden das man einen Queue hinzufügt und den letzten wegschmeißt bzw löscht aber wie erkläre ich das java?????
genau so das er ein Apfel nimmt und es vorne hinzufügt aber hinten nix rausschmeißt.


----------



## 0x7F800000 (15. Jan 2009)

diese LinkedList bei jedem methodenaufruf neu anzulegen ist schonmal unsinn. Das sollte besser eine private member-variable deiner Snake klasse sein, eben eine Liste die den Zustand des Snakes darstellt.
Die momentane vom benutzer ausgewählte richtung solltest du auch in einer member-variable mitspeichern, etwa einem int[] array mit 2 einträgen: für die horizontale und für die vertikale richtung
(nach rechts laufen wäre dann zB sowas wie {1,0} und {0,-1} für nach unten usw.)

bei jedem aufruf von nextTurn() musst du dann etwa folgendes machen:

```
List<Integer[]> snakeSegments; //member variablen, alles im konstruktor initialisieren
int[] direction;

private void nextTurn(){
  // position des kopfes im nächsten schritt berechnen
  Integer[] nextHead=new Integer[2];
  nextHead[0]=snakeSegments.getFirst()[0]+direction[0];
  nextHead[1]=snakeSegments.getFirst()[1]+direction[1];

  //entscheiden was zu tun ist
  switch(spielefeldZustandArray[nextHead[0]][nextHead[1]]{
    case BLOCK: spiel beenden 
    case SNAKE: auf sich selbst getreten, game over (evtl das letzte element gesondert behandeln)
    case APPLE: snakesegments.addFirst(nextHead); //einfach nur kopf hinzufügen, break; usw
    case EMPTY: snakeSegments.addFirst(nextHead); snakeSegments.removeLast();
                        // kopf auf die neue position schieben, schwanz löschen
  }
}
```
ich hab den code selbstverständlich nicht ausprobiert, evtl passt es hier und da mit dem autoboxing nicht ganz, aber hoffentlich ist der sinn klar geworden.


----------



## Guest (15. Jan 2009)

```
public class Snake extends JPanel implements KeyListener, Runnable {
	// Deklarieren der Attribute Field_Size,field,snake, direction,finished und
	// paused
	private int FIELD_SIZE = 20;
	private LinkedList<Point> snake = new LinkedList<Point>();
	private States[][] field;
	private int direction = KeyEvent.VK_UP;
	private boolean paused = false;
	private boolean finished = false;
	private int highscore = 0;
	private int applesInGame = 0;
	private int applesEaten = 0;
	private int level = 1;
	private int points = 0;
	
	
	
	private enum States {
		EMPTY, SNAKE, APPLE, BLOCK;
	}

	public static void main(String[] args) {
		new Snake();
	}

	/**
	 * Methode init() setzt alle Attribute der Klasse auf default-Werte, legt
	 * das Spielfeld an, platziert die Schlange darauf und verteilt 3 Aepfel.
	 */

	private void init() {
	

		// Zuweisung 2deminsionales array vom typ States
		field = new States[FIELD_SIZE][FIELD_SIZE];

		for (int a = 0; a < FIELD_SIZE; a++) {
			for (int b = 0; b < FIELD_SIZE; b++) {

				field[a][b] = States.EMPTY;

			}

		}

		field[1][1] = States.SNAKE;
		field[1][2] = States.SNAKE;
		field[1][3] = States.SNAKE;
		
		  snake.addFirst(new Point(1,1)); 
		  snake.addFirst(new Point(1,2));
		  snake.addFirst(new Point(1,3));
		

	}

	/**
	 * Methode reset() setzt das Spiel auf den Anfang zurück
	 */
	private void reset() {

	}

	/**
	 * Konstruktor für die Snake-Klasse
	 */
	public Snake() {
		
		init();
		paused = false;
		JFrame frame = new JFrame("MySnake");
		frame.setSize(200 + FIELD_SIZE * 20, 100 + FIELD_SIZE * 20);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.addKeyListener(this);
		frame.add(this);
		frame.setVisible(true);

		new Thread(this).start();
	}

	/**
	 * Notwendig zum Ablauf des Spiels, nicht veraendern!
	 */
	
	//@Override
	public void run() {
		long time = System.currentTimeMillis();
		while (true) {

			while (!paused && !finished) {
				long time_elapsed = System.currentTimeMillis() - time;
				try {
					long sleep = Math.max(100 - time_elapsed, 60);
					Thread.sleep(sleep);
				} catch (InterruptedException e) {
				}
				time = System.currentTimeMillis();
				nextTurn();
			}

			while (paused || finished) {
				try {
					Thread.sleep(100);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
	}

	/**
	 * Verteilt zufaellig ein Element vom angegeben State auf dem Spielfeld.
	 * 
	 * @param type
	 */
	public void addRandomised(States type) {

	}

	/**
	 * In der Methode nextTurn() werden alle Anweisungen ausgefuehrt, die fuer
	 * den naechsten Schritt im Spiel notwendig sind.
	 */
	public void nextTurn() {
		
		//Lesen des Schlangen Kopfs
		
			Point Head = new Point();
			Head = snake.getFirst();
			Point Head2 = new Point();
			
			
		int xHead = Head.x;
		int yHead = Head.y;
		
		
		switch (direction) {
				case KeyEvent.VK_UP: {
					Head2.x = xHead;
					Head2.y = yHead - 1;
					break;
		}
				case KeyEvent.VK_LEFT: {
					Head2.x = xHead - 1;
					Head2.y = yHead;
					break;
		}
				case KeyEvent.VK_RIGHT: {
					Head2.x = xHead + 1;
					Head2.y = yHead;
					break;
		}
				case KeyEvent.VK_DOWN: {
					Head2.x = xHead;
					Head2.y = yHead + 1;
		}
		}
		
		snake.addFirst(Head2);
		boolean noapple = true;
		
		
		if (Head2.x==5 || Head2.x==1 || Head2.y==5 || Head2.y==1 || field[Head2.x][Head2.y] ==           States.BLOCK || field[Head2.x][Head2.y] == States.SNAKE ){
		finished = true;
		if (points==highscore){
			highscore = points;
		}
		
		repaint ();
		paused = true;
		return;
		}

		if (field[Head2.x][Head2.y] == States.APPLE) {
		applesInGame--;
		noapple = false;
		applesEaten++;
		points = points + level;
		}
		Point Tail = new Point();
		field[Head2.x][Head2.y] = States.SNAKE;
		if (noapple) {
		Tail = snake.removeLast();
		field[Tail.x][Tail.y] = States.EMPTY;
		}
		if (applesInGame ==5) {
		double a = Math.random() * 100;
		if (a == 5) {
		addRandomised(States.APPLE);
		applesInGame++;
		}
		}
		if (applesEaten == 10) {
		applesEaten = 0;
		level++;
		int l = 13;
		int abschneiden = 0;
		
		
			for (int i = 1; i<level; i++) {
							abschneiden = l / 2;
							l = l - abschneiden + 10;
}
			
		for (int p = 0; p<abschneiden; p++) {
		Tail = snake.removeLast();
		field[Tail.x][Tail.y] = States.EMPTY;
		}
		addRandomised(States.BLOCK);
		}
		repaint();
			
	
	}

	/**
	 * Zeichnet die aktuelle Spielsituation auf den Bildschirm.
	 */
	@Override
	public void paint(Graphics g) {
		super.paint(g);

		// schwarze grundierung malen
		g.setColor(Color.BLACK);
		g.fillRect(0, 0, getWidth(), getHeight());

		// alles mit einer grünen wiese füllen,
		// einen pixel breiten schwarzen streifen zwischen kästchen lassen
		g.setColor(Color.GREEN.darker());
		for (int i = 0; i < field.length; i++) {
			for (int j = 0; j < field[0].length; j++) {
				g.fillRect(i * 20, j * 20, 19, 19);
			}
		}

		// alle objekte auf die wiese malen
		boolean shape = true; // true für block false für kreis (um's einfach zu
		// halten)
		for (int i = 0; i < field.length; i++) {
			for (int j = 0; j < field[0].length; j++) {
				switch (field[i][j]) {
				case SNAKE:
					g.setColor(Color.red);
					shape = false;
					break;
				case APPLE:
					g.setColor(Color.RED);
					shape = false;
					break;
				case BLOCK:
					g.setColor(Color.LIGHT_GRAY);
					shape = true;
					break;
				case EMPTY:
					continue;
				}
				if (shape) {
					g.fillRect(i * 20 + 2, j * 20 + 2, 15, 15);
				} else {
					g.fillOval(i * 20 + 2, j * 20 + 2, 15, 15);
				}
			}

		}
	}

	/**
	 * keyPressed() wird aufgerufen, wenn eine Taste gedrueckt wurde
	 */
	// @Override
	public void keyPressed(KeyEvent e) {
		switch (e.getKeyCode()) {
		case KeyEvent.VK_UP: {
			if (direction != KeyEvent.VK_DOWN) {
				direction = KeyEvent.VK_UP;
			}
		}
		case KeyEvent.VK_DOWN: {
			if (direction != KeyEvent.VK_UP) {
				direction = KeyEvent.VK_DOWN;
			}
		}
		case KeyEvent.VK_RIGHT: {
			if (direction != KeyEvent.VK_LEFT) {
				direction = KeyEvent.VK_RIGHT;
			}
		}
		case KeyEvent.VK_LEFT: {
			if (direction != KeyEvent.VK_RIGHT) {
				direction = KeyEvent.VK_LEFT;
			}
		}
		}

	}

	/**
	 * keyReleased() muss nicht implementiert werden
	 */
//	@Override
	public void keyReleased(KeyEvent e) {

	}

	/**
	 * keyTyped() muss nicht implementiert werden
	 */
	// @Override
	public void keyTyped(KeyEvent e) {

	}

}
```

Die schlange müsste sich doch bewegen aber bei mir passiert garnix?!?! das programm zeigt auch kein fehler?


----------



## Marco13 (15. Jan 2009)

Ich vermute, du weißt selbst nicht, was in dem Block

```
if (Head2.x == 5 || Head2.x == 1 || Head2.y == 5 || Head2.y == 1 ||
            field[Head2.x][Head2.y] == States.BLOCK ||
            field[Head2.x][Head2.y] == States.SNAKE)
        {
            finished = true;
            if (points == highscore)
            {
                highscore = points;
            }

            repaint();
            paused = true;
            return;
        }
```
gemacht wird. Jedenfalls läuft er weiter, wenn man den auskommentiert. (Dann fliegt allerdings sehr schnell eine Exception - ich tippe mal, das sollte mit dieser Abfrage verhindert werden... aber so stimmt sie offenbar nicht...)


----------



## Gast (15. Jan 2009)

Danke.......ich werd dran weiter arbeiten


----------



## Marco13 (15. Jan 2009)

Ja, sollte das
if (Head2.x == 5 || Head2.x == 1 || Head2.y == 5 || Head2.y == 1 || 
die Abfrage sein, ob man gegen eine Wand gelaufen ist? Vermutlich - aber ... der Head IST am Anfang ja schon bei x==1, darum hört er da sofort auf. Müßte vermutlich sowas sein wie
if (Head2.x == breite || Head2.x == 0 || Head2.y == höhe || Head2.y == 0 || ...
bzw. vielleicht statt der 0 jeweils eine -1 ....


----------



## Gast (15. Jan 2009)

Ich hatte am anfang if(if (Head2.x ==20 || Head2.x == 0 || Head2.y == 20 || Head2.y == 0 ||.... stehen da hat es schon nicht geklappt, dann habe ich das geändert und vergessen wieder so einzustellen wie vorher.....deshalb steht es da...das ist di abfrage nur bin ich am überlegen wo genau das fehler liegt? und mit -1 klappt es auch nicht......if(points==highscore)->liegt wahrscheinlich da dran


----------



## 0x7F800000 (15. Jan 2009)

nur so als tipp: um sich die extra überprüfung auf kollision mit dem rand der Spielfläche zu ersparen, solltest du lieber eine quadratische wand aus blöcken um das ganze feld basteln, dann wird das alles einheitlich als eine einfache kollision mit einem block behandelt, und am spiel ändert sich nichts, wenn du das feld jeweils um 2 einheiten breiter machst.


----------



## Gast (15. Jan 2009)

Eine andere frage.....wieso bewegt sich die schlange in einer richtung und läuft gegen die wand? die müsste doch theoretisch zu steuern sein im ganzen feld?


----------



## Ebenius (15. Jan 2009)

Andrey hat gesagt.:
			
		

> nur so als tipp: um sich die extra überprüfung auf kollision mit dem rand der Spielfläche zu ersparen, solltest du lieber eine quadratische wand aus blöcken um das ganze feld basteln, dann wird das alles einheitlich als eine einfache kollision mit einem block behandelt, und am spiel ändert sich nichts, wenn du das feld jeweils um 2 einheiten breiter machst.



Hab jetzt den Thread nicht so ganz verfolgt. Aber das Snake 1 meines vor acht Jahren verstorbenen Nokias ist durch die Außenwände gelaufen und kam auf der anderen Seite wieder an. Das macht eigentlich mehr Spaß ...

Just my $0.02


----------



## Marco13 (15. Jan 2009)

Ein 
break;
nach jedem case-Block in der keyPressed-Methode könnten helfen.


----------



## Gast (15. Jan 2009)

//pausiert, oder startet das spiel neu
		case KeyEvent.VK_ENTER:{
			if(finished == true){
				reset();

			}
			else {
				paused = true;

			}

Wieso stoppt er bei der enter taste und macht dann nicht weiter wenn man wieder auf enter drückt? Danke für die Antworten


----------



## Gast (15. Jan 2009)

private void reset() {
		for (int a = 0; a < FIELD_SIZE-1; a++) {
			for (int b = 0; b < FIELD_SIZE-1; b++) {
				field[a]* = States.EMPTY;

			}
		}
		init();
	}*


----------



## Gast (16. Jan 2009)

hat keiner eine idee?


----------



## Landei (16. Jan 2009)

Vielleicht so?

```
case KeyEvent.VK_ENTER:
   if(finished == true){ reset();} 
   else {paused = !paused; }
   break;
```


----------

