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\$

2 Answers 2

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\$
3
  • \$\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, 2017 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, 2017 at 4:16
  • \$\begingroup\$ I like the waay he handles it: youtu.be/AaGK-fj-BAM \$\endgroup\$
    – user100681
    Nov 28, 2017 at 9:43
0
\$\begingroup\$

You can remove the last piece of the tail and put on the head

\$\endgroup\$
1
  • 1
    \$\begingroup\$ Welcome to StackExchange! Thank you for your answer, but can you elaborate? \$\endgroup\$
    – Evorlor
    Jan 28, 2022 at 4:31

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .