微信小程序进阶篇

这篇博客详细介绍了微信小程序开发贪吃蛇游戏的过程,包括基本的项目结构、游戏规则和实现步骤。游戏规则是蛇吃到食物得分并增长,碰到边界或得分超3000则游戏结束。涉及的API包括canvas、wx.getSystemInfo、wx.showToast等。
摘要由CSDN通过智能技术生成

微信小程序

  • 什么是微信小程序
    微信小程序(weixinxiaochengxu),简称小程序,缩写XCX,英文名mini program,是一种不需要下载安装即可使用的应用,它实现了应用“触手可及”的梦想,用户扫一扫或搜一下即可打开应用。

  • 什么产品可以使用小程序
    由于小程序不需要下载,占用内存小,用户体验优秀,一些使用频率低的应用可以使用小程序。

  • 微信小程序的开发准备
    1.微信小程序开发API介绍文档链接
    微信小程序开发API
    2.微信注册账号(个人账号就可以开发)
    3.小程序开发工具
    开发工具下载地址以及介绍

  • APPID注册地址
    APPID注册

基本的项目结构介绍
1.三个全局文件
  • app.js
    程序启动时执行的文件,程序一旦启动就执行App()函数
  • app.json
    规定了显示的页面(.wxml 文件,类似于html),按照循序来显示,以及标题栏的样式等,如果别的页面没有定义json则用此文件
  • app.wxss
    页面布局样式,如果别的页面没有定义wxss则用此文件
2.一个文件夹包括一个完整页面信息
3.一个warning:项目路径必须是英文,但项目名称可以是中文

这里写图片描述

项目介绍

贪吃蛇小游戏,蛇可以根据手指指定的方向移动,吃到食物则累计加分,分数越高,长度越长,速度越快,直到碰壁或者得分超过3000,游戏停止。

用到的组件以及API

具体应用代码后续有说到
  • canvas

这里写图片描述

  • wx.getSystemInfo(OBJECT)

这里写图片描述

这里写图片描述

  • wx.showToast(OBJECT)

这里写图片描述

  • wx.showModal(OBJECT)

这里写图片描述

这里写图片描述

  • wx.navigateBack(OBJECT)

这里写图片描述

步骤

  • 1.画一个背景,背景色为鹅黄色
    用组件画布画了一个背景,绑定事件bindtouchstart,bindtouchmove
<canvas canvas-id="snakeCanvas" style="width:100%; height:100%; background-color:#FFFFCC;" bindtouchstart="canvasStart"  bindtouchmove="canvasMove"/>

这里写图片描述

实现绑定事件,确定手指滑动到的位置以及方向

// 手指开始位置
var startX = 0;
var startY = 0;

// 手指移动路径
var moveX = 0;
var moveY = 0;

// 差值
var X = 0;
var Y = 0;

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) {
      console.log("向右");
    }else if(Math.abs(X) > Math.abs(Y) && Y<0) {
      console.log("向左");
    }else if(Math.abs(X) < Math.abs(Y) && Y>0) {
      console.log("向下");
    } else if (Math.abs(X) < Math.abs(Y) && Y < 0) {
      console.log("向上");
    } 
  }

函数测试结果:

这里写图片描述

  • 2.绘制一个蛇头,并让蛇头根据手指移动的方向移动
    需要的变量
//画布上下文
var context = null;

// 蛇头
var snakeHead = {
    color: "#99FFCC",
    x: 0,
    y: 0,
    w: snakeW,
    h: snakeH
};

// 蛇头移动方向,默认向右
var snakeMoveDirection = "right";

修改canvasMove绑定事件:
逻辑:蛇头向上向下不允许直接切换,向左向右也不允许直接切换

  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 && !(snakeMoveDirection == "left") ){
          //  向右
          snakeMoveDirection = "right";
          console.log("向右"); 
      } else if (Math.abs(X) > Math.abs(Y) && X<0 && !(snakeMoveDirection == "right") ){
          //  向左
          snakeMoveDirection = "left";
          console.log("向左");
      } else if (Math.abs(X) < Math.abs(Y) && Y>0 && !(snakeMoveDirection == "top") ){
          //  向下
          snakeMoveDirection = "bottom";
          console.log("向下");
      } else if (Math.abs(X) < Math.abs(Y) && Y<0 && !(snakeMoveDirection == "bottom") ){
          //  向上
          snakeMoveDirection = "top";
          console.log("向上");
      }
  }

