简体   繁体   English

Javascript蛇游戏无法正常工作

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM