首页 > 其他分享 >前端使用canvas实现贪吃蛇小游戏

前端使用canvas实现贪吃蛇小游戏

时间:2023-01-11 23:23:15浏览次数:40  
标签:body function canvas ctx direction 小游戏 snake 贪吃蛇 data

贪吃蛇是一款益智小游戏,通过点击上下左右四个按键控制蛇头移动。

设计思路

主要是设计蛇的身体和移动方法。将蛇的身体设置成一个数组,数组里存放蛇身每一节的 xy 坐标。游戏开始后,蛇头(数组第 0 位)会随着时间不断地移动,也就是x+1x-1y+1y-1,当蛇头移动了,身体的每一节 xy 将等于移动前它们的前一节,也就是说,第二节的位置将变成移动前蛇头的位置,依次变化就形成了蛇身的移动效果。当蛇吃到了食物的时候,则在数组里 push 蛇身移动前最后一节的 xy 值。

功能实现

1、通过 canvas 绘制画布

<canvas
  id="canvas"
  width="500"
  height="300"
  style="border:5px solid #2f0606;"
></canvas>
canvas = document.getElementById('canvas');
ctx = canvas.getContext('2d');
ctx.fillStyle = '#c0b4b4';
ctx.fillRect(0, 0, 500, 300);

画布的长宽是500 * 300

2、创建一条蛇

function Snake(x, y) {
  this.body = [[x, y]]; // 蛇的身体
  this.direction = 'right'; // 初始方向
  this.time = null; // 定时器
  this.move = function () {};
  this.eat = function () {};
  this.stop = function () {};
}

创建了一个叫 Snake 的构造函数。其中,xy是蛇头的初始位置;body是蛇的身体,是一个二维数组;direction代表移动方向,有rightlefttopbottom四个参数;time是一个定时器;move是一个方法,控制蛇身的移动,这是整个贪吃蛇的核心;eat是吃的函数;stop停止移动。

可以直接new一个Snake对象。

snake = new Snake(data.x, data.y);

data.xdata.y是初始位置。

3、让蛇动起来

这是贪吃蛇的核心,通过定时器让贪吃蛇动起来。先从蛇的最后一节移动,每一节等一它的前一节,当身体部分移动完了再通过direction参数判断蛇头该怎么移动。

this.move = function () {
  var _this = this;
  this.time = setInterval(function () {
    var last = [].concat(_this.body[_this.body.length - 1]);
    for (var i = _this.body.length - 1; i >= 1; i--) {
      _this.body[i][0] = _this.body[i - 1][0];
      _this.body[i][1] = _this.body[i - 1][1];
    }
    switch (_this.direction) {
      case 'right':
        _this.body[0][0] += 1;
        break;
      case 'bottom':
        _this.body[0][1] -= 1;
        break;
      case 'left':
        _this.body[0][0] -= 1;
        break;
      case 'top':
        _this.body[0][1] += 1;
        break;
    }
    // 检查是否遇到食物
    if (_this.body[0][0] === food.x && _this.body[0][1] === food.y) {
      _this.eat(last);
    }
    // 检查是否遇到自己身体
    var index = _this.body.findIndex(function (e, i) {
      return i !== 0 && _this.body[0][0] === e[0] && _this.body[0][1] === e[1];
    });
    if (
      index !== -1 ||
      (_this.body[0][0] === last[0] && _this.body[0][1] === last[1])
    ) {
      alert('你撞到自己了');
      _this.stop();
    }
    // 检查是否撞墙
    if (
      _this.body[0][0] < 0 ||
      _this.body[0][0] > 49 ||
      _this.body[0][1] < 0 ||
      _this.body[0][1] > 29
    ) {
      alert('你撞墙了');
      _this.stop();
    }
  }, data.timeout);
};

4、通过上下左右键控制蛇的移动

通过document.onkeydown来监听键盘点击事件。

function getKey() {
  document.onkeydown = function (event) {
    var e = event || window.event || arguments.callee.caller.arguments[0];

    if (e && e.keyCode == 38) {
      //下
      if (snake.direction !== 'top') snake.direction = 'bottom';
    }
    if (e && e.keyCode == 37) {
      //左
      if (snake.direction !== 'right') snake.direction = 'left';
    }

    if (e && e.keyCode == 39) {
      //右
      if (snake.direction !== 'left') snake.direction = 'right';
    }

    if (e && e.keyCode == 40) {
      //上
      if (snake.direction !== 'bottom') snake.direction = 'top';
    }
  };
}

snake是之前new的蛇对象。

5、创建一份食物,当蛇吃到食物会变长

function Food() {
  this.x = Math.floor(Math.random() * 50);
  this.y = Math.floor(Math.random() * 30);
}

食物有xy轴坐标,通过new Food()来创建食物。

然后为蛇添加吃的函数功能

this.eat = function (last) {
  this.body.push(last);
  score += 1;
  food = new Food();
};

last是蛇移动前的最后一节位置坐标[x, y]。每次蛇吃了食物之后会增长,然后创建新的食物。

6、将蛇和食物绘制在画布上

  1. 将蛇绘制在画布上。
for (var i = 0; i < snake.body.length; i++) {
  ctx.save();
  ctx.translate(snake.body[i][0] * data.size, snake.body[i][1] * data.size);
  if (i === 0) {
    ctx.fillStyle = 'DarkGreen';
  } else {
    ctx.fillStyle = 'green';
  }
  ctx.fillRect(0, 0, data.size, data.size);
  ctx.restore();
}
  1. 将食物绘制在画布上
ctx.save();
ctx.translate(food.x * data.size, food.y * data.size);
ctx.fillStyle = 'OrangeRed';
ctx.fillRect(0, 0, data.size, data.size);
ctx.restore();

画布可以通过requestAnimationFrame更新。

7、开始和停止

只需要调用snake.move()函数就能让蛇移动,这个过程会创建一个定时器time

想让蛇停止只需要清除定时器。

this.stop = function () {
  clearInterval(this.time);
};

调用snake.stop()就能让蛇停止移动。

<iframe allowfullscreen="allowfullscreen" frameborder="0" height="500" src="//jsrun.net/EYcKp/embedded/all/light" width="100%"></iframe>

标签:body,function,canvas,ctx,direction,小游戏,snake,贪吃蛇,data
From: https://www.cnblogs.com/wenonly/p/17045178.html

相关文章

  • 一个C语言的剪刀石头布小游戏
    /******************************************************石头剪刀布的程序geek_monkey于2015年3月3日修改了bug(输入字符非石头剪刀布都算是玩家赢)编译环境为VC+......
  • Canvas常见问题汇总
    ##drawImage远端图片再使用getImageData时报错Uncaught(inpromise)DOMException:Failedtoexecute'getImageData'on'CanvasRenderingContext2D':Thecanva......
  • 小程序 canvas(老写法) 图片切图(一张图片切成3*3 、6*6 、长宽均等)
    <viewclass='sudoku'><viewclass='canvas-box'><canvascanvas-id='canvasIn'id='canvas'class='canvascanvas-in'style='{{canvasWH}}'wx:if='{{canvasI......
  • 适合编程初学者的开源项目:小游戏2048(微信小程序版)
    目标为编程初学者打造入门学习项目,使用各种主流编程语言来实现。2048游戏规则一共16个单元格,初始时由2或者4构成。1、手指向一个方向滑动,所有格子会向那个方向运动。2......
  • Python小游戏(1)
    name=str(input('请输入姓名:'))age=int(input('请输入真实年龄:'))ifage>=18:print(f'恭喜{name}可以在网上冲浪了。')else:print('小小年纪不学好,赶紧回......
  • 简单的24点小游戏
    简单的24点小游戏游戏规则随机生成4个数字(1-10),通过+-*/四则运算将4个数字算出24即可游戏设计生成4个数字,并给出参考答案随机生成0-10之间的4个整数穷举4个数所......
  • 适合编程初学者的开源项目:小游戏2048(Go语言版)
    目标为编程初学者打造入门学习项目,使用各种主流编程语言来实现。2048游戏规则一共16个单元格,初始时由2或者4构成。1、手指向一个方向滑动,所有格子会向那个方向运动。2......
  • 适合编程初学者的开源项目:小游戏2048(Vue版)
    目标为编程初学者打造入门学习项目,使用各种主流编程语言来实现。2048游戏规则一共16个单元格,初始时由2或者4构成。1、手指向一个方向滑动,所有格子会向那个方向运动。2、相......
  • Canvas与图层(三)恢复画布
    恢复画布有两个函数:restore()与rest无论哪种*恢复画布有两个函数:restore()与restongoCount()restore()就是把回退栈中的最上层画布状态出栈,恢复画布状态,​​具体使用​​r......
  • Canvas与图层(二)画布与图层
    图层(Layer):每次调用canvas.drawXXX系列函数,都会生成一个透明图层来绘制这个图形画布(Bitmap):每块画布都是一个Bitmap,所有的图像都是画在这个Bitmap上的,画布有两种:*一种是Vi......