一、新建一个quick start项目看看结构

在微信开发工具点击添加项目,选择 无appid,勾上"在当前目录中创建quick start 项目"。
可以看到一共有两个目录 pages和utils,和根目录下的3个app文件。pages存放的是小程序的页面,每个也面都有自己独立的文件夹。 一个页面由4文件构成,js文件是程序逻辑;wxss是微信定义的样式文件,语法跟css一样,支持的样式要少一些;wxml文件用来定义小程序的界面,作用类似于html,但是只能用微信自定义的一些标签,而且页面元素不能直接用js操作,只能通过绑定数据来修改;json是页面的配置文件一般用不着。根目录下的app.js,app.json,app.wxml作用和pages下面的作用类似,只不过pages下面的是页面级的,根目录下的是成个应用级的>。utils下面定义了一个转换时间格式工具函数,然后通过module.exports将函数暴露出去,再在logs.js中通过require引入。

二、改造index页面

知道了小程序的结构就可以动手开始做了,首先把index页面改造一下,把用户头像上的点击事件去掉,然后再新增两个按钮,用来跳转到游戏主界面和游戏成绩界面。
1.界面,bindtap相当于html的onclick
<!--index.wxml-->
<view class="container"><view  class="userinfo"><text class="userinfo-nickname"></text><image class="userinfo-avatar" src="{{userInfo.avatarUrl}}" background-size="cover"></image><text class="userinfo-nickname">{{userInfo.nickName}}</text><text class="userinfo-nickname">你好</text></view><view class="usermotto"  ><text class="user-motto" bindtap="startGame">{{motto}}</text></view><view style="margin-top:30rpx; "><text class="user-motto"  bindtap="viewScore" >查看排名</text></view>
</view>

2.index.js 文件的Page中增加两个处理点击事件的函数,用wx.navigateTo来跳转的目标页

//index.js
//获取应用实例
var app = getApp()
Page({data: {motto: '开始游戏',userInfo: {},welcome:'你好'},//事件处理函数startGame: function() {wx.navigateTo({url: '../game/game'})},viewScore: function() {wx.navigateTo({url: '../logs/logs'})},onLoad: function () {console.log('onLoad')var that = this//调用应用实例的方法获取全局数据app.getUserInfo(function(userInfo){//更新数据that.setData({userInfo:userInfo})})}
})
3.index.wxss中增加游戏背景图
page{background: url('../images/gamebg.jpg') center top; }
在pages下新建一个images目录存照片
图片下载地址
http://pan.baidu.com/share/link?shareid=1434710849&uk=3758963053

三、游戏主界面和逻辑

