[英]Javascript snake game not working
What's wrong with my code here? 我的代码在这里怎么了? My Snake is not working as in the book's code.
我的Snake的工作方式与本书的代码不同。 The code is taken for the excellent book "JavaScript for Kids" by Nick Morgan.
该代码是为尼克·摩根(Nick Morgan)的出色著作《儿童的JavaScript》所用。 I downloaded the code from the book and it seems identical to mine, am I missing something?
我从书中下载了代码,看起来和我的完全一样,我是否缺少某些内容?
See JSFiddle here: 在这里查看JSFiddle:
http://jsfiddle.net/raenset/ehjyt08k/
Code: 码:
var canvas = document.getElementById("canvas"); var ctx = canvas.getContext("2d"); var width = canvas.width; var height = canvas.height; var blockSize = 10; var widthInBlocks = width / blockSize; var heightInBlocks = height / blockSize; var score = 0; var drawBorder = function () { ctx.fillStyle = "Gray"; ctx.fillRect (0, 0, width, blockSize); ctx.fillRect (0, height - blockSize, width, blockSize); ctx.fillRect (0, 0, blockSize, height); ctx.fillRect (width - blockSize, 0, blockSize, height); }; var drawScore = function () { ctx.font = "20px Courier"; ctx.fillStyle = "Black"; ctx.textAlign = "left"; ctx.textBaseline = "top"; ctx.fillText("Score: " + score, blockSize, blockSize); }; var gameOver = function () { clearInterval(intervalId); ctx.font = "60px Courier"; ctx.fillStyle = "Black"; ctx.textAlign = "center"; ctx.textBaseline = "middle"; ctx.fillText("Game Over", width / 2, height / 2); }; var circle = function (x, y, radius, fillCircle){ ctx.beginPath(); ctx.arc(x, y, radius, 0, Math.PI * 2, false); if (fillCircle){ ctx.fill(); } else { ctx.stroke(); } }; var Block = function (col, row) { this.col = col; this.row = row; }; Block.prototype.drawSquare = function (color) { var x = this.col * blockSize; var y = this.col * blockSize; ctx.fillStyle = color; ctx.fillRect(x, y, blockSize, blockSize); }; Block.prototype.drawCircle = function (color) { var centerX = this.col * blockSize + blockSize / 2; var centerY = this.row * blockSize + blockSize / 2; ctx.fillStyle = color; circle(centerX, centerY, blockSize / 2, true); }; Block.prototype.equal = function (otherBlock) { return this.col === otherBlock.col && this.row === otherBlock.row; }; var Snake = function() { this.segments = [ new Block (7, 5), new Block (6, 5), new Block (5, 5) ]; this.direction = "right"; this.nextDirection = "right"; }; Snake.prototype.draw = function () { for (var i = 0; i < this.segments.length; i++) { this.segments[i].drawSquare("Blue"); } }; Snake.prototype.move = function () { var head = this.segments[0]; var newHead; this.direction = this.nextDirection; if (this.direction === "right"){ newHead = new Block(head.col + 1, head.row); } else if (this.direction === "down"){ newHead = new Block(head.col, head.row + 1); } else if (this.direction === "left"){ newHead = new Block(head.col - 1, head.row); } else if (this.direction === "up"){ newHead = new Block(head.col, head.row -1); } if (this.checkCollision(newHead)) { gameOver(); return; } this.segments.unshift(newHead); if (newHead.equal(apple.position)){ score++; apple.move(); } else { this.segments.pop(); } }; Snake.prototype.checkCollision = function (head) { var leftCollision = (head.col === 0); var topCollision = (head.row === 0); var rightCollision = (head.col === widthInBlocks - 1); var bottomCollision = (head.row === heightInBlocks -1); var wallCollision = leftCollision || topCollision || rightCollision || bottomCollision; var selfCollision = false; for (var i = 0; i < this.segments.length; i++){ if (head.equal(this.segments[i])) { selfCollision = true; } } return wallCollision || selfCollision; }; Snake.prototype.setDirection = function (newDirection) { if (this.direction === "up" && newDirection === "down"){ return; } else if (this.direction === "right" && newDirection === "left"){ return; } else if (this.direction === "down" && newDirection === "up") { return; } else if (this.direction === "left" && newDirection === "right"){ return; } this.nextDirection = newDirection; }; var Apple = function () { this.position = new Block (10, 10); }; Apple.prototype.draw = function () { this.position.drawCircle("LimeGreen"); }; Apple.prototype.move = function () { var randomCol = Math.floor(Math.random() * (widthInBlocks -2)) + 1; var randomRow = Math.floor(Math.random() * (heightInBlocks - 2)) +1; this.position = new Block(randomCol, randomRow); }; var snake = new Snake(); var apple = new Apple(); var intervalId = setInterval(function () { ctx.clearRect(0, 0, width, height); drawScore(); snake.move(); snake.draw(); apple.draw(); drawBorder(); }, 100); var directions = { 37: "left", 38: "up", 39: "right", 40: "down" }; $("body").keydown(function(event) { var newDirection = directions [event.keyCode]; if (newDirection !== undefined) { snake.setDirection(newDirection); } });
<!DOCTYPE html> <html><head><title>Snake!</title> </head><body> <canvas id ="canvas" width ="400" height ="400"> </canvas> </body></html>
Here is the working code from the book. 这是本书中的工作代码。 The problem is: where is it different from mine?
问题是:它和我的有什么不同?
<!DOCTYPE html>
<html>
<head>
<title>Snake!</title>
</head>
<body>
<canvas id="canvas" width="400" height="400"></canvas>
<script src="https://code.jquery.com/jquery-2.1.0.js"></script>
<script>
// Set up canvas
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
// Get the width and height from the canvas element
var width = canvas.width;
var height = canvas.height;
// Work out the width and height in blocks
var blockSize = 10;
var widthInBlocks = width / blockSize;
var heightInBlocks = height / blockSize;
// Set score to 0
var score = 0;
// Draw the border
var drawBorder = function () {
ctx.fillStyle = "Gray";
ctx.fillRect(0, 0, width, blockSize);
ctx.fillRect(0, height - blockSize, width, blockSize);
ctx.fillRect(0, 0, blockSize, height);
ctx.fillRect(width - blockSize, 0, blockSize, height);
};
// Draw the score in the top-left corner
var drawScore = function () {
ctx.font = "20px Courier";
ctx.fillStyle = "Black";
ctx.textAlign = "left";
ctx.textBaseline = "top";
ctx.fillText("Score: " + score, blockSize, blockSize);
};
// Clear the interval and display Game Over text
var gameOver = function () {
clearInterval(intervalId);
ctx.font = "60px Courier";
ctx.fillStyle = "Black";
ctx.textAlign = "center";
ctx.textBaseline = "middle";
ctx.fillText("Game Over", width / 2, height / 2);
};
// Draw a circle (using the function from Chapter 14)
var circle = function (x, y, radius, fillCircle) {
ctx.beginPath();
ctx.arc(x, y, radius, 0, Math.PI * 2, false);
if (fillCircle) {
ctx.fill();
} else {
ctx.stroke();
}
};
// The Block constructor
var Block = function (col, row) {
this.col = col;
this.row = row;
};
// Draw a square at the block's location
Block.prototype.drawSquare = function (color) {
var x = this.col * blockSize;
var y = this.row * blockSize;
ctx.fillStyle = color;
ctx.fillRect(x, y, blockSize, blockSize);
};
// Draw a circle at the block's location
Block.prototype.drawCircle = function (color) {
var centerX = this.col * blockSize + blockSize / 2;
var centerY = this.row * blockSize + blockSize / 2;
ctx.fillStyle = color;
circle(centerX, centerY, blockSize / 2, true);
};
// Check if this block is in the same location as another block
Block.prototype.equal = function (otherBlock) {
return this.col === otherBlock.col && this.row === otherBlock.row;
};
// The Snake constructor
var Snake = function () {
this.segments = [
new Block(7, 5),
new Block(6, 5),
new Block(5, 5)
];
this.direction = "right";
this.nextDirection = "right";
};
// Draw a square for each segment of the snake's body
Snake.prototype.draw = function () {
for (var i = 0; i < this.segments.length; i++) {
this.segments[i].drawSquare("Blue");
}
};
// Create a new head and add it to the beginning of
// the snake to move the snake in its current direction
Snake.prototype.move = function () {
var head = this.segments[0];
var newHead;
this.direction = this.nextDirection;
if (this.direction === "right") {
newHead = new Block(head.col + 1, head.row);
} else if (this.direction === "down") {
newHead = new Block(head.col, head.row + 1);
} else if (this.direction === "left") {
newHead = new Block(head.col - 1, head.row);
} else if (this.direction === "up") {
newHead = new Block(head.col, head.row - 1);
}
if (this.checkCollision(newHead)) {
gameOver();
return;
}
this.segments.unshift(newHead);
if (newHead.equal(apple.position)) {
score++;
apple.move();
} else {
this.segments.pop();
}
};
// Check if the snake's new head has collided with the wall or itself
Snake.prototype.checkCollision = function (head) {
var leftCollision = (head.col === 0);
var topCollision = (head.row === 0);
var rightCollision = (head.col === widthInBlocks - 1);
var bottomCollision = (head.row === heightInBlocks - 1);
var wallCollision = leftCollision || topCollision || rightCollision || bottomCollision;
var selfCollision = false;
for (var i = 0; i < this.segments.length; i++) {
if (head.equal(this.segments[i])) {
selfCollision = true;
}
}
return wallCollision || selfCollision;
};
// Set the snake's next direction based on the keyboard
Snake.prototype.setDirection = function (newDirection) {
if (this.direction === "up" && newDirection === "down") {
return;
} else if (this.direction === "right" && newDirection === "left") {
return;
} else if (this.direction === "down" && newDirection === "up") {
return;
} else if (this.direction === "left" && newDirection === "right") {
return;
}
this.nextDirection = newDirection;
};
// The Apple constructor
var Apple = function () {
this.position = new Block(10, 10);
};
// Draw a circle at the apple's location
Apple.prototype.draw = function () {
this.position.drawCircle("LimeGreen");
};
// Move the apple to a new random location
Apple.prototype.move = function () {
var randomCol = Math.floor(Math.random() * (widthInBlocks - 2)) + 1;
var randomRow = Math.floor(Math.random() * (heightInBlocks - 2)) + 1;
this.position = new Block(randomCol, randomRow);
};
// Create the snake and apple objects
var snake = new Snake();
var apple = new Apple();
// Pass an animation function to setInterval
var intervalId = setInterval(function () {
ctx.clearRect(0, 0, width, height);
drawScore();
snake.move();
snake.draw();
apple.draw();
drawBorder();
}, 100);
// Convert keycodes to directions
var directions = {
37: "left",
38: "up",
39: "right",
40: "down"
};
// The keydown handler for handling direction key presses
$("body").keydown(function (event) {
var newDirection = directions[event.keyCode];
if (newDirection !== undefined) {
snake.setDirection(newDirection);
}
});
</script>
</body>
</html>
Remove the tag from the top line of the jsfiddle script area and your code will work. 从jsfiddle脚本区域的顶行删除该标记,您的代码将起作用。 Jsfiddle doesn't like script tags inside the script area.
Jsfiddle不喜欢脚本区域内的脚本标签。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.