1
\$\begingroup\$

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?

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

2 Answers 2

1
\$\begingroup\$

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

\$\endgroup\$
2
  • \$\begingroup\$ and how do i handle all other body parts ? \$\endgroup\$
    – user3689
    Commented Oct 3, 2016 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
    Commented Oct 3, 2016 at 14:37
1
\$\begingroup\$

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;

  this.join();
}

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/

\$\endgroup\$

You must log in to answer this question.

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