Beginner requires some help for a "snake" game

Hello there,
I have to do a special snake game for my coding classes.
There is no food in this version of the game, but each time “s” is pressed, the snake have to grow by 1 (and only 1) square.

The issue is that sometime when I press “s”, several squares appears (but I don’t know exactly when). How should I fix this?

Here’s my code;

ArrayList<PVector> snake = new ArrayList<PVector>();

PVector pos;
PVector dir = new PVector(1, 0);

int size = 32;
int w;
int h;

int spd = 20;
int len = 1;

void setup() {
  size(960, 960);
  frameRate (40);
  
  w = width/size;
  h = height/size;
  
  pos = new PVector(w/2, h/2);
}

void draw() {
  background(200);
  drawSnake();
  
  if(frameCount % spd == 0) {
    updateSnake();   
  }
}

void drawSnake() {
  fill(0);
  rect(pos.x * size, pos.y * size, size, size);
  stroke (0);
  fill (255);
  for(int i = 0; i < snake.size(); i ++) {
    rect(snake.get(i).x * size, snake.get(i).y * size, size, size);
  }
}

void updateSnake() {
    snake.add(new PVector(pos.x, pos.y));
    
  while(snake.size() > len) {
    snake.remove(0);
  }
  pos.add(dir);
  
  if  ((key == 's') || (key == 'S')) 
  { len += 1; } //Here's the problem.
  
 for (int i = 0; i < snake.size (); i ++) {
    if (pos.x == snake.get(i).x && pos.y == snake.get(i).y) {
      frameRate(0);
      println ("Game Over");
      noLoop (); 
    }
    if (pos.x < -1 || pos.x > 30 || pos.y > 30 || pos.y < -1) {
      frameRate(0);
      println ("Game Over");
      noLoop (); 
  }
}
}

void keyPressed() {
  if(key == CODED) {
    if(keyCode == UP) { dir = new PVector(0, -1); }
    if(keyCode == DOWN) { dir = new PVector(0, 1); }
    if(keyCode == LEFT) { dir = new PVector(-1, 0); }
    if(keyCode == RIGHT) { dir = new PVector(1, 0); }
 }
}

Thank you for your help !

1 Like

The thing is that the check if key == 's' happens inside of updateSnake() function, which happens inside of draw().
That draw() function is what run for every frame of your code, i.e. it’s ran 60 times a second. So, each one of these frames it runs draw(), so it runs updateSnake() in there, which runs the key == 's' check and if it’s true adds 1 to the length - 60 times in the same second.

I suggest putting the if ((key == ‘s’) || (key == ‘S’)) { len += 1; } part of the code inside of keyPressed() instead, since that is ran only once every time you press a key - which is what you want.

Also, I suggest you to use the code formatting thing in the comment thing. Above the text box, there’s a button that looks like </> - that, and, when you select something and press it, it formats it in this nice monospace font, making it easier to read.

void itEven(can DoColors){ println("!!!"); }

Sorry, I’m a bit bored right now. ._.

Also, a general game development suggestion - in draw(), move drawSnake(); below updateSnake(); - this way, changes made by updateSnake() get reflected in the same exact frame that they happened, making the game feel a bit more responsive by eliminating a 1 frame input lag.

3 Likes

Wow, thank you so much for your quick answer. It works perfectly!
I’m very grateful for your advices, I’ll carefully take them into account!