微信小程序实现拼图小游戏


Posted in Javascript onOctober 22, 2020

微信小游戏入门案例——拼图游戏,供大家参考,具体内容如下

涉及内容:canvas组件、小程序界面绘图API

目录结构:

微信小程序实现拼图小游戏

pages\game\game.js

// pages/game/game.js
// 方块的初始位置
var num = [
 ['00', '01', '02'],
 ['10', '11', '12'],
 ['20', '21', '22']
]
 
// 方块的宽度
var w = 100
 
// 图片的初始地址
var url = '/images/pic01.jpg'
 
Page({
 
 /**
 * 页面的初始数据
 */
 data: {
 isWin: false
 
 },
 
 /**
 * 自定义函数--随机打乱方块顺序
 */
 shuffle: function() {
 // 先令所有方块回归初始位置
 num = [
 ['00', '01', '02'],
 ['10', '11', '12'],
 ['20', '21', '22']
 ]
 
 // 记录当前空白方块的行和列
 var row = 2
 var col = 2
 
 // 随机打乱方块顺序100次
 for (var i = 0; i < 100; i++) {
 // 随机生成一个方向:上0,下1,左2,右3
 var direction = Math.round(Math.random() * 3)
 
 // 上:0
 if (direction == 0) {
 // 空白方块不能在最上面一行
 if (row != 0) {
  // 交换位置
  num[row][col] = num[row - 1][col]
  num[row - 1][col] = '22'
 
  // 更新空白方块的行
  row -= 1
 }
 }
 
 // 下:1
 if (direction == 1) {
 // 空白方块不能在最下面一行
 if (row != 2) {
  // 交换位置
  num[row][col] = num[row + 1][col]
  num[row + 1][col] = '22'
 
  // 更新空白方块的行
  row += 1
 }
 }
 
 // 左:2
 if (direction == 2) {
 // 空白方块不能在最左边一列
 if (col != 0) {
  // 交换位置
  num[row][col] = num[row][col - 1]
  num[row][col - 1] = '22'
 
  // 更新空白方块的列
  col -= 1
 }
 }
 
 // 右:3
 if (direction == 3) {
 // 空白方块不能在最右边一列
 if (col != 2) {
  // 交换位置
  num[row][col] = num[row][col + 1]
  num[row][col + 1] = '22'
 
  // 更新空白方块的列
  col += 1
 }
 }
 
 }
 
 },
 
 /**
 * 自定义函数--绘制画布内容
 */
 drawCanvas: function() {
 let ctx = this.ctx
 
 // 清空画布
 ctx.clearRect(0, 0, 300, 300)
 
 // 使用双重for循环语句绘制3x3拼图
 for (var i = 0; i < 3; i++) {
 for (var j = 0; j < 3; j++) {
 if (num[i][j] != '22') {
  // 获取行和列
  var row = parseInt(num[i][j] / 10)
  var col = num[i][j] % 10
 
  // 绘制方块
  ctx.drawImage(url, col * w, row * w, w, w, j * w, i * w, w, w)
 }
 }
 }
 
 ctx.draw()
 },
 
 /**
 * 自定义函数--监听点击方块事件
 */
 touchBox: function(e) {
 // 如果游戏已经成功,不做任何操作
 if (this.data.isWin) {
 // 终止本函数
 return
 }
 
 // 获取被点击方块的坐标x和y
 var x = e.changedTouches[0].x
 var y = e.changedTouches[0].y
 // console.log('x:'+x+',y:'+y)
 
 // 换算成行和列
 var row = parseInt(y / w)
 var col = parseInt(x / w)
 
 // 如果点击的不是空白位置
 if (num[row][col] != '22') {
 // 尝试移动方块
 this.moveBox(row, col)
 
 // 重新绘制画布内容
 this.drawCanvas()
 
 // 判断游戏是否成功
 if (this.isWin()) {
 // 在画面上绘制提示语句
 let ctx = this.ctx
 
 // 绘制完整图片
 ctx.drawImage(url, 0, 0)
 
 // 绘制文字
 ctx.setFillStyle('#e64340')
 ctx.setTextAlign('center')
 ctx.setFontSize(60)
 ctx.fillText('游戏成功', 150, 150)
 ctx.draw()
 }
 }
 },
 
 /**
 * 自定义函数--移动被点击的方块
 */
 moveBox: function(i, j) {
 // 情况1:如果被点击的方块不在最上方,检查可否上移
 if (i > 0) {
 // 如果方块的上方是空白
 if (num[i - 1][j] == '22') {
 // 交换当前被点击的方块和空白的位置
 num[i - 1][j] = num[i][j]
 num[i][j] = '22'
 return
 }
 }
 
 // 情况2:如果被点击的方块不在最下方,检查可否下移
 if (i < 2) {
 // 如果方块的下方是空白
 if (num[i + 1][j] == '22') {
 // 交换当前被点击的方块和空白的位置
 num[i + 1][j] = num[i][j]
 num[i][j] = '22'
 return
 }
 }
 
 // 情况3:如果被点击的方块不在最左侧,检查可否左移
 if (j > 0) {
 // 如果方块的左侧是空白
 if (num[i][j - 1] == '22') {
 // 交换当前被点击的方块和空白的位置
 num[i][j - 1] = num[i][j]
 num[i][j] = '22'
 return
 }
 }
 
 // 情况4:如果被点击的方块不在最右侧,检查可否右移
 if (j < 2) {
 // 如果方块的右侧是空白
 if (num[i][j + 1] == '22') {
 // 交换当前被点击的方块和空白的位置
 num[i][j + 1] = num[i][j]
 num[i][j] = '22'
 return
 }
 }
 },
 
 /**
 * 自定义函数--判断游戏是否成功
 */
 isWin: function() {
 // 使用双重for循环检查整个数组
 for (var i = 0; i < 3; i++) {
 for (var j = 0; j < 3; j++) {
 // 如果有方块位置不对
 if (num[i][j] != i * 10 + j) {
  // 返回假,游戏尚未成功
  return false
 }
 }
 }
 
 // 游戏成功,更新状态
 this.setData({
 isWin: true
 })
 // 返回真,游戏成功
 return true
 },
 
 /**
 * 自定义函数--重新开始游戏
 */
 restartGame: function() {
 // 更新游戏状态
 this.setData({
 isWin: false
 })
 
 // 打乱方块顺序
 this.shuffle()
 
 // 绘制画布内容
 this.drawCanvas()
 },
 
 /**
 * 生命周期函数--监听页面加载
 */
 onLoad: function(options) {
 // console.log(options.level)
 
 // 更新图片路径地址
 url = '/images/' + options.level
 // 更新提示图的地址
 this.setData({
 url: url
 })
 
 // 创建画布上下文
 this.ctx = wx.createCanvasContext("myCanvas")
 
 // 打乱方块顺序
 this.shuffle()
 
 // 绘制画布内容
 this.drawCanvas()
 },
 
 /**
 * 生命周期函数--监听页面初次渲染完成
 */
 onReady: function() {
 
 },
 
 /**
 * 生命周期函数--监听页面显示
 */
 onShow: function() {
 
 },
 
 /**
 * 生命周期函数--监听页面隐藏
 */
 onHide: function() {
 
 },
 
 /**
 * 生命周期函数--监听页面卸载
 */
 onUnload: function() {
 
 },
 
 /**
 * 页面相关事件处理函数--监听用户下拉动作
 */
 onPullDownRefresh: function() {
 
 },
 
 /**
 * 页面上拉触底事件的处理函数
 */
 onReachBottom: function() {
 
 },
 
 /**
 * 用户点击右上角分享
 */
 onShareAppMessage: function() {
 
 }
})

