微信小程序-实战巩固(二)

刚刚写了小程序入门没几天,小程序就开放个人开发者资格,感觉为我而来啊 \(≧▽≦)/。迫不及待的去注册,准备将之前的处女作传上去体验一把,结果卡在了服务器配置上:免费的果然不靠谱/(ㄒoㄒ)/~~,后来尝试用个人服务器转发代理请求,发现不支持http,必须https!必须https!必须https!

好不容易做的项目不能上线,感觉心被掏空了,这种憋屈大家懂得~,于是不甘寂寞的我,准备做个不需要请求的单机版,就是这么机智(*^__^*) 嘻嘻……文末高能,慎入~

接下来我们开始动手吧,之前做过类似连连看,这次准备尝试做个小程序扫雷,来个最终效果图,先睹为快吧

因为有了上一节入门基础,这一节就讲的快一点,如果有什么不太理解的,可以去看我的上一篇文章《微信小程序-开发入门(一)》

一、初始化项目

主要包括:设置app.js、app.json和app.wxss三个文件,建立pages文件结构

//app.js,将游戏配置文件放在APP中,可实现跨页之间共享
App({
  row:12,//扫雷游戏的行数
  column:8,//扫雷游戏的列数
  bomb:8//包含雷的总数
})

二、游戏页面逻辑

重点在首页游戏逻辑的处理,因为小程序以数据为驱动,无法操作dom,所以很多实现最终要落实到数据上,查看如下index.js

//index.js
Page({
  data: {
    dialog_warn:false,//通过修改此数据值,改变弹框的显示状态
    dialog_suc:false, //游戏成功,设为true,视图层通过wx:if来判断是否渲染该弹窗
    count:null,//翻牌计数,初始值为app.row*app.column
    gamearr:[]//游戏地图的基础数据(二维数组),根据此来生成游戏
  }
})
<!--index.wxml-->
<view class="dialog warn" wx:if="{{dialog_warn}}">
  <icon type="warn" size="60" color="orange"></icon>
  <text>Game Over</text>
  <button bindtap="reset">重新开始</button>
</view>
<view class="dialog success" wx:if="{{dialog_suc}}">
  <icon type="success" size="60" color="green"></icon>
  <text>Success~</text>
  <button bindtap="reset">重新开始</button>
</view>

根据app.js中的数据,生成游戏地图数据:gamearr

setgamearr:function(row,column,bomb){//根据行列设置游戏二维数组(地图)
    var that=this;
    var arrmap=[];//二维初始数组,全为空
    for(var i=row-1;i>=0;i--){
      arrmap[i]=[];
      for(var j=column-1;j>=0;j--){arrmap[i][j]={val:"",cover:true};}//val用来记录周边雷的数量,cover用来记录是否翻开:无dom操作只能用数据记录状态
    }
    var arr=[];//一维自然数
    for(var k=row*column-1;k>=0;k--){arr[k]=k}
    //随机炸弹位置
    for(var h=bomb-1;h>=0;h--){
      var seat=arr.splice(Math.floor(Math.random()*arr.length),1)[0]
      var r=Math.floor(seat/column),c=Math.floor(seat%column);
      //console.log(seat+'\n'+r+","+c);
      arrmap[r][c].val="B";
      arrmap=that.addcount(r,c,arrmap)//给炸弹周围九宫格增加标记数
    }
    that.setData({gamearr:arrmap})
  },

给炸弹周围九宫格增加标记数

