when the snake moves, it looks like it ‘jumps’ rather than moving smoothly. How can I fix this?
Below are some functions I’ve implemented for my Phaser snake game: update, move, setBodyPartTexture, and grow
update(time) {
if (time >= this.moveTime && this.gameStarted) {
this.keyLock = false;
if (this.moveEvents.length > 0) {
this.direction = this.moveEvents.shift();
}
this.move();
this.moveTime = time + this.speed;
return true;
}
return false;
}
move() {
let oldHeadPosition = { x: this.snakeHead.x, y: this.snakeHead.y };
this.directions.unshift(this.direction.clone());
this.snakeHead.x += this.direction.x * this.bodyPartLength;
this.snakeHead.y += this.direction.y * this.bodyPartLength;
if (this.snakeHead.x > this.scene.game.config.width || this.snakeHead.x < 0 || this.snakeHead.y > this.scene.game.config.height || this.snakeHead.y < 0) {
return;
}
for (let i = 1; i < this.body.length; i++) {
let oldBodyPosition = { x: this.body[i].x, y: this.body[i].y };
let oldBodyDirection = this.directions[i];
this.body[i].x = oldHeadPosition.x;
this.body[i].y = oldHeadPosition.y;
oldHeadPosition = oldBodyPosition;
this.setBodyPartTexture(i, oldBodyDirection);
}
this.setTailTexture();
if (this.positions.length > this.body.length * this.bodyPartLength) {
this.positions.pop();
this.directions.pop();
}
this.moveTime = this.scene.time.now + this.speed;
}
setBodyPartTexture(i, oldBodyDirection) {
if (!oldBodyDirection.equals(this.directions[i - 1])) {
let prevDirection = `${this.directions[i - 1].x},${this.directions[i - 1].y}`;
let currDirection = `${oldBodyDirection.x},${oldBodyDirection.y}`;
let textureMap = {
"1,0,0,-1": "bodyUpRight",
"0,1,-1,0": "bodyUpRight",
"-1,0,0,1": "bodyRightUp",
"0,-1,1,0": "bodyRightUp",
"0,1,1,0": "bodyRightDown",
"-1,0,0,-1": "bodyRightDown",
"0,-1,-1,0": "bodyDownRight",
"1,0,0,1": "bodyDownRight",
};
let directionKey = `${prevDirection},${currDirection}`;
this.body[i].setTexture(textureMap[directionKey]);
} else {
if (oldBodyDirection.y != 0) {
this.body[i].setTexture("bodyVertical");
} else {
this.body[i].setTexture("bodyHorizontal");
}
}
}
grow() {
let newPart = this.scene.physics.add.sprite(-1 * this.bodyPartLength, -1 * this.bodyPartLength, "tailRight");
this.scene.physics.add.collider(this.snakeHead, newPart, this.endGame, null, this.scene.snake);
this.bodyParts.push(newPart);
this.body.push(newPart);
this.eat.play();
score++;
scoreNumber.innerHTML = score;
if (score > highScore) {
highScore = score;
document.querySelector("#high-score p").innerHTML = highScore;
document.getElementById("highScoreNumber").innerHTML = highScore;
}
}
These are the functions I’m using. However, I’m experiencing an issue: when the snake moves, it appears to ‘jump’ instead of moving smoothly. Can anyone help me solve this issue?
As you can see in this video, I’m experiencing that issue.
https://www.awesomescreenshot.com/video/33408786?key=90beb12f2ca0ed729a0133a2b7ad36a6
I’ve tried to make the snake’s movement smoother, so it moves fluidly instead of ‘jumping.
I’ve tried using deltaTime, velocity, and the Tween method, but I haven’t found a solution.
2
Answers
I believe this is the problem:
This means the the least amount the snake can move any given game tick is
this.bodyPartLength
. This means that the movement is jerky and easy to see as the user. It should be possible to render the snake body parts anywhere on the screen, and therefore, you don’t need to move a whole body part.To get rid of the jerkiness, the idea is to increase the game tick speed and decrease the amount moved per tick.
Well the issue is that you are moving by setting the next position in bigger increments, I see two ways to solve this issue:
this.speed
variable.Choppy movement can of course be caused by to demanding source code or a slow/old Device. For the later there is no real solution, but this game should be fine on most hardware.
Short Demo:
(ShowCasing some options)
But the easy solution is to simply use the physics velocity (this should take care of all the needed smoothness).
Mini Demo: