微信小程序云开发--拼图游戏

声明:在写这个拼图游戏以前也参看过很多其他的小程序拼图相关的列子。我的这个与其他的不同,是采用小程序云开发的模式,省去了服务器,供读者参考,同时,也希望各位能帮忙扫下二维,点一下小广告。挣钱不容易,谢谢哈!!

啥也不说上代码,看列子:哈哈

一.登陆页面

1.xml

<view class='uh'>
     <view class="uh-i" wx:if="{{avatarUrl!=''}}">
          <image  wx:if="{{avatarUrl!=''}}" src="{{avatarUrl}}"></image>
     </view>
     <button  wx:if="{{avatarUrl==''}}" class="uh-i uh-ib"  open-type="getUserInfo"  bindgetuserinfo="getUserAvatar">
          获取头像
     </button>
</view>

<view class="login">
     <view>嘿,小伙伴!欢迎进入爱拼图!</view>
     <view>爱拼才会赢,加油!</view>
     <view style='justify-content: center; display: flex;flex-direction:row;margin-top:30px;'>
          <view class='login-btn' bindtap='getOpenId'>登陆</view>
     </view>

     <view wx style='justify-content: center; display: flex;flex-direction:row;margin-top:30px;'>
          <view class='login-btn' bindtap='goUploadFile'>上传文件</view>
     </view>
</view>

2.登陆js

// miniprogram/pintu/login/login.js
var app = getApp();
var db = wx.cloud.database({ env: 'pro-egh5a' });
Page({

     /**
      * 页面的初始数据
      */
     data: {
          avatarUrl: '',
          userInfo:'',
     },

     /**
      * 生命周期函数--监听页面加载
      */
     onLoad: function (options) {
//3b07eb945d01f254008157e70b245bb4  2.13  2.12  94b1e1fc5d01f1d40082fbab1351b738
          this.getUserMes(); 
          
     
     },

     /**
      * 获取用户openId
      */
     getOpenId:function(){
          

        wx.cloud.callFunction({
             name: 'login',
             data: {},
             success: res => {
                  var avatarUrl = this.data.userInfo.avatarUrl;
                  console.log(avatarUrl);
                  app.globalData.openid = res.result.openid
                  var openId = res.result.openid;//用户openId
                  var userColl = db.collection('sys-user');
                  //根据openId获取用户
                  userColl.where({ openId: openId}).get({
                      success:res=>{
                           if(res.data.length>0){//存在
                                wx.navigateTo({
                                     url: '/pintu/game/game?user_id=' + res.data[0]._id + "&userInfo=" + JSON.stringify(this.data.userInfo) ,
                                })
                           }else{//不存在
                                if (this.data.userInfo == '') {
                                     wx.showModal({
                                          title: '提示',
                                          content: '请先获取头像信息!',
                                          showCancel: false,
                                     })
                                     return;
                                }
                                userColl.add({
                                     data: { openId: openId, nick: this.data.userInfo.nickName, flag: 2, avatarUrl: avatarUrl, nickName: this.data.userInfo.nickName},
                                     success:res=>{
                                          var id = res._id;//用户id
                                          
                                          //在用户游戏等级表中加入记录
                                           var userTh = db.collection("sys-user-through");//用户拼图等级记录表
                                           userTh.add({
                                                data: { wait_pass: '1-1', was_pic: '', f_grade: '1', c_grade: '1', total_score: 0, user_id: id, avatarUrl: avatarUrl, nickName: this.data.userInfo.nickName,userTitle:'倔强青铜III'},
                                                success:res=>{
                                                    wx.navigateTo({
                                                         url: '/pintu/game/game?user_id=' + id + "&userInfo=" + JSON.stringify(this.data.userInfo) ,
                                                    })
                                                },fail:res=>{
                                                     wx.showModal({
                                                          title: '提示',
                                                          content: '系统错误!',
                                                          showCancel:false,
                                                     })
                                                }
                                           });
                                     },fail:res=>{
                                          wx.showModal({
                                               title: '提示',
                                               content: '用户登录失败!',
                                               showCancel:false,
                                          })
                                     }
                                });
                           }
                      }
                 });   
             },
             fail: err => {
                 wx.showModal({
                      title: '提示',
                      content: '获取唯一识别失败!',
                      showCancel:false,
                 })
             }
        });  
     },

     /**
      * 获取用户基本信息
      */
     getUserAvatar:function(){
          this.getUserMes();
     },

     /**
      * 执行获取用户头像
      */
     getUserMes:function(){
          // 获取用户信息
          wx.getSetting({
               success: res => {
                    if (res.authSetting['scope.userInfo']) {
                         // 已经授权,可以直接调用 getUserInfo 获取头像昵称,不会弹框
                         wx.getUserInfo({
                              success: res => {
                                   this.setData({
                                        avatarUrl: res.userInfo.avatarUrl,
                                        userInfo: res.userInfo
                                   })
                              },
                              fail:res=>{
                                   wx.showModal({
                                        title: "提示",
                                        content: '获取失败!',
                                        showCancel:false,
                                   })
                              }
                         })
                    }
               }
          })
     },

     /**
      * 跳转到文件上传
      */
     goUploadFile:function(){
          
          wx.navigateTo({
               url: '/pintu/upload/upload',
          })
     },
     /**
      * 生命周期函数--监听页面初次渲染完成
      */
     onReady: function () {

     },

     /**
      * 生命周期函数--监听页面显示
      */
     onShow: function () {

     },

     /**
      * 生命周期函数--监听页面隐藏
      */
     onHide: function () {

     },

     /**
      * 生命周期函数--监听页面卸载
      */
     onUnload: function () {

     },

     /**
      * 页面相关事件处理函数--监听用户下拉动作
      */
     onPullDownRefresh: function () {

     },

     /**
      * 页面上拉触底事件的处理函数
      */
     onReachBottom: function () {

     },

     /**
      * 用户点击右上角分享
      */
     onShareAppMessage: function () {

     }
})

