微信小程序-贪吃蛇

    这两天接触了微信小程序,觉得还蛮好玩的,所以就在官网上下载了微信开发者工具,然后翻阅了会儿它的API,发现很多工具都是集成好了的用起来非常方便,缩减了开发者的受挫感。

    后来我在网易课堂找到了一门关于小程序开发的入门课程,里面有一些实战,先做了贪吃蛇,基本思想跟代码都是跟老师一致的,不过我后来又添加了蛇死亡的动作。有小伙伴刚好看了那门课程也想要代码的可以取走~

  进入正题,整个小程序值需要一个.js文件跟.wxml文件就可,其中.wxml文件如下:

<canvas canvas-id="snakCanvas" style="width:100%;height:100%;background-color:#ccc;"
 bindtouchstart="canvasStart" bindtouchmove="canvasMove" bindtouchend="canvasEnd"></canvas>

.js文件中主要是一些代码逻辑,首先定义手指的方向以及蛇运动的方向,通过坐标的差值比较来判断蛇的方向,具体方法如下:

 if(Math.abs(X)>Math.abs(Y)&&X>0){       
       direction = "right";
    } else if (Math.abs(X) > Math.abs(Y) && X < 0){
       //console.log("left");
       direction = "left";
    } else if (Math.abs(X) < Math.abs(Y) && Y > 0){
       //console.log("down");
       direction = "down";
    } else if (Math.abs(X) < Math.abs(Y) && Y < 0){
       //console.log("top");
       direction = "top";
    }
  },

绘制蛇头蛇身:

function draw(obj) {
      context.setFillStyle(obj.color);//设置填充色。
      context.beginPath();//开始创建一个路径,需要调用fill或者stroke才会使用路径进行填充或描边。
      context.rect(obj.x, obj.y, obj.w, obj.h);//创建一个矩形。
      context.fill();//对当前路径中的内容进行填充。
    }
    //绘制蛇头
    draw(snakHead);     
    //绘制蛇身
    for(var i=0;i<snackBodys.length;i++){
      var snakeBody=snackBodys[i];
      draw(snakeBody);

让蛇根据手指方向运动起来:

switch (snakeDirection) {
          case "left": snakHead.x = snakHead.w;
            break;
          case "right": snakHead.x = snakHead.w;
            break;
          case "down": snakHead.y = snakHead.h;
            break;
          case "top": snakHead.y = snakHead.h;
            break;
        }

绘制食物:这里绘制食物使用随机函数,对食物的大小颜色进行随机化。

//绘制食物
    for(var i=0;i<foods.length;i++){
      var foodObj=foods[i];
      draw(foodObj);
      if(collide(snakHead,foodObj)){
        //console.log("碰撞");
        collideBol = false;
        score+=10;
        foodObj.rest();
      }
    }    
    wx.drawCanvas({
      canvasId:"snakCanvas",
      actions:context.getActions()
    });
    requestAnimationFrame(animate);
    }
    
    function rand(min,max){
      return parseInt(Math.random() * (max - min)) + min;
    }
     //构造食物对象
    function Food() {
      this.x = rand(0,windowWidth);
      this.y = rand(0,windowHeight);
      var w=rand(10,20);
      this.w=w;
      this.h=w;
      this.color = "rgb(" + rand(0, 255) + "," + rand(0, 255) + "," + rand(0, 255)+")";
      this.rest=function(){
        this.x = rand(0, windowWidth);
        this.y = rand(0, windowHeight);
        this.color = "rgb(" + rand(0, 255) + "," + rand(0, 255) + "," + rand(0, 255) + ")";
      }
    }

接着讨论蛇头与食物的碰撞,主要的想法是通过比较蛇头以及食物四个边进行比较,碰撞后系统就会再次随机出一个新的食物,所以食物是永远吃不完的。

//碰撞函数
    function collide(obj1,obj2){
      var l1=obj1.x,
      r1=l1+obj1.w,
      t1=obj1.y,
      b1=t1+obj1.h;

      var l2 = obj2.x,
        r2 = l2 + obj2.w,
        t2 = obj2.y,
        b2 = t2 + obj2.h;

      if (r1 > l2 && l1 < r2 && b1 > t2 && t1 < b2){
         return true;
      }else{
        return false;
      }
    }

最后我自己又写了个函数来判断蛇头与自己的身体碰撞后就会死亡,用到了 wx.showToast函数,但是做完后因为die会一直触发,所以我又把die置为false然后弹出框可以正常弹出了,但是后面的蛇却还在移动。无奈我就用了alert方法,这个方法在微信小程序里不存在,所以触发后程序就以错误信息停止了。但是界面效果确实我想要的。所以有小伙伴感兴趣的话可以自己改一下,顺便私信我方法~

    这是整个的.js文件内容:

