1
\$\begingroup\$

I have been working on this snake game for a few days, and I have the basics down, but I was wondering if anyone could help me figure out the tail. I need it to follow the body, as it does in the original game. I have read through a lot of really helpful forums, but as I am still new to code and the processing language, I would like a more specific idea as to how I can go about making the tail work.

This is what I have so far:

PImage snake;
PImage arrow1;
PImage arrow2;
PImage arrow3;
PImage arrow4;
PFont font;

boolean state = false;

int snakeSize = 1;
int maxLength = 25;
int x [] = new int [maxLength];
int y [] = new int [maxLength];
int j;

int foodX = (round(random(49)+1*10));
int foodY = (round(random(49)+1*10));

int speed = 1;
int xspeed = 0;
int yspeed = 0;

int foodCount = 0;

int page = 0;

void setup() {
  size(1280, 800);
  x[0] = 250;
  y[0] = 250;
  snake = loadImage ("snake.png");
  arrow1 = loadImage ("arrow_up.png");
  arrow2 = loadImage ("arrow_down.png");
  arrow3 = loadImage ("arrow_left.png");
  arrow4 = loadImage ("arrow_right.png");
  font = createFont ("Arial Rounded MT Bold", 40);
}
void draw() {
  background(200);

  //PLAYING FIELD
  stroke(100);
  fill(225);
  rect(10, 10, 900, 780);

  //BUTTON
  stroke(255);
  fill (#0EEB52);
  rect(990, 690, 200, 52, 25);

  //Page 1--------------------------------------------
  //MENU
  if (page == 0) {
    textFont(font);
    textAlign(CENTER);
    fill(255);
    textSize(12);
    text ("Made by Brya Patterson", 1090, 775);
    textSize(40);
    text ("Play!", 1090, 730);
    textSize(50);
    text ("SNAKE", 1090, 85);
    image (snake, 930, 15);
  } 

  //Page 2--------------------------------------------
  //GAME
  else if (page == 1) {
    stroke(100);
    fill(255);
    textSize(12);
    text ("Made by Brya Patterson", 1090, 775);
    textSize(40);
    text ("Home", 1090, 730);
    textSize(50);
    text ("SNAKE", 1090, 85);
    image (snake, 930, 15);
    text ("Score:"+foodCount, 1080, 310);
    textSize(17);
    text ("To begin, press any key in the key pad\n 
        or use arrow keys to move.", 1085, 653);

    //KEY PAD
    image (arrow1, 1055, 375, 80, 80);
    image (arrow2, 1055, 525, 80, 80);
    image (arrow3, 975, 450, 80, 80);
    image (arrow4, 1130, 450, 80, 80);

    //SNAKE---------------------------------------------
    //BODY
    for (int i = 0; i < snakeSize; i++) {
      fill (#ACE235);
      rect (x[i], y[i], 10, 10);

      x [i] = x[i]+xspeed;
      y [i] = y[i]+yspeed;

      if (x[i]< 10 || x[i] > 910 || y[i] < 15 || y[i] > 790) {
        page = 2;
      }
    }

    //FOOD----------------------------------------------
    fill (#F0ACBD);
    rect(foodX, foodY, 12, 12);
    if (snakeSize < y.length) {
      if (x[0] >= foodX-10 && x[0] <= foodX+10 && y[0] >= foodY-10 && y[0] <= foodY+10) {
        foodX = (round(random(50))+1)*10;
        foodY = (round(random(50))+1)*10;
        snakeSize++;

        if (j!=1) {
          x[snakeSize-1] = x[snakeSize-2]-0;
          y[snakeSize-1] = y[snakeSize-2]-10;
        }
        //SCORE---------------------------------------------
        foodCount++;
      }
    }
  }

  //Page 3--------------------------------------------
  //END/RESTART
  else if (page == 2) {
    fill(255);
    rect(0, 0, 1280, 800);
    stroke(255);
    fill (#0EEB52);
    rect(990, 690, 200, 52, 25);
    fill(200);
    textAlign(CENTER);
    textFont(font);
    textSize(103);
    text ("SNAKE", width/2, 180);
    image (snake, 581, 169, 254, 250);
    textSize (60);
    text("You Died! \nPress 'Home' \nto restart.", width/2, height/2);
    fill(255);
    textSize(40);
    text ("Home", 1090, 730);
  }
}

//CONTROL MOVEMENT and BUTTON STUFF
void keyPressed() {
  if (keyCode == UP) {
    xspeed = 0;
    yspeed = -2;
  }
  if (keyCode == DOWN) {
    xspeed = 0;
    yspeed = 2;
  }
  if (keyCode == LEFT) {
    xspeed = -2;
    yspeed = 0;
  }
  if (keyCode == RIGHT) {
    xspeed = 2;
    yspeed = 0;
  }
}
void mousePressed() {
  if (mouseX > 955 && mouseX < 955+200 && mouseY > 690 && mouseY < 690+52) {
    page++; 
    if (page == 3) {
      x[0] = 300;
      y[0] = 300;
      x[1] = 300;
      y[1] = 300;
      page = 0;
    }
  }
  //arrow1-UP
  if (mouseX > 1055 && mouseX < 1055+80 && mouseY > 375 && mouseY < 375+80) {
    xspeed = 0;
    yspeed = -2;
  }
  //arrow2-DOWN
  if (mouseX > 1055 && mouseX < 1055+80 && mouseY > 525 && mouseY < 525+80) {
    xspeed = 0;
    yspeed = 2;
  }
  //arrow3-LEFT
  if (mouseX > 975 && mouseX < 975+80 && mouseY > 450 && mouseY < 450+80) {
    xspeed = -2;
    yspeed = 0;
  }
  //arrow4-RIGHT
  if (mouseX > 1130 && mouseX < 1130+80 && mouseY > 450 && mouseY < 450+80) {
    xspeed = 2;
    yspeed = 0;
  }
}
\$\endgroup\$
1
\$\begingroup\$

I'm not familiar with processing, only with java, but that shouldn't matter.

How I'd do it is to have an infinite array (in java an ArrayList) of vectors, each marking a position of a snake tile. When the snake wants to move, you first create a new vector in the heads new position, add it to the array, then check if it collides with any of the other snake tiles. If it does, then it's game over, otherwise check if it collides with the fruit.

As @wondra pointed out, a Deque is a better solution than an ArrayList, because it's easier to insert and remove elements from and to the ends of the list.

If it didn't collide with the fruit, remove the first piece (the last tail), this will make the snake win and lose a tile, thus it appears as it moved forward. You'll probably need to shift the other tiles back to make the snake occupy the beginning of the array.

If it collided with the fruit, then don't di anything, this will make the snake get a new tile.

\$\endgroup\$
  • \$\begingroup\$ I would suggest some of Deque (double-eneded queue) implementations - it both support removing and adding from front and back, which should make implementing easier compared to a bit impractical java's list API. \$\endgroup\$ – wondra Mar 17 '17 at 11:32
  • \$\begingroup\$ Java's ArrayList is a deque - it implements the Deque interface & supports inserting & removing elements from a given index. If you're concerned about ArrayList's deque performance consider ArrayDeque. \$\endgroup\$ – Pikalek Mar 18 '17 at 4:16
  • \$\begingroup\$ I like the waay he handles it: youtu.be/AaGK-fj-BAM \$\endgroup\$ – user100681 Nov 28 '17 at 9:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.