简体   繁体   English

JavaScript蛇游戏-如何移动苹果?

[英]javascript snake game - how to move the apple?

I've wrote this simple snake game - the one where you use arrows to navigate the snake to eat apples (red circle). 我已经编写了这个简单的蛇游戏-在该游戏中,您使用箭头导航蛇吃苹果(红色圆圈)。 Right now in my code when snake eats (intersects) the apple its(snake) size increases by 1 block (10px). 现在在我的代码中,当蛇吃(相交)苹果时,其(蛇)的大小增加1块(10像素)。 What I would like to do is: every time the snake eats the apple -> increase snake size -> move the apple to different position within the canvas. 我想做的是:每次蛇吃掉苹果->增加蛇的大小->将苹果移到画布中的不同位置。

inside the code I've marked the section where I think the code for moving the apple should go, but I don't know how to implement and what would be the actual code for that: 在代码内部,我已经标记了我认为移动苹果的代码应该去的那部分,但是我不知道如何实现以及该代码的实际代码是什么:

if (!this.objectCollide(myApple)){
      this.segments.pop();
    } else {
      alert("COLLISION!!"))
    }; 

here's the Full Javascript code: 这是完整的Javascript代码:

var gameField = document.getElementById('gameField');
var ctx = gameField.getContext("2d");
var blockSize = 10;
columnCt = gameField.width / blockSize;
rowsCt = gameField.height / blockSize;

var block = function(x, y) {
  this.x = x;
  this.y = y;
}

block.prototype.drawBlock = function() {
  ctx.fillStyle = "blue";
  ctx.fillRect(this.x * blockSize, this.y * blockSize, blockSize,
    blockSize);
};

block.prototype.drawApple = function() {
  ctx.fillStyle = "red";
  ctx.textBaseline = "bottom";
  ctx.arc(this.x, this.y, 6, 2 * Math.PI, false);
  ctx.fill();
}

var Snake = function() {
  this.segments = [new block(20, 20), new block(19, 20), new block(18, 20), new block(17, 20),
    new block(16, 20), new block(15, 20), new block(14, 20), new block(13, 20), new block(12, 20),
    new block(11, 20), new block(10, 20)
  ];
  this.direction = "right";
}

Snake.prototype.drawSnake = function() {
  for (i = 0; i < this.segments.length; i++) {
    this.segments[i].drawBlock();
  }
}

Snake.prototype.setDirection = function(dir) {
  if (this.direction == "left" && dir == "right" || this.direction == "right" && dir == "left" || this.direction == "up" && dir == "down" ||
    this.direction == "down" && dir == "up") {
    return
  } else {
    this.direction = dir;
  };
};

Snake.prototype.objectCollide = function(obj) {
  if (this.segments[0].x == Math.round(obj.x / blockSize) && this.segments[0].y == Math.round(obj.y / blockSize)) {
    return true
  } else {
    return false
  }
};

Snake.prototype.move = function() {
  var head = this.segments[0];
  var newHead;

  switch (this.direction) {
    case "right":
      newHead = new block(head.x + 1, head.y);
      break;
    case "left":
      newHead = new block(head.x - 1, head.y)
      break;
    case "down":
      newHead = new block(head.x, head.y + 1)
      break;
    case "up":
      newHead = new block(head.x, head.y - 1)
      break;
  }

  this.segments.unshift(newHead);

  if (!this.objectCollide(myApple)) {
    this.segments.pop();
  } else {
    alert("COLLISION!!!")
  };
  var collision = newHead.x >= columnCt || newHead.x <= -1 ||
    newHead.y >= rowsCt || newHead.y <= -1;

  for (i = 1; i < this.segments.length; i++) {
    if (this.segments[i].x == newHead.x && this.segments[i].y == newHead.y) {
      collision = true;
      break;
    };
  };

  if (collision) {
    clearInterval(myFun);
  };

};

var mySnake = new Snake()
mySnake.drawSnake();
var myApple = new block(Math.floor(Math.random() * gameField.width),
  Math.floor(Math.random() * gameField.height));
var myFun = setInterval(function() {
  ctx.clearRect(0, 0, gameField.width, gameField.height);
  mySnake.move();
  mySnake.drawSnake();
  myApple.drawApple();
}, 100)

var directions = {
  37: "left",
  38: "up",
  39: "right",
  40: "down"
};

document.onkeydown = function(event) {
  var newDirection = directions[event.keyCode]
  if (newDirection != undefined) {
    mySnake.setDirection(newDirection);
  };
};

And example on JSFiddle: https://jsfiddle.net/x9ztn3vs/ 在JSFiddle上的示例: https ://jsfiddle.net/x9ztn3vs/

Instead of using alert("COLLISION!!!"); 而不是使用alert("COLLISION!!!"); just do these two things: 只需做以下两件事:

Increasing the size of the snake 增加蛇的大小

Just add another element to the array at the end: 只需在数组的最后添加另一个元素:

this.segments.push(this.segments[this.segments.length-1]);

Moving around the apple 在苹果周围走动

do {
    myApple.x = Math.floor(Math.random() * gameField.width);
    myApple.y = Math.floor(Math.random() * gameField.height);
    var colliding = this.segments.find((v) => v.x == Math.round(myApple.x / blockSize) && v.y == Math.round(myApple.y / blockSize));    
} while (colliding);

Disclaimer: it is not efficient. 免责声明:效率不高。 It will lag as the snake's length will increase because the probability of collision. 它会滞后于蛇的长度,因为发生碰撞的可能性会增加。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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