我正在编写简单的“蛇”游戏,我正面临着这个问题: 每次驯服我的蛇都会击中红色圆圈(苹果),苹果应该被移到画布上的新位置。现在新的苹果出现,但旧的苹果不会消失(它应该),而且当画布上有超过2个苹果时,它们会创建一个填充的数字......它看起来像这样:ibb.co/nrYdLQ(也是不应该发生。)
负责移动苹果的代码是:
if (!this.objectCollide(myApple)) {
this.segments.pop();
} else {
myApple = new block(Math.floor(Math.random() * gameField.width),Math.floor(Math.random() * gameField.height))
};
我不知道为什么它像我上面描述的那样工作,而只是将苹果移动到一个新位置并移除旧位置。 请帮忙。
JSFiddle:https://jsfiddle.net/e1ga0fpm/
完整的JavaScript代码:
var gameField = document.getElementById('gameField');
var ctx = gameField.getContext("2d");
var blockSize = 10;
columnCt = gameField.width / blockSize;
rowsCt = gameField.height / blockSize;
var block = function(x, y) {
this.x = x;
this.y = y;
}
block.prototype.drawBlock = function() {
ctx.fillStyle = "blue";
ctx.fillRect(this.x * blockSize, this.y * blockSize, blockSize,
blockSize);
};
block.prototype.drawApple = function() {
ctx.fillStyle = "red";
ctx.textBaseline = "bottom";
ctx.arc(this.x, this.y, 6, 2 * Math.PI, false);
ctx.fill();
}
var Snake = function() {
this.segments = [new block(20, 20), new block(19, 20), new block(18, 20), new block(17, 20),
new block(16, 20), new block(15, 20), new block(14, 20), new block(13, 20), new block(12, 20),
new block(11, 20), new block(10, 20)
];
this.direction = "right";
}
Snake.prototype.drawSnake = function() {
for (i = 0; i < this.segments.length; i++) {
this.segments[i].drawBlock();
}
}
Snake.prototype.setDirection = function(dir) {
if (this.direction == "left" && dir == "right" || this.direction == "right" && dir == "left" || this.direction == "up" && dir == "down" ||
this.direction == "down" && dir == "up") {
return
} else {
this.direction = dir;
};
};
Snake.prototype.objectCollide = function(obj) {
if (this.segments[0].x == Math.round(obj.x / blockSize) && this.segments[0].y == Math.round(obj.y / blockSize)) {
return true
} else {
return false
}
};
Snake.prototype.move = function() {
var head = this.segments[0];
var newHead;
switch (this.direction) {
case "right":
newHead = new block(head.x + 1, head.y);
break;
case "left":
newHead = new block(head.x - 1, head.y)
break;
case "down":
newHead = new block(head.x, head.y + 1)
break;
case "up":
newHead = new block(head.x, head.y - 1)
break;
}
this.segments.unshift(newHead);
if (!this.objectCollide(myApple)) {
this.segments.pop();
} else {
myApple = new block(Math.floor(Math.random() * gameField.width),Math.floor(Math.random() * gameField.height))
};
var collision = newHead.x >= columnCt || newHead.x <= -1 ||
newHead.y >= rowsCt || newHead.y <= -1;
for (i = 1; i < this.segments.length; i++) {
if (this.segments[i].x == newHead.x && this.segments[i].y == newHead.y) {
collision = true;
break;
};
};
if (collision) {
clearInterval(myFun);
};
};
var mySnake = new Snake()
mySnake.drawSnake();
var myApple = new block(Math.floor(Math.random() * gameField.width),
Math.floor(Math.random() * gameField.height));
var myFun = setInterval(function() {
ctx.clearRect(0, 0, gameField.width, gameField.height);
mySnake.move();
mySnake.drawSnake();
myApple.drawApple();
}, 100)
var directions = {
37: "left",
38: "up",
39: "right",
40: "down"
};
document.onkeydown = function(event) {
var newDirection = directions[event.keyCode]
if (newDirection != undefined) {
mySnake.setDirection(newDirection);
};
答案 0 :(得分:2)
我非常不确定为什么苹果没有被“吃掉”但是,我可能知道为什么它看起来很奇怪:
如果你画到画布,它看起来像一支钢笔。因此,无论何时绘制新苹果,笔都会移动到该位置并绘制一条线。在几个苹果之后,如果你调用.fill(),这个(但是看不见的)线就会被填满。因此,您需要在绘制之前移动笔:
select option
答案 1 :(得分:1)
你画苹果时忘了beginpath
。当苹果吃掉时,你必须为蛇添加新的块。检查下面的编辑代码。
此处已更新fiddle
block.prototype.drawApple = function() {
ctx.fillStyle = "red";
ctx.textBaseline = "bottom";
ctx.beginPath();
ctx.arc(this.x, this.y, 6, 2 * Math.PI, false);
ctx.fill();
}
var gameField = document.getElementById('gameField');
var ctx = gameField.getContext("2d");
var blockSize = 10;
columnCt = gameField.width / blockSize;
rowsCt = gameField.height / blockSize;
var block = function(x, y) {
this.x = x;
this.y = y;
}
block.prototype.drawBlock = function() {
ctx.fillStyle = "blue";
ctx.fillRect(this.x * blockSize, this.y * blockSize, blockSize,
blockSize);
};
block.prototype.drawApple = function() {
ctx.fillStyle = "red";
ctx.textBaseline = "bottom";
ctx.beginPath();
ctx.arc(this.x, this.y, 6, 2 * Math.PI, false);
ctx.fill();
}
var Snake = function() {
this.segments = [new block(20, 20), new block(19, 20), new block(18, 20), new block(17, 20),
new block(16, 20), new block(15, 20)
];
this.direction = "right";
}
Snake.prototype.drawSnake = function() {
for (i = 0; i < this.segments.length; i++) {
this.segments[i].drawBlock();
}
}
Snake.prototype.setDirection = function(dir) {
if (this.direction == "left" && dir == "right" || this.direction == "right" && dir == "left" || this.direction == "up" && dir == "down" ||
this.direction == "down" && dir == "up") {
return
} else {
this.direction = dir;
};
};
Snake.prototype.objectCollide = function(obj) {
if (this.segments[0].x == Math.round(obj.x / blockSize) && this.segments[0].y == Math.round(obj.y / blockSize)) {
return true
} else {
return false
}
};
Snake.prototype.move = function() {
var head = this.segments[0];
var newHead;
switch (this.direction) {
case "right":
newHead = new block(head.x + 1, head.y);
break;
case "left":
newHead = new block(head.x - 1, head.y)
break;
case "down":
newHead = new block(head.x, head.y + 1)
break;
case "up":
newHead = new block(head.x, head.y - 1)
break;
}
this.segments.unshift(newHead);
if (!this.objectCollide(myApple)) {
this.segments.pop();
} else {
myApple = new block(Math.floor(Math.random() * gameField.width), Math.floor(Math.random() * gameField.height));
this.segments.push(new block(this.segments[0][0], 20))
};
var collision = newHead.x >= columnCt || newHead.x <= -1 ||
newHead.y >= rowsCt || newHead.y <= -1;
for (i = 1; i < this.segments.length; i++) {
if (this.segments[i].x == newHead.x && this.segments[i].y == newHead.y) {
collision = true;
break;
};
};
if (collision) {
clearInterval(myFun);
};
};
var mySnake = new Snake()
mySnake.drawSnake();
var myApple = new block(Math.floor(Math.random() * gameField.width),
Math.floor(Math.random() * gameField.height));
var myFun = setInterval(function() {
ctx.clearRect(0, 0, gameField.width, gameField.height);
mySnake.move();
mySnake.drawSnake();
myApple.drawApple();
}, 100)
var directions = {
37: "left",
38: "up",
39: "right",
40: "down"
};
document.onkeydown = function(event) {
var newDirection = directions[event.keyCode]
if (newDirection != undefined) {
mySnake.setDirection(newDirection);
};
};
&#13;
canvas {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
margin: auto;
border: 5px solid grey;
}
&#13;
<canvas id="gameField" height="500" width="500">
</canvas>
&#13;