Develop a gluttonous snake in a WeChat mini-game

I myself have written a small game of gluttonous snake, but it is the operation of dom. The WeChat small game is developed based on canvas using js syntax. In order to save trouble, I directly searched for a canvas-based gluttonous snake implementation.

Many thanks to the author: not the treasure of Jiaduobao (from Jianshu)

Article address: https://www.jianshu.com/p/ba5031c20cde

However, if the author's code wants to be fully used in the small game, some modifications need to be made, such as eval support, alert support, and the source code events are keyboard events, the width and height of the snake are too small, etc. I have modified the above part of the source code. The following is the directory structure and code. You can create a project and copy the code to demonstrate:

Root directory:

 

js directory:

The libs directory remains unchanged, and this directory will be automatically generated by using quick generation;

libs directory:

game.js

import './js/libs/weapp-adapter'
import './js/libs/symbol'

import Main from './js/main'

js/main.js

var c = canvas.getContext('2d')
console.log(canvas)


var mWidth = canvas.width; //当前可视区域的宽,即canvas的宽 
var mHeight = canvas.height; //当前可视区域的高,即canvas的高 
var unit = 15; //设定每个格子的边长 
var mwid = mWidth / unit; //计算当前横向格子数量 
var mhei = mHeight / unit; //计算当前竖向格子数量 
var point = point = {x : 0 , y : 0}; //记录食物的坐标的变量初始化 
var score = 0; //记录成绩的变量初始化

//注意本对象,并不改变其在画布上的样子,只是负责改变状态,改变样子的另有方法
//蛇对象
var shake = {
      startX: 3,
      //开始头x坐标
      startY: 0,
      //开始头y坐标
      currOri: 'right',
      //初始化方向
      ori: [['left', 'right'], ['up', 'down']],
      //相逆方向数组
      oriss: ['left', 'right', 'up', 'down'],
      //所有允许的方向,用来判断方向合法性,在canChangeOri方法
      mes: [{
        x: 3,
        y: 0
      },
      {
        x: 2,
        y: 0
      },
      {
        x: 1,
        y: 0
      }],
      //初始化蛇的身体坐标,初始长度3
      //坐标为格子坐标非像素坐标
      //添加一个身体的方法
      add: function () {
        //判断当前尾部方向
        var last = this.mes[this.mes.length - 1]; //获取最后一个身体
        var plast = this.mes[this.mes.length - 2]; //获取倒数第二个身体
        var px = last.x - plast.x;
        var py = last.y - plast.y; //根据计算最后两个身体的坐标差,来计算添加身体应在的方向
        //计算新加元素位置
        var newEle = {
          x: last.x + px,
          y: last.y + py
        }; //创建一个新身体
        this.mes.push(newEle); //将新身体假如身体数组
      },
      //移动方向方法,下面几个方法类似,只是方向不同
      moveup: function () {
        var pre = this.mes[0]; //记录第一个身体,即头部的坐标
        this.mes[0] = {
          x: pre.x,
          y: pre.y - 1
        }; //让头部的坐标像上移动一格
        this.move(pre); //调用移动身体的方法
      },
      movedown: function () {
        var pre = this.mes[0];
        this.mes[0] = {
          x: pre.x,
          y: pre.y + 1
        };
        this.move(pre);
      },
      moveleft: function () {
        var pre = this.mes[0];
        this.mes[0] = {
          x: pre.x - 1,
          y: pre.y
        };
        this.move(pre);
      },
      moveright: function () {
        var pre = this.mes[0];
        this.mes[0] = {
          x: pre.x + 1,
          y: pre.y
        };
        this.move(pre);
      },
      //移动身体
      move: function (pre) { //参数为之前第一个身体,即头部的位置对象
        var tmp;
        for (var i = 1; i < this.mes.length; i++) { //遍历每一个身体节点
          tmp = this.mes[i];
          this.mes[i] = pre;
          pre = tmp;
        } //并且把每个节点的左边变化成前一个节点的坐标,达到依次向前的目的
      },
      //改变方向
      changeOri: function (ori) {
        if (this.oriss.indexOf(ori) == -1) { //判断方向是否在允许方向内
          return;
        }
        if (!this.canChangeOri(ori)) { //判断改变方向是否合法
          return;
        }
        this.currOri = ori; //如果上面两个都通过,改变方向
      },
      //判断改变的方向是否合法
      canChangeOri: function (ori) { //参数为方向字符串 例如:left
        if (ori == this.currOri) { //判断方向是否为当前方向,如果是则无需操作
          return false;
        }
        var oris = null;
        for (var i in this.ori) { //判断是否改变方向为当前方向的逆方向
          if (this.ori[i].indexOf(this.currOri) != -1) {
            oris = this.ori[i];
            break;
          }
        }
        if (oris.indexOf(ori) != -1) {
          return false;
        }
        return true;
      },
      //判断是否碰撞到了自己
      isCrashSelf: function () {
        var head = this.mes[0]; //获取头节点
        for (var i = 1; i < this.mes.length; i++) { //遍历身体节点
          if (this.mes[i].x == head.x && this.mes[i].y == head.y) { //判断头结点是否碰撞身体
            return true;
          }
        }
        return false;
      },
      //判断是否撞墙
      isCrashWell: function (width, height) { //参数为横竖的格子数量
        var head = this.mes[0]; //获取头节点
        if (head.x < 0 || head.y < 0) { //判断是否撞左上墙
          return true;
        }
        if (head.x > (width - 1) || head.y > (height - 1)) { //判断是否撞右下墙
          return true;
        }
        return false;
      },
      //处理吃东西
      handleAdd: function () {
        var head = this.mes[0]; //获取头节点
        if (head.x == point.x && head.y == point.y) { //判断头节点是否碰撞食物节点,食物在外定义
          this.add(); //调用添加身体
          getPoint(); //生成一个节点
          setPoint(); //画一个节点
          score++; //加分
          //s.innerHTML = score; //显示分数

        }
      }
}

