Following an assignment and just getting started with libGDX by building a small Snake clone I've run into an issue that I'll probably be ashamed for in a little while.

I currently have a snake's head (a simple rectangle at this stage) moving around the game's canvas. The most straight-forward way of building the rest of the snake was to have the head own a Java Collections LinkedList of SnakeElements which would in-/decrease in size according to what the player does.

Having this list of SnakeElements follow the head however has proven to not be trivial.

The current function doing this is as follows and is called every time the head updates its position:

private void moveTail (float x, float y, int direction) {
    float tmpx, tmpy;
    int tmpdirection;
    int offset_x, offset_y;

    for (SnakeSegment snse : tail) {
        offset_x = 0;
        offset_y = 0;

        tmpx = snse.getX();
        tmpy = snse.getY();
        tmpdirection = snse.getDirection();

        switch(direction) {
            case 0:
                offset_x = 0;
                offset_y = -(2 + snse.width);
            case 1:
                offset_x = -(2 + snse.width);
                offset_y = 0;
            case 2:
                offset_x = 0;
                offset_y = (2 + snse.width);
            case 3:
                offset_x = (2 + snse.width);
                offset_y = 0;
                System.out.println("wrong direction");

        snse.setX(x + offset_x);
        snse.setY(y + offset_y);

        x = tmpx;
        y = tmpy;
        direction = tmpdirection;

which unfortunately results in this behavior:


Any tips on how to make a correctly working snake tail would be much appreciated :)


2 Answers 2


Think of the problem like this:
How does a snake move in the original game?
The snake moves towards its current direction. The behavior looks like the head appears out of nothing, and the last tail part disappears.

You can have a list of snakeparts. What you want to do is remove the last item in the list which represents the last tail part.
Then you want to create a new headpart where it should be positioned and put it in the first position of the list.
This means the remainder of the snake is not moved since you only alter first and last position.
This creates a snakelike behavior.

  • \$\begingroup\$ Whoa, thanks! This makes a lot of sense and should've been the idea from the get go, looks like I'll have some fun refactoring :) I'm just sorry my sad amount of karma is preventing me from upvoting you. I promise I'll be back in the future! \$\endgroup\$
    – Kilian
    May 3, 2014 at 23:36
  • 1
    \$\begingroup\$ An alternative way to think about it is that each snake element follows only the element directly in front of it, rather than following the head. This will be useful if, later, the snakes are textured or anything like that. \$\endgroup\$ May 4, 2014 at 2:48
  • 3
    \$\begingroup\$ Here's the current version by the way, thanks again :) i.imgur.com/IaT5PNH.gif \$\endgroup\$
    – Kilian
    May 4, 2014 at 14:55

The way I see it is as a "Caterpillar" like system, where each part of the snake follow the part ahead of it.

In another words, each part of the snake would be an Object with Position (x, y), a reference to the part ahead of it that it would use to move around and a function to process the position of the part ahead of it and move accordingly. The main snake (the Head) should have references for every part of the snake, and would call the function responsible to make the part follow its predecessor, being the Head the predecessor of the first part.
Hope it helps!

  • \$\begingroup\$ This was the idea, but handling corners turned out to be quite complex. And what would happen if a player would turn a sharp 180 degree corner? We weren't sure how to handle this correctly, and using the method as described by Pontus Magnusson solves all these problems nicely. \$\endgroup\$
    – Kilian
    May 4, 2014 at 14:58
  • \$\begingroup\$ I see. The only time I implemented a caterpillar system I had a grid with cells at the size of the parts, so each part was always inside one specific cell, this way, the problem didn't occur. Sorry for my bad english. \$\endgroup\$ May 5, 2014 at 0:40
  • \$\begingroup\$ Ah yes, that makes sense and should also work, but we ditched the idea of having a grid for a reason I can't currently remember ;) Thanks though :) \$\endgroup\$
    – Kilian
    May 5, 2014 at 6:55

You must log in to answer this question.

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