Gabriel West Gabriel West - 21 days ago 5
CSS Question

Determining wrong behaivor of snakes movement in snake game

I've got a snake game with classes: BodyPart, Snake, and SnakeGame. The BodyPart class act as a node that composes the Snake class which is essentially a linked list of BodyParts that's methods use recursion to draw and retrieve/set the location of each BodyPart thats created when an apple is eaten.

I'm testing the addition of body parts to the Snake from eating apples by simulating this event with a mouse click. My problem resides in the oddity of behavior caused when the window loads because by default the

<canvas>
element doesn't have focus so i must click it in order for keyboard events on the
<canvas>
to be heard. That inital click to give the
<canvas>
focus causes a body part to be created and added to the snake. My problem is that when the snake begins to move, the newly created body part doesn't follow the head. Only after a couple seconds does the functionality of the newly created body part start to work and follow the head. Additional clicks to create body parts don't create any errors, only the first click.

I've been trying to pinpoint the reason of this but can't. I'm sure this problem will be fixed when i'm not creating new body parts with mouse clicks but in this particular context I would really like to know the cause of this behavior!

Main Code At Work:

gameloop() {
var ctx = this.ctx;

this.snake.move();

ctx.clearRect(0,0, this.canvas.width, this.canvas.height);

this.snake.draw(ctx);

setTimeout($.proxy(this.gameloop, this), this.frameLength);
}
move() {
var head = this.head;

//recursively pass back new position for each BodyPart node to be drawn
head.passBackPosition();

//get new position for the root node
switch(this.direction) {
case "up":
head.yPosition -= this.velocity;
break;

case "down":
head.yPosition += this.velocity;
break;

case "left":
head.xPosition -= this.velocity;
break;

case "right":
head.xPosition += this.velocity;
break;
}
}
position(x, y) {
if(x && y) {
this.xPosition = x;
this.yPosition = y;
}else {
return {x:this.xPosition,y:this.yPosition};
}
}


Heres a jsfiddle of the game: https://jsfiddle.net/gabewest1/hq8wqwt4/7/

Answer

I played with your fiddle and the body not following the head happens near the borders where x==0 or y==0.

Reading your code, I found:

position(x, y) {
    if(x && y) {
        this.xPosition = x;
        this.yPosition = y; 
    }else {
        return {x:this.xPosition,y:this.yPosition};
    }
}

This means that whenever you are on any of those borders, the following lines are not executed:

    this.xPosition = x;
    this.yPosition = y; 

Solution:

position(x, y) {
   this.xPosition = x;
   this.yPosition = y; 
   return {x:this.xPosition,y:this.yPosition};
}

See the fiddle: https://jsfiddle.net/vzsf2nee/1/