pages\game\game.wxml

<view class="container">
 <view class="title">
 提示图
 </view>
 <image src="{{url}}"></image>
 <canvas canvas-id="myCanvas" bindtouchstart="touchBox"></canvas>
 <button type="warn" bindtap="restartGame">重新开始</button>
</view>

pages\game\game.wxss

/* pages/game/game.wxss */
/* 提示图 */
image{
 width: 250rpx;
 height: 250rpx;
}
 
/* 游戏画布区域 */
canvas{
 border: 1rpx solid;
 width: 300px;
 height: 300px;
}

pages\index\index.js

Page({
 
 /**
 * 页面的初始数据
 */
 data: {
 levels:[
 'pic01.jpg',
 'pic02.jpg',
 'pic03.jpg',
 'pic04.jpg',
 'pic05.jpg',
 'pic06.jpg',
 
 ]
 },
 chooseLevel:function(e){
 let level = e.currentTarget.dataset.level
 wx.navigateTo({
 url: '../game/game?level='+level,
 })
 },
 
 /**
 * 生命周期函数--监听页面加载
 */
 onLoad: function (options) {
 
 },
 
 /**
 * 生命周期函数--监听页面初次渲染完成
 */
 onReady: function () {
 
 },
 
 /**
 * 生命周期函数--监听页面显示
 */
 onShow: function () {
 
 },
 
 /**
 * 生命周期函数--监听页面隐藏
 */
 onHide: function () {
 
 },
 
 /**
 * 生命周期函数--监听页面卸载
 */
 onUnload: function () {
 
 },
 
 /**
 * 页面相关事件处理函数--监听用户下拉动作
 */
 onPullDownRefresh: function () {
 
 },
 
 /**
 * 页面上拉触底事件的处理函数
 */
 onReachBottom: function () {
 
 },
 
 /**
 * 用户点击右上角分享
 */
 onShareAppMessage: function () {
 
 }
})

