0

So I am making a snake game, but if I move from one direction to the other really fast then it says I made a collision with the body and ends the game (for example, if I am going left and I hit down and then left again really fast or down and right really fast, etc.)

I've tried a few things already. I changed the way that it checked for a collision by making it a .intersects rather than checking if (x == body[i][0] && y = body[i][1]). I also did a few System.out.println()'s to see if maybe something was going wrong there. I noticed that sometimes one of the values repeats (either x or y depending on the direction), but I can't figure out why... I figure that the repeating is why it messes up the collision, but I can't find the spot where it would be making it repeat.

x and y are being changed by a thread.

Here is the "Drawing" portion of my code. If you need any other snippets of code please let me know.

public void paintComponent(Graphics g) {
    super.paintComponent(g);

    if (numOfFood == 1) {//Checks wether there is food on the GUI
        g.setColor(Color.BLUE);
        g.fillRect(foodX,foodY,12,12);
    }
    else {
        foodX = random.nextInt(103)*12; //Both this and the below line get a random x or y value to put on GUI for food placement
        foodY = random.nextInt(57)*12;

        numOfFood = 1;
    }
    Rectangle headRect = new Rectangle( x, y, 12, 12 ); //Actual rectangle of the head

    Rectangle foodRect = new Rectangle(foodX, foodY, 12, 12); //Food rectangle

    g.setColor(Color.RED);
    g.fillRect(x,y,12,12); //Draws head of Snake
    g.setColor(Color.WHITE);
    g.fillRect(x+2,y+2,8,8); //Draws a white square in the head of the snake

    for (int i = 0; i < n; ++i) { //Collision Checker
        Rectangle bodyRect = new Rectangle(body[i][0],body[i][1],12,12);
        if ( headRect.intersects(bodyRect)) {
            for (int j = 0; j < n; ++j) {
                body[j][0] = -1;
                body[j][1] = -1;
            }
            numOfFood = 1;
            n = 0;
            x = 624;
            y = 348;
            endGame = true;
        }
    }

    g.setColor(Color.RED);
    if (n > 0) { //Puts the snakes body behind the head
        for (int i = 0;i < n; ++i) {
            g.fillRect(body[i][0],body[i][1],12,12);
        }
    }

    for (int i = n-1;i >= 0; --i) { //Inserts the head at the first part of the array so that the body moves
        if (body[i][0] != -1 && body[i][1] != -1) {
            body[i+1][0] = body[i][0];
            body[i+1][1] = body[i][1];
        }

        if (i == 0) {
            body[i][0] = x;
            body[i][1] = y;
        }
    }

    if (headRect.intersects(foodRect)) { //If the food rectangle and the head rectangle intersect then the snake got the food.
      numOfFood = 0;
      n++;
    }
}
Rob Hruska
  • 118,520
  • 32
  • 167
  • 192
Aerophite
  • 195
  • 2
  • 14
  • 1
    Again, you have program logic in the paintComponent method where it doesn't belong. The problem is that you can't fully control when or even if the paintComponent method will be called. By program logic, I mean any use of the random variable, any checking for collision, any setting of any variables that are outside of this method such as endGame, numOfFood, and the body array. You need to instead put this logic in your game loop, use it to set class fields, call repaint, and then have paintComponent just draw the images and that's it. – Hovercraft Full Of Eels Sep 25 '11 at 20:39
  • This is the same recommendation that I gave you in your last thread, but I guess you don't believe me? – Hovercraft Full Of Eels Sep 25 '11 at 20:40
  • @HovercraftFullOfEels I moved some of the stuff, I guess I didn't fully understand some of what you told me to do. I moved the border and the background color stuff into an earlier area and it helped. It made it where the snake could be drawn. I'll now do what you said here though. Thanks again. – Aerophite Sep 25 '11 at 20:49
  • The down-vote isn't mine by the way, and I'm not sure whose it is since they didn't leave a comment. – Hovercraft Full Of Eels Sep 25 '11 at 20:55
  • 1
    Ok, i got it to work perfectly, thank you very much @HovercraftFullOfEels. I guess I did truly misunderstand you the last time, I thought you just meant the border and the background needed to move. I would say that you were the one that answered my question but you didn't put an actual answer, you just commented. So I said you put a truly great comment. Thanks so much! – Aerophite Sep 25 '11 at 21:15
  • You're welcome -- glad you've got it working! – Hovercraft Full Of Eels Sep 25 '11 at 21:23

1 Answers1

0

When do you call paintComponent? I suspect that you have one method that continuously moves the snake forward in regular intervals, but paintComponent is responsible for making the snake longer.

You should move collision and moving the snake into the same method that is responsible for moving the head in the direction the snake is moving.

Otherwise, paintComponent might be called many times on one move update, and this is responsible for duplicates of x and y in your array.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Per Alexandersson
  • 2,443
  • 1
  • 22
  • 28