3.登陆xss

/* miniprogram/pintu/login/login.wxss */
.uh{

     width:100%;
     text-align: center;
     display: flex;
     flex-direction: row;
     justify-content: center;
}
.uh-i{
     position: relative;
     font-size: 14px;
     margin-top:50px;
     width:100px;
     height:100px;
     
     border-radius: 50px;
     overflow: hidden;
}
image{
     width:100px;
     height:100px;
     border-radius: 50px;
}
.uh-ib{
     border:4px solid #FFD700;
     line-height: 100px; text-align: center;background-color: rgba(220, 236, 174, 0.5); color:#ADADAD;
}

.login{
     margin-top:50px;
     color:#ADADAD;
     display: flex;
     flex-direction: column;
     
     text-align: center;
     width:100%;
     font-size: 14px;
}

.login-btn{
     color:black;
     width:100px;
     height:40px;
     line-height: 40px;
     text-align: center;
     font-weight: bolder;
     background-color: #FFD700;
     border-radius: 5px;
      box-shadow:0px 0px 5px #ADADAD;
      letter-spacing: 1px;
}

二、游戏页面

1.xml

<!--miniprogram/pintu/game/game.wxml-->
<!-- <image style='width:300px;height:300px;' src='cloud://pro-egh5a.7072-pro-egh5a/1/1/0.png'></image> -->
<view class='user_mes'>
     
     <view class='item'>
          <image src='{{userInfo.avatarUrl}}' class='ava'></image>
          <view class='item-t'>{{userInfo.nickName}}</view>
     </view>
     <view class='item'>
          <image class='level' src='/images/level.png'></image>
          <view class='item-t item-t-l'>{{userTitle}}</view>
     </view>
</view>
<view class="tips">(点击图片与空白区,相邻即可交换位置)</view>
<view class='show' wx:if="{{pass==0}}">
     <view class='show_img' style='height:{{showImgHeight}}px;width:{{showImgWidth}}px'>
          <view style="height:{{height}}px;width:{{width}}px" wx:for="{{chList}}" wx:key=""  bindtap='selectThis' >
          <!-- 图片 -->
              <image class="{{index==imgIndex?'imgBorder':''}}" wx:if="{{item.filePath!=''&&item.filePath!=1}}" src='{{item.filePath}}' style="height:{{height}}px;width:{{width}}px;" data-index="{{index}}" data-mark="1"></image>
              <!-- 填充区 -->
              <!-- <view wx:if="{{item.filePath==''&&item.filePath!=1}}" style='height:{{height}}px;width:{{width}}px;'></view> -->
              <!-- 空格 -->
              <view class="{{index==fillIndex?'imgBorder':''}}" wx:if="{{item.filePath!=''&&item.filePath==1}}" style='height:{{height}}px;width:{{width}}px;background-color: #fff' data-index="{{index}}" data-mark='2'></view>
          </view>
     </view>
