javascript - 蛇水平移动

标签 javascript

我正在尝试创建一个简单的贪吃蛇游戏。

(function() {
  var canvas = document.getElementById('canvas'),
      ctx = canvas.getContext('2d'),
      x = 0,
      y = 0,
      speed = 2; 
      x_move = speed,
      y_move = 0,                          
      food_position_x = Math.floor(Math.random() * canvas.width / 10) * 10,
      food_position_y = Math.floor(Math.random() * canvas.height / 10) * 10,
      size_x = 10;    

  function eat() {   
   console.log('food_x:' + food_position_x + ' x:' + x + ' / food_y:' + food_position_y + ' y:' + y);
    if (Math.floor(y / 10) * 10 == food_position_y && Math.floor(x / 10) *10  == food_position_x) {  
    	size_x += 2;
      //throw new Error("MATCH!"); // This is not an error. Just trying to stop the script
    }
  }
  
  // Drawing
  function draw() {
    eat();
    requestAnimationFrame(function() {      
      draw();      
    });    
    // Draw the snake
    ctx.beginPath();
    ctx.rect(Math.floor(x/10)*10, Math.floor(y/10)*10, size_x, 10);
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    ctx.fillStyle = '#ffffff'; 
    ctx.fill();
    ctx.closePath();

    // Draw the food
    ctx.beginPath(); 
    ctx.rect(Math.floor(food_position_x/10)*10, Math.floor(food_position_y/10)*10, 10, 10);
    ctx.fillStyle = "blue";
    ctx.fill();
    ctx.closePath();

    // Increase the value of x and y in order to animate
    x = x + x_move;
    y = y + y_move;       
  } 
  draw();

  // Key Pressing
  document.addEventListener('keydown', function(event) {
    switch(event.keyCode) {
      case 40: // Moving down
        if (x_move != 0 && y_move != -1) {
          x_move = 0;
          y_move = speed;
        }
      break;
      case 39: // Moving right
        if (x_move != -1 && y_move != 0) {
          x_move = speed;
          y_move = 0; 
        }
      break;
      case 38: // Moving top
        if (x_move != 0 && y_move != 1) {
          x_move = 0;
          y_move = -speed; 
        }
      break;
      case 37: // Moving left
        if (x_move != 1 && y_move != 0) {
          x_move = -speed;
          y_move = 0; 
        }
      break;
    }
  });
})();
canvas { background-color: #000022 }
<canvas id="canvas" width="400" height="400"></canvas>

jsfiddle

问题

每次当我捕获食物时,蛇都会变长,但是当你按下向下或向上键时,它会水平移动。

也许是一个解决方案

我认为解决方案可能是: 蛇应该是一个数组!每次按键时,定义蛇头的位置,并一步步移动蛇,因为它是一个数组。所以 body 跟随头部。但在这种情况下,我不知道如何从中创建一个数组。

也许还有其他解决方案。任何帮助将不胜感激!

最佳答案

您需要维护一个蛇体当前占据的点的数组,并在蛇接近时向数组添加新点(unshift)并删除点从数组的后面(pop)。以下代码是入门代码,您需要自己编写:)。

(function () {
    const COLORS={ SNAKE:'#ff7bf5', FOOD:'blue' };
    var canvas = document.getElementById('canvas'),
        ctx = canvas.getContext('2d');
    var snake=[], score=0;
    var x, y, food_position_x, food_position_y, x_move, y_move;
    var frameCount=0, framesRequiredToMove=10;
    //the less the framesToMove the faster the sname moves
    function draw(){
        if(++frameCount==framesRequiredToMove){
            frameCount=0;
            move();
        }
        requestAnimationFrame(draw);
    }
    function init(){
        snake = [{x:3,y:0},{x:2,y:0},{x:1,y:0},{x:0,y:0}];
        snake.forEach((p)=>{plot(p.x,p.y,COLORS.SNAKE)})
        x=snake[0].x;y=snake[0].y;
        score=0;x_move=1;y_move=0;
        scoreboard.innerText=score;
        newfood();
        setTimeout(draw,1000);
    }
    function plot(x,y,color){
        ctx.beginPath();
        ctx.rect(x * 10, y * 10, 10, 10);
        ctx.fillStyle = color;
        ctx.fill();
        ctx.closePath();
    }
    function move(){
        snakepx.innerText = x;
        snakepy.innerText = y;
        x = x + x_move;
        y = y + y_move;
        // Advance The Snake
        plot(x,y,COLORS.SNAKE);
        snake.unshift({x:x,y:y});
        // Check food encounter
        if(x==food_position_x && y==food_position_y){
            scoreboard.innerText=++score;
            newfood();
        }
        else{
            var last=snake.pop();
            ctx.clearRect(last.x * 10, last.y * 10, 10, 10);
        }
    }
    function newfood(){
        food_position_x=Math.floor(Math.random() * canvas.width / 10);
        food_position_y=Math.floor(Math.random() * canvas.height / 10);
        plot(food_position_x,food_position_y,COLORS.FOOD);
        foodpx.innerText = food_position_x;
        foodpy.innerText = food_position_y;
    }
    init();

    // Key Pressing
    document.addEventListener('keydown', function (event) {
        event.preventDefault();
        switch (event.keyCode) {
            case 40: // Moving down
                if (x_move != 0 && y_move != -1) {
                    x_move = 0;
                    y_move = 1;
                }
                break;
            case 39: // Moving right
                if (x_move != -1 && y_move != 0) {
                    x_move = 1;
                    y_move = 0;
                }
                break;
            case 38: // Moving top
                if (x_move != 0 && y_move != 1) {
                    x_move = 0;
                    y_move = -1;
                }
                break;
            case 37: // Moving left
                if (x_move != 1 && y_move != 0) {
                    x_move = -1;
                    y_move = 0;
                }
                break;
        }
    });
})();
canvas {
    background-color: #000022;
    float: left;
}
<canvas id="canvas" width="400" height="180"></canvas>
<div style="margin-left: 410px">
    Snake: (<span id="snakepx"></span>, <span id="snakepy"></span>)<br>
    Food: (<span id="foodpx"></span>, <span id="foodpy"></span>)<br>
    Score: <span id="scoreboard"></span>
</div>

关于javascript - 蛇水平移动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49603760/

相关文章:

javascript - 如何使用查询中不存在的值列表填充选择元素

javascript - $(window).on ('load' , ...) 在 MS Edge 中出现得太快

javascript - jQuery 切换更多按钮切换多个 div

javascript - 使用 PHP 设置焦点并选择错误的内容元素

javascript - 将所有内容加载到 Node.js 中的一个变量中是个好主意吗?

javascript - 如何从 base64 编码的字符串重建音频 blob?

javascript - 使用普通 JavaScript 围绕其中心旋转 SVG 矩形

javascript - 通过ajax从mysql数据库获取数据的问题

javascript - Bootstrap 中的弹出窗口

javascript - jQuery 调整视频大小,重置大小