Creating Snake Code

Hi, I’m new when it comes to processing so I’ve been having quite a hard time with coming up with codes and making them work properly. I’m trying to create a snake(similar to the snake game except there’s no food, scoring, and etc), but my code isn’t working. I’ve tried everything. I need to make the snake move to the right when the mouse is pressed so far all I can do is make the snake follow the mouse as it glides over the screen. I’m just having a really hard time with this code. Please help me.
Here is what I have so far:

int x= 0;
int rad = 40;        // Width of the snake
int xdirection = 1;  // Moving to the East
int ydirection = -1;  // Moving to the South
int turnTimer = 0;
float xPos, yPos;    // Starting position of snake    
float xspeed = 6.0;  // Speed of the snake
float yspeed = 6.0;  // Speed of the snake

void setup() {
size(500,500);

xPos = xPos + ( xspeed * xdirection );
yPos = yPos + ( yspeed * ydirection );

}

void draw() {
background(203,60,60);
if (keyPressed == true) {
int xdirection = 1;  // Moving to the East
 } else { // Otherwise,
int ydirection = -1;  // Moving to the West
 }

//snake
fill( random(255), random(255), random(255), random(255));
noStroke();
rect(mouseX,mouseY, 40, 40);
}
1 Like

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!

1 Like

This is very helpful, thank you so much!!

1 Like

I feel so rude doing this, but this part of the code seems to be malfunctioning this was how I did it several times before too. How would I fix this problem?

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;
    }
  }
}
1 Like

Can you say what problem? What are you expecting to happen? What happens instead? How do you know this is the code where it goes wrong (we can’t test it on its own without a full sketch)

When I add this to your keypressed above:

void draw(){}
void setDirection(char c){
  println(c);
}

…it seems to work just fine for me.

Note that to register keypresses, your focus must be inside the sketch window.

1 Like

ow, tell me if iam wrong