Javascript蛇游戏无法正常工作

时间:2015-03-22 15:34:53

标签: javascript html5 canvas

我的代码出了什么问题?我的蛇不像书中的代码那样工作。该代码是由Nick Morgan出版的优秀书籍“JavaScript for Kids”。我从书中下载了代码,看起来和我的相同,我错过了什么?

请参阅JSFiddle:

http://jsfiddle.net/raenset/ehjyt08k/

代码:

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>

这是本书的工作代码。问题是:它与我的不同之处在哪里?

<!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>

1 个答案:

答案 0 :(得分:0)

从jsfiddle脚本区域的顶行删除标记,您的代码将起作用。 Jsfiddle不喜欢脚本区域内的脚本标签。