New to processing (centipede) stuck on tail

Im fairly new to processing and im working on doing a basic game but im stuck on adding a tail to the centipede.

float x = 0;
float y = 0;
float spacing = 50;
float positiex = 200;
float positiey = 200;


void setup() {
  size(400, 300);
}

void draw() {
  background(0);
  stroke(255);

  x = 0;
  while (x < width) {
    line(x, 0, x, height);
    x = x + spacing;
  }

  y = 0;
  while (y < height) {
    line(0, y, width, y);
    y = y + spacing;
  }

  rect(positiex, positiey, 50, 50);
  fill(150);
}

void mouseClicked() {
  if (mouseY == constrain(mouseY, positiey - 50, positiey ) && mouseX == constrain(mouseX, positiex, positiex + 50)) {
    positiey = positiey - 50;
  }
  if (mouseY == constrain(mouseY, positiey + 50, positiey + 100 ) && mouseX == constrain(mouseX, positiex, positiex + 50)) {
    positiey = positiey + 50;
  }
  if (mouseX == constrain(mouseX, positiex  -50, positiex  )) {
    positiex = positiex - 50;
  }
  if (mouseX == constrain(mouseX, positiex  +50, positiex + 100  )) {
    positiex = positiex + 50;
  }
}

You can try with this to see a „tail“, though it‘s more of a „trail“, but it should give you a hint.

bool arr = new bool[8][6];

   arr[int(positiex/50)][int(positiey/50)] = true;
   
   for (int i = 0; i < arr.length; i++) {
      for (int j = 0; j < arr[i].length; j++) {
         if (arr[i][j]) {
            rect(i*50, j*50, 50, 50);
         }
      }
   }
1 Like

@crazybob5 remember to format your code using the </> icon and putting your code there :wink:

Taking the hint of @Lexyth and modifying a little bit, you can get something like this, but depends totally about what is exactly what you want… if you want the trial to be permanent, delete all about the variable “age” and set the fill(150,age[i][j]); to fill(150);, or if you want the trial to have a length store the position inside an array… :thinking:

float x = 0;
float y = 0;
float spacing = 50;
float positiex = 200;
float positiey = 200;
boolean[][] arr = new boolean[8][6];
float[][] age = new float[8][6];

void setup() {
size(400, 300);
}

void draw() {
background(0);
stroke(255);

x = 0;
while (x < width) {
line(x, 0, x, height);
x = x + spacing;
}

y = 0;
while (y < height) {
line(0, y, width, y);
y = y + spacing;
}

  arr[int(positiex/50)][int(positiey/50)] = true;
  age[int(positiex/50)][int(positiey/50)] = 10;
  
  for (int i = 0; i < arr.length; i++) {
     for (int j = 0; j < arr[i].length; j++) {
        if (arr[i][j]) {
          if(age[i][j]!=0)
          age[i][j]-=0.02; //touch this parameter to increase the time or decrease the time it vanishes
             fill(150,map(age[i][j],10,0,255,0));
           rect(i*50, j*50, 50, 50);
        }
     }
  }
fill(150);
rect(positiex, positiey, 50, 50);
}

void mouseClicked() {
if (mouseY == constrain(mouseY, positiey - 50, positiey ) && mouseX == constrain(mouseX, positiex, positiex + 50)) {
positiey = positiey - 50;
}
if (mouseY == constrain(mouseY, positiey + 50, positiey + 100 ) && mouseX == constrain(mouseX, positiex, positiex + 50)) {
positiey = positiey + 50;
}
if (mouseX == constrain(mouseX, positiex -50, positiex )) {
positiex = positiex - 50;
}
if (mouseX == constrain(mouseX, positiex +50, positiex + 100 )) {
positiex = positiex + 50;
}
}
1 Like

Adding a tail is in whenever an event happens, or just once at the beginning? Please specify, and format your code with the </> button.

Its a bit like the game snake, but the movement is controlled by mouseclicks.

Thank you already. I want the tail to exist out of 9 rects. So like everytime it moves the last rect disappears.

Well, there are many ways to do it, but you can for example, store the last 9 positions in an array and fill the array taking off the oldest position stored.

I recommend you to use Objects, probably in a future all will be much easier with objects (detect collisions, increase the length, draw the snake, etc)

You can take a look at how i solved that here. The move() function is where it‘s handeled, and it‘s only ~3 real lines of code. It’s probably not the best implementation, but it works. Should also be closes to how the Snake Game actually works (probably).

Also, the class Tail only consists of a PVector and the display(x, y, w, h) method, so you can technically ignore it and use PVector directly (though you‘d have to add a display method()).

Summary
final int LENGTH = 10;
final float POSX = 50;
final float POSY = 50;
final float WIDTH = 10;
final float HEIGHT = 10;
final int SIZEW = 10;
final int SIZEH = 10;

Tail[] tails;

PVector dir;

void setup() {
   size(screen.width, screen.height);
   
   frameRate(5);
   
   dir = new PVector(0,1);
   
   tails = new Tail[0];
   
   tails[0] = new Tail(0,0);
}

void draw() {
   background(0,0,255);
   
   println(frameCount);
   
   drawGrid();
   
   println("drawGrid");
   
   drawSnake();
   
   println("drawSnake");
   
   move();
   
   println("move");
   
   turn();
}

void drawGrid() {
   strokeWeight(0);
   for (int x = 0; x < SIZEW; x++) {
      for (int y = 0; y < SIZEH; y++) {
         rect(POSX + x * WIDTH, POSY + y * HEIGHT, WIDTH, HEIGHT);
      }
   }
}

void drawSnake() {
   for (int i = tails.length-1; i > 0; i--) {
      strokeWeight((LENGTH-i)/2);
      fill((i/LENGTH)*255);
      if (tails[i] != null) {
         tails[i].display(POSX, POSY, WIDTH, HEIGHT);
      }
   }
   fill(255);
   strokeWeight(0);
}

void move() {
   for (int i = LENGTH; i > 0; i--) {
      if (tails[i-1] != null) tails[i] = tails[i-1];
   }
   println("move");
   tails[0] = new Tail(tails[1].pos.x + dir.x, tails[1].pos.y + dir.y);
}

void turn() {
   PVector[] possibleDirs = getDirs();
   
   dir = possibleDirs[int(random(0,possibleDirs.length))];
}

PVector[] getDirs() {
   PVector[] dirs = new PVector[0];
   
   int x = tails[0].pos.x;
   int y = tails[0].pos.y;
   
   if (x > 1) dirs = append(dirs,new PVector(-1, 0));
   if (x < WIDTH-1) dirs = append(dirs, new PVector(1,0));
   if (y > 1) dirs = append(dirs, new PVector(0,-1));
   if (y < HEIGHT-1) dirs = append(dirs, new PVector(0,1));
   
   return dirs;
}
class Tail {
   PVector pos;
   
   Tail(int x, int y) {
      pos = new PVector(x, y);
   }
   
   void display(float x, float y, float w, float h) {
      //line(x + pos.x * w, y + pos.y * h + h/2, x + pos.x * w + w, y + pos.y * h + h/2);
      
      //line(x + pos.x * w + w/2, y + pos.y * h, x + pos.x * w + w/2, y + pos.y * h + h);
      
      rect(x + pos.x * w, y + pos.y * h, w, h);
   }
}