Diverse Bugs in einem Snake Spiel

  • Themenstarter Themenstarter Kakashi
  • Beginndatum Beginndatum
K

Kakashi

Gast
Hallo Zusammen

Ich versuche gerade das Spiel Snake nachzuprogrammieren. Leider habe ich im Moment einige Probleme:

1. Die X Koordinaten vom "Essen" werden irgendwie falsch berechnet. Das "Essen" wird jedoch richtig angezeigt. Das führt dazu, dass die Methode foodColision nicht richtig arbeitet.

2. Die Werte welche mit dem FileWriter in ein Dokument geschrieben werden sollen werde alle auf 0 gesetzt. Die Werte sind jedoch bevor die Methode welche den FileWriter aufruft noch richtig gesetzt.

3. Habt ihr eine Idee wie ich meine Variablen (int, long, double und String) in ein Textfile abspeichere und diese wieder auslesen und der entsprechenden Variabel zuweisen kann?

Hier ist mein gesamter Code:

Klasse Starter:
Java:
package snake;

public class Starter {

	
	public static void main(String[] args) {
		MenuGUI Mgui = new MenuGUI();

	}

}

Klasse MenuGUI:
Java:
package snake;

import java.awt.*;
import java.awt.event.*;

import javax.swing.*;

class MenuGUI extends Frame implements ActionListener {
	
	GUI g = new GUI();
	
	Button btnStartGame = new Button("Spiel starten!");
	Button btnRangliste = new Button("Rangliste");
	Color c = new Color(0x008000);

	class CloseListener extends WindowAdapter {
		public void windowClosing(WindowEvent e) {
			System.exit(0);
		}
	}

	MenuGUI() {

		this.setTitle("Snake");
		this.setBackground(c);
		this.setResizable(false);
		
		this.addWindowListener(new CloseListener());
		
		this.setLayout(null);

		btnStartGame.setBounds(160, 200, 180, 50);
		btnStartGame.addActionListener(this);
		btnRangliste.setBounds(160, 320, 180, 50);
		
		add(btnStartGame, this);
		add(btnRangliste, this);

		this.setSize(500, 500);
		this.setVisible(true);
		
	}

	public void actionPerformed(ActionEvent arg0) {
		if (arg0.getSource() == btnStartGame) {
			g.startGame();
			this.setVisible(false);
		}
		
	}

	public GUI getG() {
		return g;
	}
}

Klasse GUI:
Java:
package snake;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;


import javax.swing.*;

class GUI extends Frame implements KeyListener, MouseListener, MouseMotionListener{
	
	Color c = new Color(0x008000);
	Color s = new Color(0x000000);
	Color f = new Color(0xFF0000);
	Graphics g;
	int pressedKey;

	Main main = new Main();
	
	boolean keyReleased;
	Point dragPosition = new Point();
	
	/*Main p;
	public GUI(){
		this.addKeyListener(this);
		p = new Main("SpaceUfo", 150, 100, this);
		this.addWindowListener(new WindowAdapter(){
				public void windowClosing(WindowEvent e){
				System.exit(0);
				}
			});
	}*/


	class CloseListener extends WindowAdapter {
		public void windowClosing(WindowEvent e) {
			System.exit(0);
		}
	}

	GUI() {
		this.setTitle("Snake");
		this.setBackground(c);
		this.setResizable(false);
		this.addWindowListener(new CloseListener());
		this.setSize(500, 500);	
		this.setUndecorated(true);
		
		this.addKeyListener(this);
		this.addMouseListener(this);
		this.addMouseMotionListener(this);
	}
	
	public void keyPressed(KeyEvent ke){
		int key = ke.getKeyCode();
		main.moveSnake(key);
		this.setPressedKey(key);
		
		this.repaint();
	}
	
	protected void startGame(){
		this.setVisible(true);
		main.startGame();
		//main.drawFood();
		this.repaint();
	}
	
	public void openRanking(){
		this.setVisible(true);
		main.openRanking();
		//this.repaint();
	}
	
	public void createRank(String PlayerName){
		main.createRank(PlayerName);
	}
	
	@Override 
	public void paint(Graphics g){
		main.playerCollision();
		main.wallCollision();
		main.foodCollision(getPressedKey());
		
		for (int i = 0; i < main.getSnakeLenght(); i++){
			g.setColor(s);
			g.fillRect((main.getxSnakePos(i)), (main.getySnakePos(i)), 10, 10);
		}
		g.setColor(f);
		g.fillRect((main.getyFoodPos()), (main.getyFoodPos()), 10, 10);
		
		System.out.println("Food X:		"+main.getxFoodPos());
		System.out.println("Snake X:	"+main.getxSnakePos(0));
		System.out.println("Food Y:		"+main.getyFoodPos());
		System.out.println("Snake Y:	"+main.getySnakePos(0));
		
	}
	//@Override 
	public void mousePressed (MouseEvent e)
	{
	                dragPosition.x = e.getX();
	                dragPosition.y = e.getY();
	}
	
	//@Override 
	public void mouseDragged (MouseEvent e)
	{
	                Point p = this.getLocation();
	                this.setLocation(p.x + e.getX() - dragPosition.x, p.y + e.getY() - dragPosition.y);
	}
	
	public int getPressedKey() {
		return pressedKey;
	}

	public void setPressedKey(int pressedKey) {
		this.pressedKey = pressedKey;
	}
	
	public void dispose(){
		this.dispose();
	}
	

	public void mouseMoved(MouseEvent e) {
		// TODO Auto-generated method stub
		
	}

	public void mouseClicked(MouseEvent e) {
		// TODO Auto-generated method stub
		
	}

	public void mouseEntered(MouseEvent e) {
		// TODO Auto-generated method stub
		
	}

	public void mouseExited(MouseEvent e) {
		// TODO Auto-generated method stub
		
	}

	public void mouseReleased(MouseEvent e) {
		// TODO Auto-generated method stub
		
	}

	public void keyReleased(KeyEvent arg0) {
		// TODO Auto-generated method stub
		
	}

	public void keyTyped(KeyEvent arg0) {
		// TODO Auto-generated method stub
		
	}
}

Klasse Main:
Java:
package snake;

import java.io.*;
import java.util.ArrayList;

public class Main extends Thread {
	protected int Score = 0;
	private int KeyUp = 0;
	private int KeyDown = 0;
	private int KeyLeft = 0;
	private int KeyRight = 0;
	private long PlayTime;
	private double AvrPoints;

	private boolean inGame;
	private File datei = new File("Ranking.txt"); // Speicherdatei

	private ArrayList<int[]> snakePos = new ArrayList<int[]>(); // rz	
	private ArrayList<int[]> FoodPos = new ArrayList<int[]>();
	int SpielfeldGroesse = 50;
	
	private int SnakeLenght = 3;
	private int xSnakeStartPos = (int) (Math.random() * SpielfeldGroesse);
	private int ySnakeStartPos = (int) (Math.random() * SpielfeldGroesse);
	private int SnakeDotSize = 10;
	private int space = 0;
	private int direction = 0;

	private int xFoodPos = (int) (Math.random() * SpielfeldGroesse);
	private int yFoodPos = (int) (Math.random() * SpielfeldGroesse);

	protected void startGame() {
		inGame = true;
		xSnakeStartPos = xSnakeStartPos*10;
		ySnakeStartPos = ySnakeStartPos*10;
		xFoodPos = xFoodPos*10;
		yFoodPos = yFoodPos*10;
		
		snakePos.add(new int[]{xSnakeStartPos, ySnakeStartPos}); // rz
		FoodPos.add(new int[]{xFoodPos, yFoodPos});
		for (int i = 1; i < SnakeLenght; i++) {
			snakePos.add(0, new int[]{(snakePos.get(0)[0] + SnakeDotSize + space), snakePos.get(0)[1]}); // rz
		}
	}
	
	protected void playerCollision() {
		for (int i = 1; i < SnakeLenght; i++) {
			if ((snakePos.get(0)[0] == snakePos.get(i)[0])
					&& (snakePos.get(0)[1] == snakePos.get(i)[1])) {
				this.gameOver();
			}
		}
	}

	protected void wallCollision() {
		if (snakePos.get(0)[0] > 490 || snakePos.get(0)[1] > 490 || snakePos.get(0)[0] < 0 || snakePos.get(0)[1] < 0) {
			this.gameOver();
		} 
	}

	protected void foodCollision(int pressedKey) {
		if (FoodPos.get(0)[0] == snakePos.get(0)[0] && FoodPos.get(0)[1] == snakePos.get(0)[1]) {
			System.out.println("foodCollision detected");
			pointUp();
			addDot(pressedKey);
		}
	}