addcount:function(r,c,arrmap){
    var that=this;
    if(r-1>=0){//九宫格上三个
        if(c-1>=0 && arrmap[r-1][c-1].val!="B"){arrmap[r-1][c-1].val++}
        if(arrmap[r-1][c].val!="B"){arrmap[r-1][c].val++}
        if(c+1<app.column && arrmap[r-1][c+1].val!="B"){arrmap[r-1][c+1].val++}
      }
      if(r+1<app.row){//九宫格下三个
        if(c-1>=0 && arrmap[r+1][c-1].val!="B"){arrmap[r+1][c-1].val++}
        if(arrmap[r+1][c].val!="B"){arrmap[r+1][c].val++}
        if(c+1<app.column && arrmap[r+1][c+1].val!="B"){arrmap[r+1][c+1].val++}
      }
      //九宫格左右两个
      if(c-1>=0 && arrmap[r][c-1].val!="B"){arrmap[r][c-1].val++}
      if(c+1<app.column && arrmap[r][c+1].val!="B"){arrmap[r][c+1].val++}
      return arrmap;
  }

生成数据后,根据数据生成页面视图

<view class="game">
    <view class="tr" wx:for="{{gamearr}}" wx:for-index="row" wx:for-item="itemrow"><!--根据数据遍历行-->
      <view class="td" wx:for="{{itemrow}}" wx:for-index="column" wx:for-item="itemcolumn" data-row="{{row}}" data-column="{{column}}"  bindtap="taphandler">
        <view class="mask" wx:if="{{itemcolumn.cover}}"></view><!--遮罩层,无法用伪元素before来更改状态,只能数据来判断了-->
        <text wx:if="{{itemcolumn.val==''}}">{{itemcolumn.val}}</text><!--根据数值显示不同样式,如果是web能用jquery选择器就简单多了,这里略显复杂-->
        <text class="color1" wx:elif="{{itemcolumn.val==1}}">{{itemcolumn.val}}</text>
        <text class="color2" wx:elif="{{itemcolumn.val==2}}">{{itemcolumn.val}}</text>
        <text class="color3" wx:else>{{itemcolumn.val}}</text>
      </view>
    </view>
</view>

游戏控制部分,单元格tap事件

//游戏控制部分
  taphandler:function(e){
    var that=this;
    var r=e.currentTarget.dataset.row,c=e.currentTarget.dataset.column;//无法想jquery获得index,只能用数据记录,直接获取喽
    if(that.data.gamearr[r][c].val!="B"){//如果没点到炸弹
      that.data.gamearr[r][c].cover=false;
      that.data.count--;
      that.setData({count:that.data.count})
      if(that.data.count==app.bomb){that.setData({dialog_suc:true})}//当剩余单元格计数等于雷数,游戏胜利
      if(that.data.gamearr[r][c].val==""){//如果点到的是空,将它周围的四个打开
        that.data.gamearr=that.show4(r,c,that.data.gamearr)
        // that.data.gamearr=that.show9(r,c,that.data.gamearr)//原先考虑九点,结果递归直接栈溢出了,(⊙﹏⊙)b
      }
      console.log(that.data.count)
    }else{that.setData({dialog_warn:true})}//点到了雷,游戏结束
    that.setData({gamearr:that.data.gamearr})
  }

如果点击为空,将它周围四个翻牌,并进行递归操作

show4:function(r,c,arrmap){//显示周边的4点
    var that=this;
    if(r-1>=0 && arrmap[r-1][c].val==""){//上
        if(arrmap[r-1][c].cover){
          arrmap[r-1][c].cover=false;that.data.count--;that.setData({count:that.data.count})
          that.show4(r-1,c,arrmap)//递归
        }
      }
      if(r+1<app.row && arrmap[r+1][c].val==""){//下
        if(arrmap[r+1][c].cover){
          arrmap[r+1][c].cover=false;that.data.count--;that.setData({count:that.data.count})
          that.show4(r+1,c,arrmap)//递归
        }
      }
      if(c-1>=0 && arrmap[r][c-1].val==""){//左
        if(arrmap[r][c-1].cover){
        arrmap[r][c-1].cover=false;that.data.count--;that.setData({count:that.data.count})
        that.show4(r,c-1,arrmap)//递归
      }}
      if(c+1<app.column && arrmap[r][c+1].val==""){//右
        if(arrmap[r][c+1].cover){
        arrmap[r][c+1].cover=false;that.data.count--;that.setData({count:that.data.count})
        that.show4(r,c+1,arrmap)//递归
      }}
      return arrmap;
  }