在pages目录下新建一个game目录,然后再照着index页面新建game.js、game.json、game.wxml、game.wxss4个文件。
然后在app.json中增加game页的配置,顺便改下游戏标题.
{"pages":["pages/index/index","pages/logs/logs","pages/game/game" ],"window":{"backgroundTextStyle":"light","navigationBarBackgroundColor":"white","navigationBarTitleText": "微信翻牌小程序","navigationBarTextStyle":"black"}
}
1.game.js 游戏的逻辑
游戏的界面元素不能直接用js操作,只能用page的setData方法通过重新绑定数据来修改.界面上要用的变量都要定义在page的data中,界面有变化时必须要通过this.setData方法修改变量的值,直接修改变量界面不会变.
  data: {clickNum:0,      // 点击次数useTime:0,       // 游戏时间  checked:0,       // 已匹配牌数allCard:allCard,    // 全部卡牌数组backImage:backCardImage, // 牌背面 图片地址modalHidden: true,    // 游戏完成提示是否显示firstX:-1,        // 点击的第一张卡牌的坐标 firstY:-1,cards:[],        // 随机挑选出来的牌   size:8 ,        // 界面显示的牌数=size*2clickable:false,    // 当前是否可点击timer:''        // 游戏计时的定时器}

游戏初始化时随机从牌堆中挑出一些,打乱显示在界面上几秒,然后翻回去游戏正式开始.

  startGame:function(){  // 开始游戏var data = this.data;var that = this;console.log('startGame');var tmp = this.data.allCard.sort(function(a,b){ return Math.random()>.5 ? -1 : 1;}).splice(0,Math.floor(data.size)); // 打乱牌堆,挑出size/2张牌tmp = tmp.concat(tmp).sort(function(a,b){ return Math.random()>.5 ? -1 : 1;}); // 牌*2,再打乱// 添加图片src和卡牌翻转状态state,存在二维数组方便展示var cards = [];var ix = -1;   var iy = 0;for(var i in tmp){if( i%4 == 0){cards.push([]);ix++; iy = 0;}cards[ix].push({src:'../images/' +tmp[i]+ '.jpg',state:1   // 为1时显示图片,为0时显示牌背面});}this.data.cards = cards;this.setData({cards:cards,clickNum:0,useTime:0,checked:0,modalHidden:true,firstX:-1,clickable:false});var that = this;setTimeout(function(){that.turnAllBack();  // 所有的牌翻到背面console.log('turn all back');data.clickable = true;if(data.timer === ''){data.timer = setInterval(function(){data.useTime++;that.setData({useTime:data.useTime});},1000); // 游戏开始计时}else{that.setData({useTime:0});}},5000); // 游戏开始前先让玩家记忆几秒钟}

响应点击事件

onTap: function(event){var that = this;var data = this.data;var ix = event.currentTarget.dataset.ix; // 获取点击对象的坐标var iy = event.currentTarget.dataset.iy; console.log('onTap ' + ix + ' ' + iy);if(data.cards[ix][iy].state != 0 || !data.clickable)  // 点击的不是未翻过来的牌或者现在不让点直接passreturn;that.setData({clickNum:++data.clickNum}); //点击数加1   // 1. 检测是翻过来的第几张牌if(data.firstX == -1){// 1.1 第一张修改状态为 1data.cards[ix][iy].state = 1;data.firstX = ix; data.firstY = iy;  // 记下坐标that.setData({cards:data.cards});     // 通过setData让界面变化}else{// 1.2 前面已经有张牌翻过来了,先翻到正面然后看是不是一样data.cards[ix][iy].state = 1;that.setData({cards:data.cards});if(data.cards[data.firstX][data.firstY].src === data.cards[ix][iy].src){// 1.2.1.1 两张牌相同, 修改两张牌的state为2完成配对data.cards[data.firstX][data.firstY].state = 2;data.cards[ix][iy].state = 2;data.checked += 1; // 完成配对数++data.firstX = -1; // 准备下一轮匹配 // 1.2.1.2 检查是否所有牌都已经翻过来,都已翻过来提示游戏结束if(data.checked == data.size){ // 所有牌都配对成功了!this.setData({ modalHidden: false});     clearInterval(this.data.timer); // 暂停计时this.data.timer = '';this.saveScore({'time':data.useTime,'click':data.clickNum}) // 保存成绩}}else{  // 1.2.2 两张牌不同, 修改两张牌的state为 0data.cards[data.firstX][data.firstY].state = 0; data.cards[ix][iy].state = 0;data.firstX = -1;data.clickable = false;setTimeout(function(){that.setData({cards:data.cards,clickable:true});},500); //过半秒再翻回去}} console.log(this.data.cards);}

把所有牌翻到反面

turnAllBack:function(){for(var ix in  this.data.cards)for(var iy in this.data.cards[ix])this.data.cards[ix][iy].state = 0;this.setData({ cards:this.data.cards });}

游戏结束时,对游戏成绩进行排名然后通过wx.getStorageSync保存到本地

saveScore:function(score){ // 保存分数var maxscore = wx.getStorageSync('maxscore');if(maxscore == undefined || maxscore == '')maxscore = [];maxscore.push(score);maxscore = maxscore.sort(function(a,b){ if(a.time < b.time )return -1;else if( a.time == b.time && a.click < b.click)return -1;else return 1;});wx.setStorageSync( 'maxscore',maxscore);}

进入页面时记得调用startGame

  onLoad: function () {this.startGame();console.log(this.data.cards);}

2.界面布局

用view标签建立游戏的主界面
首先在顶部新建两个view 来显示时间和点击次数, 时间和点击次数是动态变化的所以要用两个大括号包住变量名这种格式
<view class="score"><view class="scoredetail"><view class="scoredesc">时间</view><view class="scorenumber">{{useTime}}</view></view><view class="scoredetail"><view class="scoredesc">点击次数</view><view class="scorenumber">{{clickNum}}</view></view>
</view>
然后是卡牌,游戏的卡牌保存在二维数组中,用view标签for方法把二维数组展开.for-index 是当前元素索引值, for-item表示当前元素的引用,.同时通过state的值来控制牌的display样式是none还是block
<view class=""><view class="board" ><view class="rows" wx:for="{{cards}}" wx:for-index="idx" wx:for-item="row"><view wx:for="{{row}}" class="cols"   wx:for-index="idy"  wx:for-item="card" ><view  class="" data-ix="{{idx}}"  data-iy="{{idy}}"  bindtap="onTap" ><image class="card" style="display:{{card.state == 0 ? 'none' : 'block'}}" mode="scaleToFill" src= "{{card.src}}" data-card="{{card}}"></image> <!--牌正面--><image class="card back" style="display:{{card.state != 0 ? 'none' : 'block'}}" mode="scaleToFill" src= "{{backImage}}" ></image> <!--牌背面--></view></view></view></view>
</view>

相当于 javascript的
for(row in cards){for(card in row){<image>...</image>
          <image>...</image>
 }}
最后用model标签来弹出游戏结束时的提示, hidden属性用来控制modal是否显示,bindconfirm是点击确认时调用的方法, bindcancel是点取消时的方法, 这里点取消时我们让游戏跳转到排名页.
<modal class="modal" hidden="{{modalHidden}}" bindconfirm="modalComfirm" bindcancel="modalCancle" cancelText="查看排名"><view> 游戏结束 ,重新开始吗? </view>
</modal>

在game.js中加两个响应函数


modalComfirm:function(){this.startGame();},
modalCancle:function(){this.setData({modalHidden: true,})wx.navigateTo({url: '../logs/logs'})}

3.样式文件


.score {display: flex;font-size: 1vh;
}.scoredetail{flex: 1;height: 150rpx;background:rgba(185, 65, 189, 0.8);/*opacity: 0.6; */margin: 50rpx 20rpx 40rpx 20rpx;text-align: center;border-radius: 11rpx;
}.scoredetail:last-child{margin-right: 40rpx;
}.scoredesc{font-size: 0.9rem;line-height: 50rpx;margin-top: 10rpx;color:yellow;
}
.scorenumber{line-height: 60rpx;font-size: 1.1rem;margin-top: 5rpx;color:yellow;
}.board{margin-left: 5rpx;margin-bottom: 5rpx;
}
.rows{margin-bottom:1rpx ;padding:0rpx;text-algin:center;flex-direction:row;display:flex;
}
.cols{margin: 5rpx;
}
.card{width:  175rpx;height: 237rpx;padding:1rpx;magrin: 2rpx;
}
page{background: url('../images/gamebg.jpg') center top; }

四、最后把logs页面改造成游戏成绩页


在进入log页时用wx.getStorageSync 读取之前保存在游戏成绩信息

//logs.js
Page({data: {logs: []},onLoad: function () {this.setData({logs: (wx.getStorageSync('maxscore') || [])})}
})

游戏成绩读取出来是一个已经排好序的数组, 所以直接用wx:for按顺序显示出来就行
<!--logs.wxml-->
<view class="container log-list"><text class="log-item">    用时  点击</text><block wx:for="{{logs}}" wx:for-item="log" wx:key="*this"><text class="log-item">{{index + 1}}. {{log.time}}秒 {{log.click}}次</text></block>
</view>

然后就大功告成啦

游戏完整代码

https://github.com/kwdhd/wxFpgame
开发时参考了这个版本

http://blog.csdn.net/fdipzone/article/details/8630427

微信小程序版翻牌游戏相关推荐

  1. php 翻牌,微信小程序版翻牌小游戏的实现

    这篇文章主要为大家详细介绍了微信小程序版翻牌小游戏,具有一定的参考价值,感兴趣的小伙伴们可以参考一下 本文实例为大家分享了微信小程序翻牌游戏的具体代码,供大家参考,具体内容如下 一.新建一个quick ...

  2. 适合编程初学者的开源项目:小游戏2048(微信小程序版)

    目标 为编程初学者打造入门学习项目,使用各种主流编程语言来实现. 2048游戏规则 一共16个单元格,初始时由2或者4构成. 1.手指向一个方向滑动,所有格子会向那个方向运动. 2.相同数字的两个格子 ...

  3. 用mpvue实现的微信小程序版cnode社区

    五一放假,没出去玩,想熟悉下vue的开发流程,又想体验下mpvue,于是写了个练手项目.一个用mpvue实现的cnode微信小程序版. 代码在仓库.欢迎各位star.fork.issue.pr.目前已 ...

  4. 微信小程序开发的游戏《拼图游戏》

    微信小程序开发的游戏<拼图游戏> 代码直接考进去就能用 pintu.js // pintu.js Page({/*** 页面的初始数据*/data: {},initGame: functi ...

  5. 微信小程序版博客——开发汇总总结(附源码)

    花了点时间陆陆续续,拼拼凑凑将我的小程序版博客搭建完了,这里做个简单的分享和总结. 整体效果 对于博客来说功能页面不是很多,且有些限制于后端服务(基于ghost博客提供的服务),相关样式可以参考截图或 ...

  6. 视频直播终端开发之微信小程序版

    前言 由于项目需要最近接到公司的一个研发任务,尝试开发视频直播功能,要求双方可以对讲互动,并提供微信小程序.PC.Web等版本.由于之前对流媒体技术有所积累,这个任务只要满足功能演示,因此这个任务对我 ...

  7. 开源leaflet地图组件的微信小程序版——leafletwx

    leafletwx开源地址:leafletwx leaflet库的微信小程序版(使用小程序原生组件view+image显示瓦片,并非web-view方式) leafletwx在leaflet的基础上开 ...

  8. 微信小程序版QQ音乐

    来源 <a href="http://www.see-source.com:80/weixinwidget/downloadZip.html?wid=161">实例源码 ...

  9. 微信小程序版个人博客及简历---面试加分

    WeChatMiniProgram-Blog 微信小程序初体验 微信小程序版的个人博客及简历 说明: 本项目为小程序入门项目,需要一定的前端基础及一点后端知识,项目可能不太好,欢迎大家吐槽,纯萌新小白 ...

最新文章

  1. springboot核心原理
  2. c++常见操作的模板
  3. .net你不行——是你的父亲把你封装的太死,还是你的子孙们太懒,未把你发扬光大。...
  4. python是什么和c++是什么区别_c++和python的区别有哪些
  5. IDEA无法通过类加载器获取resources文件夹配置文件解决办法
  6. c#枚举数字转枚举_C#枚举能力问题和解答 套装4
  7. 批处理 java环境_java环境配置简单批处理方法一键OK
  8. html间数据传送,Express框架与html之间如何进行数据传递(示例代码)
  9. mfc color 亮度_双十一4K投影仪怎么选?小心别掉“亮度坑” - 电视
  10. mysql 导入导出 csv_mysql文件导入导出为csv格式
  11. 遗传优化算法优化LSTM-MSE
  12. Python | 股票数据可视化
  13. 两款强大的PC优化工具推荐,CleanMyPc与Memreduct
  14. R语言 时间序列arima模型
  15. 加速Pytorch安装的速度
  16. java new jsonparser_java – JSONParser无法解析为某种类型
  17. redis数据结构及其应用场景
  18. 【原创】畅言实现单点登录的设计流程和技术细节(2/2)
  19. connectex: No connection could be made because the target machine actively refused it.
  20. Ubuntu Linux 系统安装、分区规划

热门文章

  1. Appium实现手机自动化测试案例
  2. 办一个消防资质大概花多少钱?选对不选贵
  3. linux下RTP编程(使用JRTPLIB)(转)
  4. postMessage传递消息详细示例
  5. COleVariant与常用基本数据类型之间的转换
  6. 西亚文明的时空概念与历史上的文明形态
  7. 表格:表格作用,展示数据
  8. OpenCV 之 RNG rng(12345)
  9. 计算机指令系统由什么表示,什么是指令和指令系统?
  10. vue 如何使用定时器?