pages\index\index.wxml

<view class="container">
 <view class="title">
 游戏选关
 </view>
 
 <view class="levelBox">
 <view class="box" wx:for="{{levels}}" wx:key="levels{{index}}" bindtap="chooseLevel" data-level="{{item}}">
 <image src="/images/{{item}}"></image>
 <text>第{{index+1}}关</text>
 </view>
 </view>
</view>

pages\index\index.wxss

/**index.wxss**/
/* 关卡区域列表 */
.levelBox{
 width: 100%;
}
 
/* 单个关卡区域 */
.box{
 width: 50%;
 float: left;
 margin: 25rpx 0;
 display: flex;
 flex-direction: column;
 align-items: center;
}
 
/* 选关图片 */
image{
 width: 260rpx;
 height: 260rpx;
}

app.json

{
 "pages":[
 "pages/index/index",
 "pages/game/game"
 ],
 "window":{
 "backgroundTextStyle":"light",
 "navigationBarBackgroundColor": "#E64340",
 "navigationBarTitleText": "拼图游戏",
 "navigationBarTextStyle":"black"
 },
 "style": "v2",
 "sitemapLocation": "sitemap.json"
}

app.wxss

/**app.wxss**/
/* 页面容器样式 */
.container{
 height: 100vh;
 color: #e64340;
 font-weight: bold;
 display: flex;
 flex-direction: column;
 align-items: center;
 justify-content: space-evenly;
}
 
/* 顶端标题样式 */
.title{
 font-size: 18pt;
}

app.js

App({
 
 /**
 * 当小程序初始化完成时,会触发 onLaunch(全局只触发一次)
 */
 onLaunch: function () {
 
 },
 
 /**
 * 当小程序启动,或从后台进入前台显示,会触发 onShow
 */
 onShow: function (options) {
 
 },
 
 /**
 * 当小程序从前台进入后台,会触发 onHide
 */
 onHide: function () {
 
 },
 
 /**
 * 当小程序发生脚本错误,或者 api 调用失败时,会触发 onError 并带上错误信息
 */
 onError: function (msg) {
 
 }
})

运行截图:

微信小程序实现拼图小游戏

为大家推荐现在关注度比较高的微信小程序教程一篇:《微信小程序开发教程》小编为大家精心整理的,希望喜欢。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
教你如何解密js/vbs/vbscript加密的编码异处理小结
Jun 25 Javascript
WordPress JQuery处理沙发头像
Jun 22 Javascript
Web跨浏览器进程通信(Web跨域)
Apr 17 Javascript
JS禁用浏览器退格键实现思路及代码
Oct 29 Javascript
jQuery移除tr无效的解决方法(tr是动态添加)
Sep 22 Javascript
javascript跨域原因以及解决方案分享
Apr 08 Javascript
javascript获取select标签选中的值
Jun 04 Javascript
基于JS代码实现导航条弹出式悬浮菜单
Jun 17 Javascript
JavaScript之cookie技术详解
Nov 18 Javascript
Angular中的interceptors拦截器
Jun 25 Javascript
详解操作虚拟dom模拟react视图渲染
Jul 25 Javascript
Vue OpenLayer 为地图绘制风场效果
Apr 24 Vue.js
Vue select 绑定动态变量的实例讲解
Oct 22 #Javascript
在Vue中使用Select选择器拼接label的操作
Oct 22 #Javascript
JavaScript 中判断变量是否为数字的示例代码
Oct 22 #Javascript
关于vue属性使用和不使用冒号的区别说明
Oct 22 #Javascript
jquery实现抽奖功能
Oct 22 #jQuery
Vue实现简单的留言板
Oct 23 #Javascript
Vue+Bootstrap收藏(点赞)功能逻辑与具体实现
Oct 22 #Javascript
You might like
十天学会php之第一天
2006/10/09 PHP
通过PHP自带的服务器来查看正则匹配结果的方法
2015/12/24 PHP
利用laravel搭建一个迷你博客实战教程
2017/08/13 PHP
PHP微信发送推送消息乱码的解决方法
2019/02/28 PHP
PHP字符串和十六进制如何实现互相转换
2020/07/16 PHP
js form action动态修改方法
2008/11/04 Javascript
jQuery中bind与live的用法及区别小结
2014/01/27 Javascript
javascript 获取元素样式必杀技
2014/05/04 Javascript
使用impress.js制作幻灯片
2015/09/09 Javascript
弹出遮罩层后禁止滚动效果【实现代码】
2016/04/29 Javascript
深入解析JavaScript中的立即执行函数
2016/05/21 Javascript
AngularJS ngModel实现指令与输入直接的数据通信
2016/09/21 Javascript
JS常用函数和常用技巧小结
2016/10/15 Javascript
video.js使用改变ui过程
2017/03/05 Javascript
NodeJS使用Range请求实现下载功能的方法示例
2018/10/12 NodeJs
微信小程序实现多选功能
2018/11/04 Javascript
vue单文件组件lint error自动fix与styleLint报错自动fix详解
2019/01/08 Javascript
JS中创建自定义类型的常用模式总结【工厂模式,构造函数模式,原型模式,动态原型模式等】
2019/01/19 Javascript
Vue解决echart在element的tab切换时显示不正确问题
2020/08/03 Javascript
在HTML中使用JavaScript的两种方法
2020/12/24 Javascript
[43:51]2014 DOTA2国际邀请赛中国区预选赛 Dream Times VS TongFu
2014/05/22 DOTA
编写自定义的Django模板加载器的简单示例
2015/07/21 Python
ubuntu系统下 python链接mysql数据库的方法
2017/01/09 Python
选择python进行数据分析的理由和优势
2019/06/25 Python
Python实现个人微信号自动监控告警的示例
2019/07/03 Python
django项目登录中使用图片验证码的实现方法
2019/08/15 Python
TensorFlow MNIST手写数据集的实现方法
2020/02/05 Python
Python实现分数序列求和
2020/02/25 Python
让IE6支持css3,让 IE7、IE8 都支持CSS3
2011/10/09 HTML / CSS
CSS3实现多重边框的方法总结
2016/05/31 HTML / CSS
windeln官方海外旗舰店:德淘超人气母婴超市
2017/12/15 全球购物
户外活动总结范文
2014/04/30 职场文书
2014年信访维稳工作总结
2014/12/08 职场文书
Python-typing: 类型标注与支持 Any类型详解
2021/05/10 Python
Python入门学习之类的相关知识总结
2021/05/25 Python
OpenStack虚拟机快照和增量备份实现方法
2022/04/04 Servers