	protected void moveSnake(int pressedKey) {
		boolean didChange = false;
		
		if (pressedKey == 37 && direction != 2) {
		
			//xSnakePos.set(0, xSnakePos.get(0) - SnakeDotSize - space);
			snakePos.add(0, new int[] {(snakePos.get(0)[0]) - SnakeDotSize - space, (snakePos.get(0)[1])}); //rz
			KeyLeft++;
			this.direction = 1; //1 steht für links
			didChange = true;
		}
		else if (pressedKey == 39 && direction != 1) {
			//xSnakePos.set(0, xSnakePos.get(0) + SnakeDotSize + space);
			snakePos.add(0, new int[] {(snakePos.get(0)[0]) + SnakeDotSize + space, (snakePos.get(0)[1])}); //rz
			KeyRight++;
			this.direction = 2; //2 steht für rechts
			didChange = true;
		}
		else if (pressedKey == 38 && direction != 4) {
			//ySnakePos.set(0, ySnakePos.get(0) - SnakeDotSize - space);
			snakePos.add(0, new int[] {(snakePos.get(0)[0]), (snakePos.get(0)[1]) - SnakeDotSize - space }); //rz
			KeyUp++;
			this.direction = 3; //3 steht für oben
			didChange = true;
		}
		else if (pressedKey == 40 && direction != 3) {
			//ySnakePos.set(0, ySnakePos.get(0) + SnakeDotSize + space);
			snakePos.add(0, new int[] {(snakePos.get(0)[0]), snakePos.get(0)[1] + (SnakeDotSize) + space }); //rz
			KeyDown++;
			this.direction = 4; //4 steht für unten
			didChange = true;
		}
		if(didChange) {
			snakePos.remove(snakePos.size()-1); //rz
		}
	}

	/*protected void drawFood() {
		for (boolean aufSchlange = true; aufSchlange == true;) {
			FoodPos.add(new int[]{xFoodPos, yFoodPos});
			for (int i = 0; i < SnakeLenght; i++) {
				if (FoodPos.get(0)[0] == snakePos.get(i)[0]
						&& FoodPos.get(0)[1] == snakePos.get(i)[1]) {
					aufSchlange = true;
				} else {
					aufSchlange = false;
				}
			}
		}
	}*/

	protected void addDot(int pressedKey) {
		SnakeLenght++;
		
		if (pressedKey == 37) {
			snakePos.add(0, new int[] {(snakePos.get(0)[0]) - SnakeDotSize - space, (snakePos.get(0)[1])}); //rz
		}
		else if (pressedKey == 39) {
			snakePos.add(0, new int[] {(snakePos.get(0)[0]) + SnakeDotSize + space, (snakePos.get(0)[1])}); //rz
		}
		else if (pressedKey == 38) {
			snakePos.add(0, new int[] {(snakePos.get(0)[0]), (snakePos.get(0)[1]) - SnakeDotSize - space }); //rz
		}
		else if (pressedKey == 40) {
			snakePos.add(0, new int[] {(snakePos.get(0)[0]), snakePos.get(0)[1] + (SnakeDotSize) + space }); //rz
		}
		
		newFood();
	}
	
	protected void gameOver(){
		System.out.println(Score);
		System.out.println(KeyLeft);
		System.out.println(KeyRight);
		GameOverGUI gog = new GameOverGUI();
	}

	protected void pointUp() {
		Score++;
		// GUI.setScore(Score);
	}
	
	private void newFood(){
		xFoodPos = (int) (Math.random() * SpielfeldGroesse);
		yFoodPos = (int) (Math.random() * SpielfeldGroesse);
		xFoodPos = xFoodPos*10;
		yFoodPos = yFoodPos*10;
		
		System.out.println("NewFood: Ich wurde ausgefürt");
		
		for (int i = 0; i < SnakeLenght; i++){
			if (xFoodPos == snakePos.get(i)[0] && yFoodPos == snakePos.get(i)[1]) {
				xFoodPos = (int) (Math.random() * SpielfeldGroesse);
				yFoodPos = (int) (Math.random() * SpielfeldGroesse);
				xFoodPos = xFoodPos*10;
				yFoodPos = yFoodPos*10;
			}
		}
		FoodPos.set(0, new int[]{xFoodPos, yFoodPos});
	}
	
	protected void createRank(String PlayerName) {
		FileDal writer = new FileDal();
		String PlayTimeS = String.valueOf(getPlayTime());
		String AvrPointsS = String.valueOf(getAvrPoints());
		try{
			writer.createRank(getScore(), getKeyUp(), getKeyDown(), getKeyLeft(), getKeyRight(), PlayTimeS, AvrPointsS, PlayerName,datei);
			System.out.println("Rangliste wurde erstellt");
		} catch(IOException e){
			System.out.println(e);
		}
	}

	protected void openRanking() {
		FileDal reader = new FileDal();
		try {
			reader.openRank(datei);
		} catch (IOException e) {
			System.out.println(e);
		}
	}	
	
	public int getSnakeLenght() {
		return SnakeLenght;
	}

	public int getySnakePos(int index) {
		//return this.ySnakePos.get(index);
		return this.snakePos.get(index)[1]; //rz
	}

	public int getxSnakePos(int index) {
		//return this.xSnakePos.get(index);
		return this.snakePos.get(index)[0]; //rz
	}
	
	public int getyFoodPos(){
		return this.FoodPos.get(0)[1];
	}
	
	public int getxFoodPos(){
		return this.FoodPos.get(0)[0];
	}

	public int getScore() {
		return Score;
	}

	public int getKeyUp() {
		return KeyUp;
	}

	public int getKeyDown() {
		return KeyDown;
	}

	public int getKeyLeft() {
		return KeyLeft;
	}

	public int getKeyRight() {
		return KeyRight;
	}

	public long getPlayTime() {
		return PlayTime;
	}

	public double getAvrPoints() {
		return AvrPoints;
	}	

}

Klasse FileDal:
Java:
package snake;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

public class FileDal {
	
	/*public void createRank(int Score, int KeyUp, int KeyDown, int KeyLeft, int KeyRight, long PlayTime, double AvrPoints, char PlayerName, File datei){
		try {
			FileOutputStream out = new FileOutputStream(datei, true); //True: Überschreibt die Datei nicht sondern schreibt am Ende der Datei weiter
			DataOutputStream dout = new DataOutputStream(out);
			
			dout.writeInt(Score);
			dout.writeInt(KeyUp);
			dout.writeInt(KeyDown);
			dout.writeInt(KeyLeft);
			dout.writeInt(KeyRight);
			dout.writeLong(PlayTime);
			dout.writeDouble(AvrPoints);
			//dout.writeChar(PlayerName);
			dout.close();
			
		} catch(IOException e) {
			System.out.println(e);
		}
	}
	public void openRank(File datei){
		try{
			FileInputStream in = new FileInputStream(datei);
			DataInputStream din = new DataInputStream(in);
			System.out.println("Erreichte Punktzahl:                   " + din.readInt());
			System.out.println("Anzahl Tastenanschläge nach Oben:      " + din.readInt());
			System.out.println("Anzahl Tastenanschläge nach Unten:     " + din.readInt());
			System.out.println("Anzahl Tastenanschläge nach Links:     " + din.readInt());
			System.out.println("Anzahl Tastenanschläge nach Rechts:    " + din.readInt());
			System.out.println("Gespielte Zeit:                        " + din.readLong());
			System.out.println("Erreichte Punkte pro Minute:           " + din.readDouble());
			System.out.println("Spielername:                           " + din.readChar());
			
		} catch(IOException e) {
			System.out.println(e);
		}
	}*/
	
	
	public void createRank(int Score, int KeyUp, int KeyDown, int KeyLeft, int KeyRight, String PlayTime, String AvrPoints, String PlayerName, File datei) throws IOException{
		BufferedWriter bw = new BufferedWriter(new FileWriter(datei));
		System.out.println("Rechts: " + KeyRight);
		String KeyRightS = ""+ KeyRight;
		String KeyLeftS = String.valueOf(KeyLeft);
		String KeyUpS = String.valueOf(KeyUp);
		String KeyDownS = String.valueOf(KeyDown);
		String ScoreS = String.valueOf(Score);
		
		System.out.println("Neu Rechts; " + KeyRight);
		
		bw.write(ScoreS);
		bw.newLine();
		bw.write(KeyUpS);
		bw.newLine();
		bw.write(KeyDownS);
		bw.newLine();
		bw.write(KeyLeftS);
		bw.newLine();
		bw.write(KeyRightS);
		bw.newLine();
		bw.write(PlayTime);
		bw.newLine();
		bw.write(AvrPoints);
		bw.newLine();
		bw.write(PlayerName);
		bw.newLine();
		
		bw.flush();
		bw.close();
	}
	
	public void openRank(File datei) throws IOException{
		BufferedReader br = new BufferedReader(new FileReader(datei));
		
		String line;
		
		while((line = br.readLine()) != null){
			System.out.println(line);
		}
		br.close();
		
	}
}

Klasse GameOverGUI:
Java:
package snake;

import java.awt.*;
import java.awt.event.*;

import javax.swing.*;

