I'm working with students to make a snake game, and we are just about finished but the last thing we added does not work: if the snake collides with itself, it doesn't end the game! The logic behind the check is correct, and it seems to be more reliable at a lower framerate, though it still does not work correctly at all times.
The code to detect the collision is in draw(), and is written as:
System.out.println("headX: " + x.get(x.size()-1) + "\theadY: " +y.get(y.size()-1));
for (int i=0; i < x.size()-1; i++) {
System.out.println("i: " + i + "\tx: " + x.get(i) + "\ty: " + y.get(i));
if ((x.get(x.size()-1) == x.get(i)) && (y.get(y.size()-1) == y.get(i))) {
println("=======================================");
alive = false;
textSize(90);
text("YOU LOSE", 300, 400);
}
}
This includes some print statements I've added to check, and it does in fact have the condition in the if statement be satisfied without executing the code inside the if statement.
The snake is saved in an arraylist as a series of x and y coordinates, and a rectangle is drawn from each of them. This for loop is supposed to check the coordinates of each of the snake pieces except for the head and compare it to the head. Even when it is true, the code does not always execute.
Here is the entire code, written in the Processing IDE
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Random;
boolean moveRight = true;
boolean moveLeft = false;
boolean moveUp = false;
boolean moveDown = false;
boolean alive = true;
Random food = new Random();
int foodX = food.nextInt(100)*10;
int foodY = food.nextInt(100)*10;
ArrayList<Integer> x = new ArrayList<Integer>(Arrays.asList(0, 10, 20, 30, 40, 50, 60, 70, 80, 80, 70, 60, 50, 40, 30, 20, 20));
ArrayList<Integer> y = new ArrayList<Integer>(Arrays.asList(0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 10, 10, 10, 10, 10, 10, 20));
void setup() {
size(1000, 1000);
frameRate(60);
}
void draw() {
if (alive) {
background(242, 195, 53);
if (moveRight) {
int headX = x.get(x.size()-1)+10;
int headY = y.get(y.size()-1);
x.add(headX);
y.add(headY);
//if you eat food, stuff below is false
if (headX != foodX || headY != foodY) {
x.remove(0);
y.remove(0);
} else {
updateFood();
}
}
if (moveLeft) {
int headX = x.get(x.size()-1)-10;
int headY = y.get(y.size()-1);
x.add(headX);
y.add(headY);
if (headX != foodX || headY != foodY) {
x.remove(0);
y.remove(0);
} else {
updateFood();
}
}
if (moveUp) {
int headX = x.get(x.size()-1);
int headY = y.get(y.size()-1)-10;
x.add(headX);
y.add(headY);
if (headX != foodX || headY != foodY) {
x.remove(0);
y.remove(0);
} else {
updateFood();
}
}
if (moveDown) {
int headX = x.get(x.size()-1);
int headY = y.get(y.size()-1)+10;
x.add(headX);
y.add(headY);
if (headX != foodX || headY != foodY) {
x.remove(0);
y.remove(0);
} else {
updateFood();
}
}
drawFood();
fill(25, 62, 125);
for (int i=0; i < x.size(); i++) {
rect(x.get(i), y.get(i), 10, 10);
}
if (x.get(x.size() -1) >1000 || y.get(y.size() -1) > 1000 || x.get(x.size() -1) < 0 || y.get(y.size() -1) < 0) {
textSize(90);
text("YOU LOSE", 300, 400);
fill(255, 255, 255);
alive = false;
}
System.out.println("headX: " + x.get(x.size()-1) + "\theadY: " +y.get(y.size()-1));
for (int i=0; i < x.size()-1; i++) {
System.out.println("i: " + i + "\tx: " + x.get(i) + "\ty: " + y.get(i));
if ((x.get(x.size()-1) == x.get(i)) && (y.get(y.size()-1) == y.get(i))) {
println("=======================================");
alive = false;
textSize(90);
text("YOU LOSE", 300, 400);
}
}
}
}
void keyPressed()
{
if (key == 'd') {
if (!moveLeft) {
moveRight = true;
moveLeft = false;
moveUp = false;
moveDown = false;
}
}
if (key == 'a') {
if (!moveRight) {
moveLeft = true;
moveUp = false;
moveRight = false;
moveDown = false;
}
}
if (key == 'w') {
if (!moveDown) {
moveUp = true;
moveLeft = false;
moveDown = false;
moveRight = false;
}
}
if (key == 's') {
if (!moveUp)
moveUp = false;
moveLeft = false;
moveDown = true;
moveRight = false;
}
}
void drawFood() {
fill(255, 12, 12);
rect(foodX, foodY, 10, 10);
}
void updateFood() {
foodX = food.nextInt(100)*10;
foodY = food.nextInt(100)*10;
}
EDIT: Integers do not reliably work with ==, they must use .equals. Check out this question: Java: Integer equals vs. ==