绘制蛇头,循环执行绘画使其移动

function beginGame(){
      //获得画布上下文
      context = wx.createContext();
      // 绘制蛇头
      function drawObj(obj) {

        context.setFillStyle(obj.color);
        context.beginPath();
        context.rect(obj.x, obj.y, obj.w, obj.h);
        context.closePath();
        context.fill();
      }

      function beginDraw (){   
         //移动
         switch(snakeMoveDirection){
             case "left":
                 snakeHead.x -= snakeHead.w-14;
                 break;
             case "right":
                 snakeHead.x += snakeHead.w - 14;
                 break;
             case "top":
                 snakeHead.y -= snakeHead.w - 14;
                 break;
             case "bottom":
                 snakeHead.y += snakeHead.w - 14;
                 break;
          }

          drawObj(snakeHead);
          // 调用 wx.drawCanvas,通过 canvasId 指定在哪张画布上绘制,通过 actions 指定绘制行为

          wx.drawCanvas({
              canvasId: 'snakeCanvas',
              actions: context.getActions() // 获取绘图动作数组
          });
          // 循环执行动画绘制
          requestAnimationFrame(beginDraw);
    }
    beginDraw();
  }
  beginGame();
}

效果:
这里写图片描述

  • 3.绘画蛇的身体

变量:

// 蛇身数组 
var snakeBodys = [];

修改函数beginDraw
把蛇移动的频率改成moveSpeedLevel ,移动的长度改成蛇身长
蛇身的逻辑是这样的,蛇身的长度有一个控制范围,然后每次增加一个蛇身,这个蛇身保持当前蛇头的信息,当这个蛇头信息改变后,蛇身就是上一个蛇头,蛇身其实就是记录了一个蛇身长度的信息,所以要在蛇头改变以前记下来

    //每moveSpeedLevel移动一次
    if(++perform %moveSpeedLevel ==0){
        // 添加蛇身
        snakeBodys.push({
           color: "#CCFFCC",
           x: snakeHead.x,
           y: snakeHead.y,
           w: snakeW,
           h: snakeH
        });

        // 只要长度大于5,移除蛇身

        if (snakeBodys.length>5){
            snakeBodys.shift();      
         }
         //每次移动一个身体的长度
         switch(snakeMoveDirection){
             case "left":
                snakeHead.x -= snakeHead.w;
                break;
             case "right":
                snakeHead.x += snakeHead.w;
                break;
             case "top":
                 snakeHead.y -= snakeHead.h;
                 break;
             case "bottom":
                 snakeHead.y += snakeHead.h;
                 break;
          }

    }
    // 绘制蛇头
    drawObj(snakeHead);

    // 绘制蛇身体
    for (var i=0; i<snakeBodys.length; i++) {
        var snakeBody = snakeBodys[i];     
        drawObj(snakeBody);
    }

效果:
这里写图片描述

  • 4.绘制食物
    变量:
// 手机屏幕宽/高
var windowW = 0;
var windowH = 0;
//食物的颜色
var mycolor = ["#FFCCFF", "#CCCCFF","#99CCFF"];
// 食物
var foods = [];

用到了微信的API来获取屏幕长度,因为每个手机屏幕大小不一样

    wx.getSystemInfo({
        success: function(res) { 
            // console.log(res.windowWidth);
            // console.log(res.windowHeight);
            windowW = res.windowWidth;
            windowH = res.windowHeight;

        }
    })

