尝试JavaScript蛇游戏-蛇尾越来越多;不在一起

时间:2019-01-31 18:23:42

标签: javascript arrays loops

我试图弄清楚为什么我吃蛇的时候一次只将我的蛇的尾巴阵列画一个方块。我希望它被拉在一起并跟随蛇的头(做一条完整的蛇)。当我的蛇头掠过食物时,只有一个矩形画在食物所在的位置;无论我走到哪里,头部都会不断被吸引。

就好像蛇的尾巴阵列被绘制在地图的各处,而实际上并没有被绘制为“已连接”。

下面是我的代码。

谢谢您的帮助!

完整代码:

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <meta http-equiv="X-UA-Compatible" content="ie=edge">
      <title>Document</title>
      <style>
        .new-div {
          display:flex;
          justify-content: center;
          align-items: center;
          width:400px;
          height:400px;
          position:absolute;
          top:0;
          z-index:4000;
        }

        .game-content {
          position:relative;
          top:35px;
          right:0px;
          border:none;
          border-radius:5px;
          padding:10px;
          background-color:teal;
          color:white;
        }
      </style>
    </head>
    <body>
      <canvas id="canvas" width="400" height="400" style="border:1px solid black"></canvas>
      <script type="text/javascript">

      window.onload = function() {
        fruit.generateNewFruit();
        window.requestAnimationFrame(main);
      }

      var tools = {
        canvas: document.getElementById('canvas'),
        ctx: canvas.getContext('2d'),
        drawRect: function(x, y, sizeX, sizeY, color, type, stroke, strokeColor) {
          if (type == 'fill') {
            this.ctx.fillStyle = color;
            this.ctx.fillRect(x, y, sizeX, sizeY);
            if (stroke == true) {
              this.ctx.strokeStyle = strokeColor;
              this.ctx.strokeRect(x, y, sizeX, sizeY);
            }
          } else {
            this.ctx.fillStyle = color;
            this.ctx.strokeRect(x, y, sizeX, sizeY);
          }
        },
        writeText: function(text, x, y, font, fontStyle, color) {
          if (font) {
            this.ctx.font = fontStyle;
          }
          this.ctx.fillStyle = color;
          this.ctx.fillText(text, x, y);
        }
      }

      let game = {
        x: tools.canvas.width / 2 - 40,
        y: tools.canvas.height / 2,
        gameOver: false,
        gameOverMsg: function(msg, font) {
          let newDiv = document.createElement('div');
          let button = document.createElement('button');
          let btnText = document.createTextNode('Play Again');

          button.className = "game-content";
          newDiv.className = "new-div";

          tools.writeText(msg, this.x, this.y, true, "16px bold sans-serif", "#fff");

          button.appendChild(btnText);
          newDiv.appendChild(button);
          document.body.appendChild(newDiv);

          document.getElementsByClassName('game-content')[0].addEventListener('click', function() {
            game.gameOver = true;
          });
        }
      }

      let map = {
        tileX: 0,
        tileY: 0,
        tileRow: 20,
        tileCol: 20,
        tileSize: 20,
        tileColor: 'gray',
        drawMap: function() {
          for (let col = 0; col < this.tileCol; col++) {
            for (let row = 0; row < this.tileRow; row++) {
              tools.drawRect(this.tileX, this.tileY, this.tileSize, this.tileSize, this.tileColor, 'fill');
              this.tileX += this.tileSize;
            }
            this.tileX = 0;
            this.tileY += this.tileSize;
          }
          this.tileY = 0;
        },
        outOfBounds: function() {
          if (snake.x < 0 || snake.x > tools.canvas.width || snake.y < 0 || snake.y > tools.canvas.height) {
            game.gameOver = true;
          }
        }
      }

      let fruit = {
        x: 0,
        y: 0,
        size: 20,
        fillColor: 'hotpink',
        strokeColor: 'black',
        drawFruit: function() {
          tools.drawRect(this.x, this.y, this.size, this.size, this.fillColor, 'fill', true, this.strokeColor);
        },
        generateNewFruit: function() {
          this.x = Math.floor(Math.random() * 20) * 20;
          this.y = Math.floor(Math.random() * 20) * 20;
        }
      }

      let snake = {
        x: 0,
        y: 0,
        size: 20,
        color: 'black',
        direction: '',
        bodySize: 0,
        init: false,
        tail: [],
        drawSnake: function() {

          for (let i=0; i < this.bodySize; i++) {
            tools.drawRect(this.tail[i].x, this.tail[i].y, this.size, this.size, this.color, 'fill', true, 'lime');
          }

          tools.drawRect(this.x, this.y, this.size, this.size, this.color, 'fill', true, 'lime');
        },
        move: function() {
          if (this.direction == 'left') {
            this.x-=this.size;
          }
          else if (this.direction == 'up') {
            this.y-=this.size;
          }
          else if (this.direction == 'right') {
            this.x+=this.size;
          }
          else if (this.direction == 'down') {
            this.y+=this.size;
          }
        }
      }

      let drawEverything = function() {
          if (game.gameOver) {
            window.cancelAnimationFrame(main);
          }



          if (snake.x === fruit.x && snake.y === fruit.y) {
            fruit.generateNewFruit();
            snake.bodySize++;


          if (snake.bodySize === snake.tail.length) {
            for (let i=0; i < snake.tail.length - 1; i++) {
              snake.tail[i] = snake.tail[i+1];
            }
          }

          snake.tail[snake.bodySize-1] = {x: snake.x, y: snake.y};

          }

          tools.ctx.clearRect(0, 0, tools.canvas.width, tools.canvas.height);
          map.drawMap();
          map.outOfBounds();
          snake.drawSnake();
          snake.move();
          fruit.drawFruit();
      }



      let main = function() {
          if (game.gameOver) {
            game.gameOverMsg("Game Over");
            cancelAnimationFrame(main);
            return;
          } else {
            drawEverything();

            setTimeout(function() {
              requestAnimationFrame(main);
            }, 1000/20);
          }
      }

      window.addEventListener('keydown', function(e) {
        let key = e.keyCode;

        switch(key) {
          case 65: snake.direction = 'left';
          break;
          case 87: snake.direction = 'up';
          break;
          case 68: snake.direction = 'right';
          break;
          case 83: snake.direction = 'down';
          break;
        }
      });

      </script>
    </body>
    </html>

