I try to find the right formula to mimic the smooth non-grid movement of the slither.io snake.

I can do it manually to save each point the "head" movement went and do some interpolation in between its body parts but it is very error prone.

Also I find this: http://www.emanueleferonato.com/2014/06/10/html5-string-avoider-game-made-with-phaser/

Which is not working in my case but do show something similar

Here is a picture to express what I want to do:
enter image description here

Any idea how to do it right?

  • \$\begingroup\$ That's still grid based, just with a grid size of 1 pixel x 1 pixel... \$\endgroup\$ – Caleth Sep 15 '17 at 10:35

Well... I actually don't know what you're calling "grid based" movement but to reproduce the slither.io's movement you might need to:

Save the current snake moving angle

make a vector that is equal to (cursor position - snake position) and calculate its angle

Calcuate the difference beetween the two angles and increment the snake's moving angle by a little portion of it every tick.

Done ;)

[EDIT]Here's an exemple:

your snake spawns looking to the top, at position x=100, y=100, his moving angle is currently pi/2

the player mouse cursor is at x=150, y=250

the angle formed is : angleFormed = atan2((150 - 100)/ (250 - 100)) in radians

you move the snake angle depending on the difference with the other angle :

snakeAngle += (angleFormed - snakeAngle) / timeStep

  • \$\begingroup\$ and how do i handle all other body parts ? \$\endgroup\$ – user3689 Oct 3 '16 at 13:38
  • 1
    \$\begingroup\$ Actually, you can save a point in a list each time the snake's moving angle changes and move the bodyparts from a point to another \$\endgroup\$ – Treycos Oct 3 '16 at 14:37

This might be useful for you!

ok, so let positions[] be a vector array with the current positions of the snake.

to move the snake (or the snake's head) to a new position, this is what i did for my game

moveTo (x, y) {
  // positions[0] is the head of the snake
  this.positions[0].x = x;
  this.positions[0].y = y;


join () {
  // loop through each position
  for (let i = 1; i < this.positions.length; i++) {
    // get last and current position
    const last = this.positions[i - 1];
    const curr = this.positions[i];

    // get difference in x and y of each position
    const dx = curr.x - last.x;
    const dy = curr.y - last.y;

    // calculate the angle between the two parts of the snake
    let angle = Math.atan2(dy, dx);

    // get the new x and new y using polar coordinates
    const nx = 2 * this.radius * Math.cos(angle);
    const ny = 2 * this.radius * Math.sin(angle);

    // add the new x and new y to the last snake's position to "join" the two together without a gap
    curr.x = nx + last.x;
    curr.y = ny + last.y;

Basically, this the moveTo() function just moves the head to the new position, and the join() function joins all of the parts together smoothly with a wiggly animation

a jsfiddle is here: https://jsfiddle.net/rzx9hmro/1/


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.