Gabriel West Gabriel West - 20 days ago 5
CSS Question

Apples not properly spawning in Snake game

I have a Snake game that bugs out whenever i collect an apple. The apple will disappear upon collision and a new apple spawns in a new location but for some reason the first apple then respawns in its original location. Then when i collect the newly spawned second apple the first two apples disappear and a third apple spawns in a new location, but the first and second apples then respawn in their original locations and this process continues...

Only the newest spawned apple is capable of detecting collisions with the snake and spawning new apples.

I have an

Apple
class that keeps track of its x and y coordinates and a
SnakeGame
class that is composed with an apple and snake. When an apple is collected I set the
SnakeGame.apple
property to null then i create a new
Apple
object with new x,y coordinates and set it as the new
SnakeGame.apple
object.

Any ideas to solve this problem would be appreciated!

Heres a fiddle if you wanna play with my code: https://jsfiddle.net/gabewest1/knuxsa5t/1/

Apple Class:

class Apple {
constructor(x, y) {
this.xPos = x;
this.yPos = y;
this.radius = 10;
}

draw(ctx) {
ctx.fillStyle = "black";
ctx.arc(this.xPos, this.yPos, this.radius, 0, 2 * Math.PI);
ctx.fill();
}

position(x, y) {
if (x > -100 && y > -100) {
this.xPos = x;
this.yPos = y;
} else {
return {
x: this.xPos,
y: this.yPos
};
}
}
}


SnakeGame Class:

class SnakeGame {
constructor(snake) {
this.ctx = $("#myCanvas")[0].getContext("2d");
this.canvas = $("#myCanvas")[0];
this.init();

this.frameLength = 500;
this.apple = this.createApple();
this.snake = snake;

this.score = 0;
this.gameloop();
}

createApple() {
var xPos = Math.floor(Math.random() * this.canvas.width);
var yPos = Math.floor(Math.random() * this.canvas.height);
var apple = new Apple(xPos, yPos);
return apple;
}

gameloop() {
var ctx = this.ctx;

this.snake.move();

if (this.collision()) {
console.log("There was a collision!");
this.score++;
this.increaseSnake();
this.apple = null;
}

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

this.snake.draw(ctx);

if (this.apple) {
this.apple.draw(ctx);
} else {
this.apple = this.createApple();
}

setTimeout($.proxy(this.gameloop, this), this.frameLength);
}
}

Answer

Simply add ctx.beginPath(); before creating the arc.

ctx.fillStyle = "black";
ctx.beginPath();
ctx.arc(this.xPos, this.yPos, this.radius, 0, 2 * Math.PI);
ctx.fill();

The ctx keeps track of every arc that is created, and applies fill to all those shapes.