这是我将蛇下移的地方

  let drawEverything = function() {
          if (game.gameOver) {
            window.cancelAnimationFrame(main);
          }



          if (snake.x === fruit.x && snake.y === fruit.y) {
            fruit.generateNewFruit();
            snake.bodySize++;


          if (snake.bodySize === snake.tail.length) {
            for (let i=0; i < snake.tail.length - 1; i++) {
              snake.tail[i] = snake.tail[i+1];
            }
          }

          snake.tail[snake.bodySize-1] = {x: snake.x, y: snake.y};

          }

          tools.ctx.clearRect(0, 0, tools.canvas.width, tools.canvas.height);
          map.drawMap();
          map.outOfBounds();
          snake.drawSnake();
          snake.move();
          fruit.drawFruit();
      }

我在这里绘制更新后的向下移动的尾巴和蛇头

drawSnake: function() {

          for (let i=0; i < this.bodySize; i++) {
            tools.drawRect(this.tail[i].x, this.tail[i].y, this.size, this.size, this.color, 'fill', true, 'lime');
          }

          tools.drawRect(this.x, this.y, this.size, this.size, this.color, 'fill', true, 'lime');
}

我不知道我的drawSnake函数是否有问题;但无论出于何种原因,这不是想要一起绘制尾部阵列作为一组块。

1 个答案:

答案 0 :(得分:0)

我需要将for循环放在if语句中,以食用食物。