class GameOverGUI extends Frame implements ActionListener {
	
	GUI g = new GUI();
	
	String PlayerName;
	
	TextField txtPlayerName = new TextField();
	Button btnStartGame = new Button("Neues Spiel?");
	Button btnLeaveGame = new Button("Spiel verlassen?");
	Button btnRangliste = new Button("Rangliste");
	Button btnSetName = new Button("Ok");
	Color c = new Color(0x008000);

	class CloseListener extends WindowAdapter {
		public void windowClosing(WindowEvent e) {
			System.exit(0);
		}
	}

	GameOverGUI() {

		this.setTitle("Game Over");
		this.setBackground(c);
		this.setResizable(false);
		
		this.addWindowListener(new CloseListener());
		
		this.setLayout(null);

		txtPlayerName.setBounds(160, 110, 180, 50);
		btnSetName.setBounds(200, 170, 180, 50);
		btnSetName.addActionListener(this);
		btnSetName.setSize(100, 35);
		btnStartGame.setBounds(160, 270, 180, 50);
		btnStartGame.addActionListener(this);
		btnStartGame.setSize(180, 45);
		btnLeaveGame.setBounds(160, 330, 180, 50);
		btnLeaveGame.addActionListener(this);
		btnLeaveGame.setSize(180, 45);
		btnRangliste.setBounds(160, 390, 180, 50);
		btnRangliste.addActionListener(this);
		btnRangliste.setSize(180, 45);
		
		add(txtPlayerName, this);
		add(btnSetName, this);
		add(btnStartGame, this);
		add(btnLeaveGame, this);
		add(btnRangliste, this);
		
		this.setSize(500, 500);
		this.setVisible(true);
		
	}

	
	public void actionPerformed(ActionEvent arg0) {
		if (arg0.getSource() == btnRangliste) {
			g.openRanking();
			this.setVisible(false);
		}
		if (arg0.getSource() == btnStartGame) {
			g.startGame();
			this.setVisible(false);
		}
		if (arg0.getSource() == btnLeaveGame) {
			g.dispose();
			dispose();
		}
		if (arg0.getSource() == btnSetName) {
			g.createRank(PlayerName = txtPlayerName.getText());
		}
	}
/*
	public GUI getG() {
		return g;
	}*/
}


Hier ist noch ein Bild vom Spiel. Darin sind die Aktuellen X und Y Koordinaten vom Essen (Roter Punkt) und von dem Kopf der Schlange ersichtlich. (Bild zu Problem 1)
show_img.php
[/URL][/IMG]

Direkt Link: Kostenloser Bilder Upload Service - Gratis Bilder hochladen / uploaden ohne Anmeldung


Vielen Dank für eure Hilfe.

Kakshi
 
Kurz zu Problem 1, Klasse Gui Zeile 97
[Java] g.fillRect((main.getyFoodPos()), (main.getyFoodPos()), 10, 10);[/code]

Sollte das eine nicht die x und das andere die y Position sein, anstatt 2 mal y? 😉
 
danke, das Problem ist somit behoben.

Neu kommt noch dazu, dass wenn das GameOverGUI aufgerufen wird, dieses ununterbrochen geöffnet wird. Also es wird nicht nur einmal geöffnet, es werden immer neue GameOverGUI Fenster geöffnet bis ich die Java Anwendung unten an der Taskliste beende.


Hat noch jemand einen Vorschlag wie und wo ich meine Threads setzen sollte?
 
Verrate doch wo und wie du das GameOverGUI aufrufst. Ich denke die wenigsten haben Lust erstmal ein paar hundert Zeilen Code zu durchsuchen, bis sie die passende Stelle finden.

Gruß Fant
 
Hallo Zusammen

Also das GameOverGUI wird durch die Methode gameOver (Zeile 139) in der Klasse Main aufgerufen. Diese Methode wird wiederum von den Methoden PlayerCollision (Zeile 46) oder WallCollision (Zeile 55)aufgerufen und zwar sobald die Schlange in die Wand oder sich selbst fährt.


Die Rangliste wird durch den Button SetName (Zeile 76) im GameOverGUI aufgerufen. Dieser Button ruft die Methode createRank (Zeile 82) in der Klasse GUI auf. Diese Methode wiederum ruft in der Main Klasse die Methode createRank (Zeile 170) auf. Die Ruft den FileDal auf, welcher die Rangliste erstellt. Aber mit den falschen werten (Alles 0 ausser der Name stimmt)


Gruss Kakashi
 

Zurück
Oben