Ich stelle meine Frage mal am Ende, damit ich nicht spoilere.
Die Aufgabe 17 wurde als richtig erkannt (Apfel darf nicht innerhalb der Schlange existieren) und habe das Spiel auch zu Ende programmiert. Aber habe beim Testen festgestellt, dass der Apfel trotzdem innerhalb meiner Schlange erscheinen kann. Was habe ich falsch gemacht?
"Snake.java"
package ...
import ...
import ...
import ...
public class Snake {
private static final String HEAD_SIGN = ...
private static final String BODY_SIGN = ...
private List<GameObject> snakeParts = new ArrayList<>();
public boolean isAlive = true;
private Direction direction = Direction.LEFT;
public boolean checkCollision(GameObject gameObject) {
for (int i = 0; i < snakeParts.size(); i++) {
if (gameObject.x == snakeParts.get(i).x && gameObject.y == snakeParts.get(i).y) {
return true;
}
}
return false;
}
public GameObject createNewHead() {
GameObject newHead;
switch (direction) {
case LEFT:
newHead = new GameObject(snakeParts.get(0).x-1, snakeParts.get(0).y);
break;
case RIGHT:
newHead = new GameObject(snakeParts.get(0).x+1, snakeParts.get(0).y);
break;
case UP:
newHead = new GameObject(snakeParts.get(0).x, snakeParts.get(0).y-1);
break;
default:
newHead = new GameObject(snakeParts.get(0).x, snakeParts.get(0).y+1);
break;
}
return newHead;
}
public void draw(Game game) {
if (isAlive) { // Schlange lebt
game.setCellValueEx(snakeParts.get(0).x, snakeParts.get(0).y, Color.NONE, HEAD_SIGN, Color.BLACK, 75); // Anzeigen des Kopfes - Farbe schwarz
}
else { // Schlange töt
game.setCellValueEx(snakeParts.get(0).x, snakeParts.get(0).y, Color.NONE, HEAD_SIGN, Color.RED, 75); // Anzeigen des Kopfes - Farbe rot
}
for (int i=1 ; i < snakeParts.size() ; i++) {
//game.setCellValue(snakeParts.get(i).x, snakeParts.get(i).y, BODY_SIGN); // Anzeigen des Körpers - gelöscht mit Aufgabe 7
if (isAlive) { // Schlange lebt
game.setCellValueEx(snakeParts.get(i).x, snakeParts.get(i).y, Color.NONE, BODY_SIGN, Color.BLACK, 75); // Anzeigen des Körpers - Farbe schwarz
} else { // Schlange töt
game.setCellValueEx(snakeParts.get(i).x, snakeParts.get(i).y, Color.NONE, BODY_SIGN, Color.RED, 75); // Anzeigen des Körpers - Farbe rot
}
}
}
public int getLength() {
return snakeParts.size();
}
public void move(Apple apple) {
GameObject head = createNewHead();
if (head.x < 0 || head.y < 0 || head.x >= SnakeGame.WIDTH || head.y >= SnakeGame.HEIGHT) {
isAlive = false;
}
else {
if (checkCollision(head)) {
isAlive = false;
} else {
snakeParts.add (0, head);
if (head.x == apple.x && head.y == apple.y) {
apple.isAlive = false;
} else {
removeTail();
}
}
}
}
public void setDirection(Direction direction) {
if (this.direction == Direction.LEFT && direction != Direction.RIGHT && snakeParts.get(0).x != snakeParts.get(1).x) {
this.direction = direction;
}
if (this.direction == Direction.RIGHT && direction != Direction.LEFT && snakeParts.get(0).x != snakeParts.get(1).x) {
this.direction = direction;
}
if (this.direction == Direction.UP && direction != Direction.DOWN && snakeParts.get(0).y != snakeParts.get(1).y) {
this.direction = direction;
}
if (this.direction == Direction.DOWN && direction != Direction.UP && snakeParts.get(0).y != snakeParts.get(1).y) {
this.direction = direction;
}
}
public Snake (int x, int y) {
GameObject first = ...
GameObject second = ...
GameObject third = ...
snakeParts.add(first);
snakeParts.add(second);
snakeParts.add(third);
}
public void removeTail() {
snakeParts.remove(snakeParts.size()-1);
}
}
"SnakeGame.java"
package ...
import ...
public class SnakeGame extends Game {
private Snake snake; // Schlange definiert
private Apple apple; // Apfel definiert
private int turnDelay;
private boolean isGameStopped;
private int score;
private static final int GOAL = ...
public static final int HEIGHT = ...
public static final int WIDTH = ...
private void createGame() {
snake = new Snake(WIDTH/2, HEIGHT/2);
turnDelay = ...
setTurnTimer(turnDelay); // Timer-Dauer setzen
createNewApple();
isGameStopped = false;
score = ...
setScore(score);
drawScene(); // zuerst Rasterfeld aufrufen
}
private void createNewApple() {
Apple newApple;
do {
newApple = new Apple (getRandomNumber(WIDTH), getRandomNumber(HEIGHT));
} while (snake.checkCollision(newApple) == true);
apple = newApple;
}
private void drawScene() {
for (int x = 0; x < WIDTH; x++) { // x-schleife 0 - width
for (int y = 0; y < HEIGHT; y++) { // y-schleife 0-height
// setCellColor(x, y, Color.DARKSEAGREEN); // Rasterfeld einfärben - gelöscht mit Aufgabe 10
setCellValueEx(x, y, Color.DARKSEAGREEN, "");
}
}
snake.draw(this); // Aufruf Snake.java
apple.draw(this);
}
private void gameOver() {
stopTurnTimer();
isGameStopped = true;
showMessageDialog(Color.RED, "GAME OVER", Color.BLACK, 75);
}
@Override
public void initialize() { // initialisieren
setScreenSize(WIDTH, HEIGHT); // Feldgröße (15 x 15)
isGameStopped = true;
showMessageDialog(Color.BLACK, "PRESS SPACE", Color.RED, 50);
}
@Override
public void onTurn(int time) {
snake.move(apple);
if (apple.isAlive == false) {
score = score + 5;
setScore(score);
turnDelay = turnDelay - 10;
setTurnTimer(turnDelay);
createNewApple();
}
if (snake.isAlive == false) {
gameOver();
}
if (snake.getLength() > GOAL) {
win();
}
drawScene();
}
@Override
public void onKeyPress(Key key) {
switch (key) {
case LEFT:
snake.setDirection(...
break;
case RIGHT:
snake.setDirection(...
break;
case UP:
snake.setDirection(...
break;
case DOWN:
snake.setDirection(...
break;
case SPACE:
if (isGameStopped == true) {
createGame();
}
default:
break;
}
}
private void win() {
stopTurnTimer();
isGameStopped = true;
showMessageDialog(...
}
}
while (!snake.checkCollision(newApple));
Hat nichts damit zu tun... ich sag es nur, weil es irgendwie komisch aussieht while (snake.checkCollision(newApple) == true); checkCollision gibt ja ein boolen zurück, z.B. true, dann würde das bedeuten (setzt man den Rückgabewert ein) while (true == true), also ist == true überflüssig und while (snake.checkCollision(newApple)) würde völlig ausreichen PPS: Wenn du die Bedingung vorher prüfst, dann ist es andersherum... das sollte also auch funktionieren.