创建一个食物对象
randomAB

    function randomAB(A,B) {
        return parseInt(Math.random()*(B-A)+A);
    }
    // 食物构造方法
    function Food() {
        this.color = mycolor[randomAB(0,3)];
        this.x = randomAB(0, windowW-20);
        this.y = randomAB(0, windowH-20);
        var w = 15;
        this.w = w;
        this.h = w;

        // 重置位置
        this.reset = function (){
        this.color = mycolor[randomAB(0, 3)];
        this.x = randomAB(0, windowW);
        this.y = randomAB(0, windowH);
        var w = 15;
        this.w = w;
        this.h = w;
        }
    }

在初始化函数里创建食物

        // 创建食物 25个
        for (var i = 0; i<25; i++) {       
            var food = new Food();
            foods.push(food);
        }

在绘制函数beginDraw里:

// 绘制食物 25个
for (var i = 0; i<foods.length; i++) {
     var food = foods[i];              
     drawObj(food);
}

效果:
这里写图片描述

  • 5.实现游戏的加分,即碰到食物就加分,且蛇身加长,达到一定次数就给蛇加速

判断蛇头是否碰到食物

    // 吃到食物函数
    function eatFood(snakeHead, food){
        var sL = snakeHead.x;
        var sR = sL+snakeHead.w;
        var sT = snakeHead.y;
        var sB = sT+snakeHead.h;

        var fL = food.x;
        var fR = fL+food.w;
        var fT = food.y;
        var fB = fT+food.h;

        if ( sR>fL && sB>fT && sL<fR && sT<fB && sL<fR ){
            return true;
        } else {
            return false;
        }
    }

每加一次分用微信的API showToast 来提示,每吃到一个食物,就重置一个随机位置的食物

// 吃食物
if( eatFood(snakeHead, food) ){
    // 食物重置
    food.reset();

    wx.showToast({
        title: "+"+food.w+"分",
        icon: 'succes',
        duration: 500
    })
    score+=food.w;

    // 吃到食物的次数
    eatFoodCount++
    if(eatFoodCount%speederPerFood==0){
    // 每吃到speederPerFood次食物 蛇移动速度变快                      
    moveSpeedLevel-=1;                
    if (moveSpeedLevel<=2){
        moveSpeedLevel = 2;
     }
     shouldRemoveBody = false;
 }

这里写图片描述

要实现蛇身的增加,那么移除蛇身的代码需要修改,如果此次吃到食物,那么不执行移除操作,那么蛇身长度增加

变量

// 是否变长/即移除蛇身 
var shouldRemoveBody = true;
// 移除蛇身

if (snakeBodys.length>5){

    if(shouldRemoveBody ){

        snakeBodys.shift();
     }    
     shouldRemoveBody = true;           
}

这里写图片描述

  • 6.设置游戏结束方式
游戏失败
一旦贪吃蛇的蛇头碰到了手机屏幕的边界,那么就提示用户游戏失败了
if(snakeHead.x>windowW || snakeHead.x<0 || snakeHead.y>windowH || snakeHead.y<0){
     wx.showModal({
       title: "总得分:"+score+"分-----蛇身总长:"+snakeBodys.length+"",
       content: '游戏失败, 是否重新开始',
       success: function(res) {
         console.log(res)
         if (res.confirm) {
           beginGame();

          } else {
            initGame();
            wx.navigateBack({
              delta: 1
            })
         }
     }
   })

   return;
}

这里写图片描述

游戏成功
分数达到3000以上就为成功,测试时设置为100
if (score >= 3000) {
   wx.showModal({
      title: "总得分:" + score + "分-----蛇身总长:" + snakeBodys.length + "",
      content: '游戏成功,是否重新开始',
      success: function (res) {
        console.log(res)
        if (res.confirm) {
          beginGame();

        } else {
          initGame();
          wx.navigateBack({
             delta: 1
          })
        }
      }
    })
     return;
 }

这里写图片描述

  • 7.增加开始提醒,在游戏开始时弹出对话框
    写在onReady的函数里面,点击确定后才执行开始函数
    wx.showModal({
        title: '请开始游戏',
        content: "每得15分,蛇身增长1 ",
        success: function(res) {
            if (res.confirm) {
                 beginGame();                     
            } else {
                initGame();
                wx.navigateBack({
                    delta: 1
                })
            }
        }
    });

这里写图片描述

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值