//手指按下坐标
var startX = 0, startY=0;
//手指移动坐标
var moveX=0,moveY=0;
//移动位置跟开始位置的差值
var X=0,Y=0;
//蛇头对象
var snakHead={
  x:0,y:0,
  color:"#ff0000",
  w:20,h:20
}
//手机窗口宽高
var windowWidth = 0, windowHeight=0;
//身体对象 数组
var snackBodys=[];
//食物
var foods=[];
//确定身体不再继续增长是否删除
var collideBol=true;
//是否死亡
var die = false;
//总分
var score=0;
//手指方向
var direction=null;
//蛇移动方向
var snakeDirection="right";
Page({
  canvasStart:function(e){
    startX=e.touches[0].x;
    startY=e.touches[0].y;
  },
  canvasMove:function(e){
    moveX=e.touches[0].x;
    moveY=e.touches[0].y;
    X=moveX-startX;
    Y=moveY-startY;

    if(Math.abs(X)>Math.abs(Y)&&X>0){       
       direction = "right";
    } else if (Math.abs(X) > Math.abs(Y) && X < 0){
       //console.log("left");
       direction = "left";
    } else if (Math.abs(X) < Math.abs(Y) && Y > 0){
       //console.log("down");
       direction = "down";
    } else if (Math.abs(X) < Math.abs(Y) && Y < 0){
       //console.log("top");
       direction = "top";
    }
  },
  canvasEnd:function(){
    snakeDirection=direction;
  },
  onReady:function(){
    //获取画布上下文
    var context=wx.createContext();
    //帧数
    var frameNumm=0;  

    //碰撞函数
    function collide(obj1,obj2){
      var l1=obj1.x,
      r1=l1+obj1.w,
      t1=obj1.y,
      b1=t1+obj1.h;

      var l2 = obj2.x,
        r2 = l2 + obj2.w,
        t2 = obj2.y,
        b2 = t2 + obj2.h;

      if (r1 > l2 && l1 < r2 && b1 > t2 && t1 < b2){
         return true;
      }else{
        return false;
      }
    }
    
    function animate(){
      frameNumm++;
      if (frameNumm%20==0){//限制蛇移动速度
        snackBodys.push({//蛇身在蛇头的位置开始push
          x: snakHead.x,
          y: snakHead.y,
          w: snakHead.w,
          h: snakHead.h,
          color: "#00ff00"
        });      
      //向蛇身体数组添加一个最新的位置(身体对象)
      if (snackBodys.length > 4) {
        if(collideBol){
        //删除身体数组第一位,保证长度为4
        snackBodys.shift();
        }else{
          collideBol=true;
        }
      }

      if(die){
        switch (snakeDirection) {
          case "left": snakHead.x = snakHead.w;
            break;
          case "right": snakHead.x = snakHead.w;
            break;
          case "down": snakHead.y = snakHead.h;
            break;
          case "top": snakHead.y = snakHead.h;
            break;
        }
      } else{
        switch (snakeDirection) {
          case "left": snakHead.x -= snakHead.w;
            break;
          case "right": snakHead.x += snakHead.w;
            break;
          case "down": snakHead.y += snakHead.h;
            break;
          case "top": snakHead.y -= snakHead.h;
            break;
              }
            }
      }
    function draw(obj) {
      context.setFillStyle(obj.color);//设置填充色。
      context.beginPath();//开始创建一个路径,需要调用fill或者stroke才会使用路径进行填充或描边。
      context.rect(obj.x, obj.y, obj.w, obj.h);//创建一个矩形。
      context.fill();//对当前路径中的内容进行填充。
    }
    //绘制蛇头
    draw(snakHead);     
    //绘制蛇身
    for(var i=0;i<snackBodys.length;i++){
      var snakeBody=snackBodys[i];
      draw(snakeBody);
      if (collide(snakHead, snakeBody)) {
        
         die=true;
      }
    }
    //死亡后弹出框
    if(die){
      wx.showToast({
        title: 'you are died!',
        icon: 'succes',
        duration: 10000,
        mask: true
      })
      die=false;
      console.log(score);
      alert("die");
    }
    
    //绘制食物
    for(var i=0;i<foods.length;i++){
      var foodObj=foods[i];
      draw(foodObj);
      if(collide(snakHead,foodObj)){
        //console.log("碰撞");
        collideBol = false;
        score+=10;
        foodObj.rest();
      }
    }    
    wx.drawCanvas({
      canvasId:"snakCanvas",
      actions:context.getActions()
    });
    requestAnimationFrame(animate);
    }
    
    function rand(min,max){
      return parseInt(Math.random() * (max - min)) + min;
    }
     //构造食物对象
    function Food() {
      this.x = rand(0,windowWidth);
      this.y = rand(0,windowHeight);
      var w=rand(10,20);
      this.w=w;
      this.h=w;
      this.color = "rgb(" + rand(0, 255) + "," + rand(0, 255) + "," + rand(0, 255)+")";
      this.rest=function(){
        this.x = rand(0, windowWidth);
        this.y = rand(0, windowHeight);
        this.color = "rgb(" + rand(0, 255) + "," + rand(0, 255) + "," + rand(0, 255) + ")";
      }
    }
   //getSystemInfo获取系统信息。
    wx.getSystemInfo({
      success: function(res) {
        windowWidth = res.windowWidth;
        windowHeight = res.windowHeight;
        for(var i=0;i<20;i++){
          var foodObj=new Food();
          foods.push(foodObj);
        }
        animate();
      },
    })
   
   
  }
})

    大家一起学习一起进步~~

转载于:https://my.oschina.net/u/3614593/blog/1486821

  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值