fisrt define your snake as an array of x and y location as the segment of body. to move the snake, first move the tail. the tail location will be the current location of the head. then move the head to desired location
//move the tail first
for (int i = body.size() - 1; i > 0; i--) {
body.get(i).x = body.get(i-1).x;
body.get(i).y = body.get(i-1).y;
}
then move the head
//the head will be the first element in the array
body.get(0).add(velocity); //adding speed to the head
so the whole code is
PVector vel;
PVector head;
char direction;
int len = 3;
float scl = 10;
int frameSpeed = 1;
ArrayList<PVector> body = new ArrayList<PVector>();
void setup() {
size(800, 500);
for (int i = 0; i < len; i++) {
body.add(new PVector(floor((width/2)/scl) * scl, floor(((height/2)/scl)) * scl));
}
head = body.get(0);
vel = new PVector(scl, 0);
}
void draw() {
background(0);
update();
show();
}
void update() {
for (int i = body.size() - 1; i > 0; i--) {
body.get(i).x = body.get(i-1).x;
body.get(i).y = body.get(i-1).y;
}
body.get(0).add(vel);
}
void show() {
fill(255);
colorMode(HSB);
for (int i = 0; i < body.size(); i++) {
fill(map(i, 0, len, 0, 255), 255, 255);
rect(body.get(i).x, body.get(i).y, scl, scl);
}
}
void setDirection(char dir) {
switch(dir) {
case 'r':
if (direction != 'l') {
vel.set(scl, 0);
direction = dir;
}
break;
case 'l':
if (direction != 'r') {
vel.set(-scl, 0);
direction = dir;
}
break;
case 'u':
if (direction != 'd') {
vel.set(0, -scl);
direction = dir;
}
break;
case 'd':
if (direction != 'u') {
vel.set(0, scl);
direction = dir;
}
break;
}
}
void keyPressed() {
if (key==CODED) {
switch(keyCode) {
case UP:
setDirection('u');
break;
case DOWN:
setDirection('d');
break;
case LEFT:
setDirection('l');
break;
case RIGHT:
setDirection('r');
break;
}
}
}
if you prefer to move the snake based on the mouse location, implement Forward Kinematic solution. but its quite dificult
/**
* Follow 3
* based on code from Keith Peters.
*
* A segmented line follows the mouse. The relative angle from
* each segment to the next is calculated with atan2() and the
* position of the next is calculated with sin() and cos().
*/
float[] x = new float[20];
float[] y = new float[20];
float segLength = 18;
void setup() {
size(640, 360);
strokeWeight(9);
stroke(255, 100);
}
void draw() {
background(0);
dragSegment(0, mouseX, mouseY);
for(int i=0; i<x.length-1; i++) {
dragSegment(i+1, x[i], y[i]);
}
}
void dragSegment(int i, float xin, float yin) {
float dx = xin - x[i];
float dy = yin - y[i];
float angle = atan2(dy, dx);
x[i] = xin - cos(angle) * segLength;
y[i] = yin - sin(angle) * segLength;
segment(x[i], y[i], angle);
}
void segment(float x, float y, float a) {
pushMatrix();
translate(x, y);
rotate(a);
line(0, 0, segLength, 0);
popMatrix();
}
hope that help you!