三、游戏设置

游戏设置就相对简单了,直接读取app.js的数据为设置页的数据,操作修改则修改app数据,然后切换回游戏页面onshow获取更新后的数据重新生成游戏

// pages/set/set.js
var app = getApp();
Page({
  data:{
    row:app.row,
    column:app.column,
    bomb:app.bomb
  },//游戏设置部分,修改设置将重新生成游戏
  rowChange:function(e){app.row=e.detail.value;},
  columnChange:function(e){app.column=e.detail.value;},
  bombChange:function(e){app.bomb=e.detail.value;}
})

四、总结

做完了发布上传的时候才发现,小程序的分类里面没有游戏,更多的是工具应用类,不知道小程序以后会不会放开服务类目,拭目以待吧~

项目源文件:https://github.com/gavin125/wx_game

上传小程序审核等了一天,结果不通过详情如下,(⊙o⊙)…我想一个人静静…

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏aCloudDeveloper

百练OJ 1017 2801

一、1017填箱子      这个题题目读起来有些晦涩,如果按题目给的条件很难找到突破口,需要事先计算一下每种CP(产品)在没装满的情况下还需要的其他CP数。(...

16610
来自专栏逍遥剑客的游戏开发

星际2中复刻DOTA白虎

1532
来自专栏iOS Developer

iOS开发之多国语言国际化适配经验浅谈

1223
来自专栏带你撸出一手好代码

把需求变化带来的代码修改成本降至最低的一种方法

为解决工作中一些繁琐的问题, 写了一个GUI程序, 操作界面是这个样子的 ? 这个程序的实现起来并不是非常的繁琐, 但在界面的交互操作上, 也不仅仅只是展示数据...

3247
来自专栏tkokof 的技术,小趣及杂念

随便聊聊水面效果的2D实现(一)

  一直想随便写写自己关于水面效果2D实现的一些了解,可惜各种原因一直拖沓,幸而近来有些事情终算告一段落,自己也有了一些闲暇时间,于是便有了这篇东西 :)

1034
来自专栏腾讯IVWEB团队的专栏

[译]Top JavaScript Frameworks & Topics to Learn in 2017

JavaScript 的普及导致了一个非常活跃的技术,框架和类库的生态系统。 随着这充满令人惊叹的多样性和能量的生态圈的到来,许多人的烦恼也变得越来越多。

940
来自专栏信安之路

Clickjacking简单介绍

今天没有原创文章发了,从乌云知识库里选了一个文章给大家分享一下,不知道这种方式,大家是否能够接我从乌云知识库里选择一些文章给大家分享,请大家给我提出来,我来根据...

560
来自专栏腾讯Bugly的专栏

【沙龙干货分享】你要知道的N个Android适配问题

2015年8月29日下午,腾讯Bulgy移动开发者沙龙第三期在车库咖啡与大家如约相见。本期,我们分享的主题是安卓应用机型适配之痛。适配性问题作为安卓开发者中的老...

2646
来自专栏张戈的专栏

另类SEO分享:利用JS封装iframe躲过搜索引擎的抓取

前言:很多博友不仔细看完内容就直接认为用 iframe 不好之类的云云,而实际上本文就是教你在必须使用 iframe 的时候,该如何躲过搜索引擎的抓取,避免不利...

4146
来自专栏企鹅号快讯

技术分享连载|UGUI对于emoji表情的处理|加载资源时的内存波动|Animator采样……

我们将从日常技术交流中精选若干个开发相关的问题,建议阅读时间15分钟,认真读完必有收获。如果您有任何独到的见解或者发现也欢迎联系我们,一起探讨。 内存管理 Q:...

2606

扫码关注云+社区