//生成点
function getPoint() {
  point.x = Math.floor(Math.random( ) * mwid);
  point.y = Math.floor(Math.random( ) * mhei);
}

//画点
function setPoint() {
      c.rect(point.x * unit, point.y * unit, unit, unit);
}

//画蛇
function setShake() {
      for (var i = 0; i < shake.mes.length; i++) {
        //c.fullStyle = '#ffffff';
        c.strokeStyle = 'red';
        c.rect(shake.mes[i].x * unit, shake.mes[i].y * unit, unit, unit);
      }
      c.stroke();
}

//清屏
function clear() {
     c.clearRect(0, 0, mWidth, mHeight);
}


//开始游戏
var looper=null;
function startGame() {
      clearInterval(looper); //终止游戏主循环
      //初始化状态
      shake.mes = [{
        x: 3,
        y: 0
      },
      {
        x: 2,
        y: 0
      },
      {
        x: 1,
        y: 0
      }];
      shake.currOri = 'right';

      c.beginPath(); //开始画笔
      getPoint(); //设置点
      setPoint();

      setShake(); //话蛇
      //画
      c.stroke();

      //游戏主循环
      looper = setInterval(function () {

       //var method = 'move' + shake.currOri + '()'; //调用方向函数
       //eval('shake.' + method); //执行方向方法
       /*
         移动
       */
       //ori: [['left', 'right'], ['up', 'down']],
        if (shake.currOri =="left"){
          shake.moveleft();
        } else if (shake.currOri == "right"){
          shake.moveright();
        } else if (shake.currOri == "up"){
          shake.moveup();
        } else if (shake.currOri == "down"){
          shake.movedown();
      }
      
        clear(); //清理屏幕
        c.beginPath(); //开始绘制
        shake.handleAdd(); //处理吃东西
        setPoint(point); //设置点
        setShake(); //画蛇
        if (shake.isCrashWell(mwid, mhei)) { //是否撞墙,未使用是否吃自己。想用调用shake.isCrashSelf方法。
          clearInterval(looper);
          //console.log('you die');
          //console.log('you die , and your score is ' + score);
          /*
          提示
          */
          wx.showModal({
            title: '提示',
            content: '游戏结束 , 你的分数是 ' + score,
            success: function (res) {
              if (res.confirm) {
                console.log('用户点击确定')
                startGame()
              } else if (res.cancel) {
                console.log('用户点击取消')
              }
            }
          })
        }
      },
      200);
}
/*
启动
*/ 
wx.showModal({
  title: '提示',
  content: '是否开始游戏 ',
  success: function (res) {
    if (res.confirm) {
      console.log('用户点击确定')
      startGame()
    } else if (res.cancel) {
      console.log('用户点击取消')
    }
  }
})



//键盘监听
// window.onkeyup = function (key) {
//   var ori = '';
//   switch (key.keyCode) {
//     case 65:
//       ori = 'left';
//       break;
//     case 68:
//       ori = 'right';
//       break;
//     case 87:
//       ori = 'up';
//       break;
//     case 83:
//       ori = 'down';
//       break;
//   }
//   if (ori == '') {
//     return;
//   }
//   //改变蛇走向
//   shake.changeOri(ori);
// }
/*
方向
*/
var startX=0;
var startY = 0;
var moveEndX  = 0;
var moveEndY  = 0;
wx.onTouchStart(function (e) {
    //pageX
    //pageY
    //console.log(e.touches[0])
  startX = e.changedTouches[0].pageX;
  startY = e.changedTouches[0].pageY;
})

wx.onTouchMove(function (e) {
    // console.log(e.touches[0])
})

wx.onTouchEnd(function (e) {
    //console.log(e.changedTouches[0])
      moveEndX = e.changedTouches[0].pageX;
      moveEndY = e.changedTouches[0].pageY;
      var X = moveEndX - startX;
      var Y = moveEndY - startY;
      if (Math.abs(X) > Math.abs(Y) && X > 0) {
        console.log("right");
        shake.changeOri("right");
      }
      else if (Math.abs(X) > Math.abs(Y) && X < 0) {
        console.log(" left");
        shake.changeOri("left");
      }
      else if (Math.abs(Y) > Math.abs(X) && Y > 0) {
        console.log("down");
        shake.changeOri("down");
      }
      else if (Math.abs(Y) > Math.abs(X) && Y < 0) {
        console.log("up");
        shake.changeOri("up");
      }
      else {
        console.log("just touch");
      }
})

wx.onTouchCancel(function (e) {
  console.log(e.touches)
})

Effects in the simulator:

You can also click the editor preview button to scan the QR code to try it out on a real machine.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325255141&siteId=291194637