</view>
<view class='pass' wx:if="{{pass==1}}">
     <view class='p-item'>
          <view class='pass-1'>恭喜,您已通关!</view>
     </view>
     <view  class='p-item'>
          <view class='pass-2' bindtap='lookRanking'>排行榜</view>
     </view> 
</view>
<view class='bot' wx:if="{{pass==0}}">
     <view class='bot-item bot-item-l' bindtap='lookOriPic'>原图</view>
     <view class='bot-item bot-item-r' bindtap='lookRanking'>排行榜</view>
</view>

2.js

// miniprogram/pintu/game/game.js
const db = wx.cloud.database({ env: "pro-egh5a" });
var app = getApp();
Page({

     /**
      * 页面的初始数据
      */
     data: {
          imgIndex: -1,
          fillIndex: -1,
          pass:0,
          border: '1px solid black;',
          user_id: '',
          userInfo: '',
          father_pic: '',//当前正在玩的图片的父级
          chList: '',
          height: '',
          width: '',
          showImgHeight: 0,
          wait_pass:'',
          chListLength:0,
          throughId:'',
          score:0,
          userTitle:'',
          userTitles:[
               { lscore: 0, mscore: 20, title: '倔强青铜III' },
               { lscore: 21, mscore: 40, title: '倔强青铜II'},
               { lscore: 41, mscore: 60, title: '倔强青铜I' }, 
               { lscore: 61, mscore: 100, title: '秩序白银III' },
               { lscore: 101, mscore: 140, title: '秩序白银II' }, 
               { lscore: 141, mscore: 180, title: '秩序白银I' },
               { lscore: 181, mscore: 220, title: '荣耀黄金IV' },               
               { lscore: 221, mscore: 260, title: '荣耀黄金III' },
               { lscore: 261, mscore: 300, title: '荣耀黄金II' },
               { lscore: 301, mscore: 340, title: '荣耀黄金I' },
               { lscore: 341, mscore: 400, title: '尊贵铂金IV' },
               { lscore: 401, mscore: 460, title: '尊贵铂金III' },
               { lscore: 461, mscore: 520, title: '尊贵铂金II' },
               { lscore: 521, mscore: 580, title: '尊贵铂金I' },
               { lscore: 581, mscore: 640, title: '永恒钻石V' },
               { lscore: 641, mscore: 700, title: '永恒钻石IV' },
               { lscore: 701, mscore: 760, title: '永恒钻石III' },
               { lscore: 761, mscore: 820, title: '永恒钻石II' },
               { lscore: 821, mscore: 880, title: '永恒钻石I' },
               { lscore: 881, mscore: 940, title: '至尊星耀V' },
               { lscore: 941, mscore: 1000, title: '至尊星耀IV' },
               { lscore: 1001, mscore: 1060, title: '至尊星耀III' },
               { lscore: 1061, mscore: 1120, title: '至尊星耀II' },
               { lscore: 1121, mscore: 1180, title: '至尊星耀I' },
               { lscore: 1181, mscore: 1500, title: '最强王者' },
               { lscore: 1501, mscore: 99999, title: '荣耀王者' },
               ],
     },

     /**
      * 生命周期函数--监听页面加载
      */
     onLoad: function (options) {


         
          var user_id = options.user_id;
          this.setData({
               user_id: user_id,
               userInfo: JSON.parse(options.userInfo)
          });
          this.getUserThroughMes();
     },
     /**
      * 生命周期函数--监听页面显示
      */
     onShow: function () {
         
     },
     /**
      * 获取用户等级信息
      */
     getUserThroughMes: function () {
          var user_id = this.data.user_id;
          db.collection('sys-user-through').where({ user_id: user_id }).get().then(res => {
               var mes = res.data[0];

               this.setData({
                    throughId:mes._id,
                    wait_pass: mes.wait_pass,
                    score: mes.total_score*1,
                    userTitle:mes.userTitle
               });
               var fG = mes.wait_pass.split("-")[0];
               var cG = mes.wait_pass.split("-")[1];

               db.collection("sys-pic-father").where({ grade: fG }).count().then(res => {
                           
                    if (cG == res.total && fG==2){
                        this.setData({
                             pass:1
                        });
                    }else{
                         this.getFatherPicMes(mes.wait_pass);//根据用户图片等级查询父级图片 
                    }
                              
               });

               
          });
     },

     /**
      * 根据用户图片等级查询父级图片
      */
     getFatherPicMes:function(wait_pass){
          wx.showLoading({
               title: '加载中···',
          })
          var grads = wait_pass.split("-");
          db.collection("sys-pic-father").where({
               grade: grads[0], grade_childe: grads[1]
          }).get().then(res => {
               wx.hideLoading();
 
               this.setData({
                    father_pic: res.data[0].filePath
               });
               var fId = res.data[0]._id;

               this.getPicsByFid(fId);//根据父级Id查询图片组
          });
     },
     /**
      * 根据父级Id查询图片组
      */
     getPicsByFid: function (fId) {
          db.collection("sys-pic-child").where({ fId: fId }).field({ filePath: true }).get().then(res => {
            
               var list = res.data;
               var listLength = list.length;
               var indexArr = [];
               for (var i = 0; i < listLength;i++){
                    var serial = list[i].filePath.split(".pn")[0].split("/").pop();
                    indexArr.push(serial);
               }
               var inLength = indexArr.length;
               var max;
               if (inLength%3==0){
                    max=9;
               }
               if (inLength % 4 == 0) { 
                    max=16;
               }
               var popIndex = '';
               for (var a = 0; a < inLength; a++) {
                    if (indexArr[a]==max){
                         popIndex=a;
                    }
               }

               res.data.splice(popIndex, 1) ;//去掉最后一个

               var chList = res.data;
            
               //宽高设置
               var width = 0;
               var height = 0;
               var showImgWidth= 0;
               var showImgHeight=0;
               //打乱数组           
               chList = this.upsetArr(chList);
               chList = chList.concat([{ filePath: '1' }])
             
               //数组长度 
               var chLength = chList.length;
               
               //添加空格
               if (chLength % 3 == 0) {
                    width = (300 / chLength) * 3;
                    height = (300 / chLength) * 3;
                    showImgWidth = 300+2*3;
                    showImgHeight = 300 + 2 * 3 ;

               } else if (chLength % 4 == 0) {

                    width = (300 / chLength) * 4;
                    height = (300 / chLength) * 4;
                    showImgWidth = 300 + 2 * 4;
                    showImgHeight = 300 + 2 * 4 ; 

               }
               
             
               this.setData({
                    chListLength: chLength,
                    chList: chList,
                    height: height,
                    width: width,
                    showImgWidth: showImgWidth,
                    showImgHeight: showImgHeight,
               });
          });
     },
     

     /**
      * 打乱数组
      */
     upsetArr:function(chList){
          //打乱数组
          let i = chList.length;
          while (i) {
               let j = Math.floor(Math.random() * i--);
               [chList[j], chList[i]] = [chList[i], chList[j]];
          }
          //打乱后图片顺序cloud://pro-egh5a.7072-pro-egh5a-1259354038/1/1/4.png
          var aUpset = [];
          var length = chList.length;
          for (var a = 0; a < length; a++) {
               var serial = chList[a].filePath.split(".pn")[0].split("/").pop();
               aUpset.push(serial)
          }
          
          //验证打乱是否成功?
          var bool = this.isContinuityArray(aUpset);
          if (bool){
               this.upsetArr(chList);

          }
          return chList;
     },

     /**
      * 判断数组是否是递增数组
      */
     isContinuityArray:function(arrStr) {
          var isContinuityArray = false;
          var array = arrStr;
          var arrayCount = array.length - 1;
          for(var i = 0; i<arrayCount; i++) {
               var currentArr = Number(array[i]) + 1;
               var nestArr = Number(array[i + 1]);
               if (i + 1 == arrayCount) {
                    currentArr = Number(array[i]);
                    nestArr = Number(array[i]);
               }
               if (currentArr != nestArr) {
                    isContinuityArray = false;
                    break;
               } else {
                    isContinuityArray = true;
               }
          }
          return isContinuityArray;
     },

     /**
      * 选择图片或者空格
      */
     selectThis: function (e) {
          var index = e.target.dataset.index;
          var mark = e.target.dataset.mark;
          var chList = this.data.chList;
          if (mark == 1) {
               this.setData({
                    imgIndex: index
               });
          } else if (mark == 2) {
               this.setData({
                    fillIndex: index
               });
          }
          this.gameCore();
     },

     /**
      * 判断选择的图片与空白区是否相邻,如果相邻就交换位置,并获取新的图片数组顺序,如果顺序为有序递增,则通过
      */
     gameCore:function(){
          var imgIndex = this.data.imgIndex;
          var fillIndex = this.data.fillIndex;
          var chListLength = this.data.chListLength;

          //保证必须相邻
          var numI = imgIndex+1;
          var numF = fillIndex+1;
          var jude = false;
          if (chListLength % 3 == 0) { 
               var num = Math.abs(numF - numI);
               if (num==1||num==3){
                    jude=true;
               }
          } else if (chListLength % 4 == 0){
               var num = Math.abs(numF - numI);
               if (num == 1 || num == 4) {
                    jude = true;
               }
          }

          if (imgIndex != -1 && fillIndex != -1 && jude){//两者都已选取
               // [array[index1],array[index2]] = [array[index2],array[index1]];
               var chList = this.data.chList;
               [chList[imgIndex], chList[fillIndex]] = [chList[fillIndex], chList[imgIndex]];
               this.setData({
                    chList: chList,
                    imgIndex:-1,
                    fillIndex:-1
               });
               var aUpset = [];
               var length = chList.length;
               for (var a = 0; a <length; a++) {
                    var serial = chList[a].filePath.split(".pn")[0].split("/").pop();
                    aUpset.push(serial)
               }
               
               // aUpset = ["1", "2", "3", "4", "5", "6", "7", "8", "1"];
               aUpset = aUpset.slice(0, aUpset.length - 1);

               // aUpset = [1,2,3];
               //验证顺序是否成功
               var bool = this.isContinuityArray(aUpset);
              
               if(bool){
                    console.log("拼图成功******累计积分");
                    var nowScore=0;
                    if (chListLength % 3 == 0) {
                         nowScore = this.data.score + 40;
                    } else if (chListLength%4==0){
                         nowScore = this.data.score + 60;
                    }
                    //获取用户当前称号
                    var title = this.getUserTitleByScore(nowScore);

                    var waitPass = this.data.wait_pass;
                    var fG = waitPass.split("-")[0];
                    var cG = waitPass.split("-")[1];
                        
                    db.collection("sys-pic-father").where({ grade: fG}).count().then(res=>{
                         if(cG == res.total){//最后一张
                              if (fG<2){
                                   fG = fG*1 + 1;
                                   cG=1;
                              }else{
                                   wx.showModal({
                                        title: '提示',
                                        content: '恭喜!通关!',
                                        showCancel:false,
                                   })
                                   this.setData({
                                        pass: 1
                                   });
                                   return;
                              }
                              
                         } else if (cG < res.total){
                              cG = cG*1+1;
                              if (fG == 2 && (cG ==12||cG==14)){
                                   cG = cG * 1 + 1;
                              }
                              
                         }

                         var newWaitPass = fG + '-' + cG;
                         
                         //修改数据库
                         db.collection("sys-user-through").doc(this.data.throughId).update({ data: { total_score: nowScore, wait_pass: newWaitPass, userTitle: title } }).then(res => {
                              
                              this.setData({
                                   score: nowScore,
                                   wait_pass: newWaitPass,
                                   userTitle: title
                              });
                              wx.showModal({
                                   title: '恭喜',
                                   content: '恭喜您,拼图成功!',
                                   showCancel:false,
                                   success:res=>{
                                        if(res.confirm){
                                             //换图片
                                             this.getFatherPicMes(newWaitPass);
                                        }
                                   }
                              })
                              
                         });         
                    });
               }
          }
     },

          
     /**
      * 根据用户积分获取称号
      */
     getUserTitleByScore:function(score){

          var userTitles = this.data.userTitles;
          var title;
          var tLength = userTitles.length;
          for (var i = 0; i < tLength;i++){
               if (score<=userTitles[i].mscore){
                  
                    title = userTitles[i].title;
                    break;
               }
          }

          return title;
     },
     /**
      * 查看原图
      */
     lookOriPic:function(){
          wx.previewImage({
               current: this.data.father_pic, // 当前显示图片的http链接
               urls: [this.data.father_pic] ,// 需要预览的图片http链接列表
               success:res=>{

               }
          })
     },

     /**
      * 查看排名
      */
     lookRanking:function(){
          wx.navigateTo({
               url: '/pintu/ranking/ranking',
          })
     },
     /**
      * 生命周期函数--监听页面初次渲染完成
      */
     onReady: function () {

     },



     /**
      * 生命周期函数--监听页面隐藏
      */
     onHide: function () {

     },

     /**
      * 生命周期函数--监听页面卸载
      */
     onUnload: function () {

     },

     /**
      * 页面相关事件处理函数--监听用户下拉动作
      */
     onPullDownRefresh: function () {

     },

     /**
      * 页面上拉触底事件的处理函数
      */
     onReachBottom: function () {

     },

     /**
      * 用户点击右上角分享
      */
     onShareAppMessage: function () {

     }
})

3.xss

/* miniprogram/pintu/game/game.wxss */


/* 用户信息 */
.user_mes{
     margin-top:5px;
     width:100%;
     height: 50px;
     line-height: 50px;
     display: flex;
     flex-direction: row;
     justify-content: space-between;
     font-size: 14px;
     color:#FFD700;
}
.item{
     display: flex;
     flex-direction: row
}
.ava{
     margin-left: 5px;
     height:50px;
     width:50px;
     border-radius: 25px;
}

.level{
     margin-top: 8px;
     height:32px;
     width:32px;
}

.item-t{
     margin-left: 10px;
}

.item-t-l{
     margin-right:5px;
}
/* tips */
.tips{
     font-size: 14px;
     color: #A8A8A8;
}
/* 图片操作 */
.show{
     margin-top: 10px;
     width:100%;
     display:flex; flex-direction:row;justify-content:center;
}

.show_img{
     box-shadow:0px 0px 5px #ADADAD;
     border:1px solid #FFD700;
     display: flex;
     flex-flow: row wrap;
     justify-content: space-between;
     background-color: #FFD700;
}
.imgBorder{
     border:1px dashed #ADADAD;
}

.bot{
     width:100%;
     margin-top:10px;
     display: flex;
     flex-direction: row;
     justify-content: space-between;
     font-size: 14px;
}

.bot-item{
     width:80px;
     height:35px;
     line-height: 35px;
     text-align: center;
     background-color: #FFD700;
     color:#ffff;
     border-radius: 5px;
}
.bot-item-l{
     margin-left: 5px;
}

.bot-item-r{
     margin-right: 5px;
}

.pass{
     display: flex;
     width: 100%;
     flex-direction: column;
     justify-content: center;
}
.p-item{
     margin-top: 40px;
      display: flex;
     width: 100%;
     flex-direction: row;
     justify-content: center;
}

.pass-1{

     font-size: 20px;
     color:#FFC125;
     font-weight: bolder;

}

.pass-2{
     width:80px;
     height:35px;
     font-size: 14px;
     line-height: 35px;
     text-align: center;
     background-color: #FFD700;
     color:#ffff;
     border-radius: 5px;
}

各位大哥,核心代码就在上面了。如有疑问请留言,小编会第一时间回复,谢谢,再次麻烦扫一下二维码,进入游戏玩一下,可以体验,有小广告帮忙点一下,谢谢!!!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值