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


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 相关文章推荐
JavaScript下利用fso判断文件是否存在的代码
Dec 11 Javascript
jQuery操作CheckBox的方法介绍(选中,取消,取值)
Feb 04 Javascript
一个JS函数搞定网页标题(title)闪动效果
May 13 Javascript
JS+CSS实现弹出全屏灰黑色透明遮罩效果的方法
Dec 20 Javascript
AngularJS基础知识笔记之表格
May 10 Javascript
简介JavaScript中toTimeString()方法的使用
Jun 12 Javascript
VUE利用vuex模拟实现新闻点赞功能实例
Jun 28 Javascript
jQuery获取随机颜色的实例代码
May 21 jQuery
JS引用传递与值传递的区别与用法分析
Jun 01 Javascript
vue实现键盘输入支付密码功能
Aug 18 Javascript
解决vue 表格table列求和的问题
Nov 06 Javascript
如何用threejs实现实时多边形折射
May 07 Javascript
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 常用字符串函数总结
2008/03/15 PHP
PHP环境搭建的详细步骤
2016/06/30 PHP
php 实现一个字符串加密解密的函数实例代码
2016/11/01 PHP
ThinkPHP5.1框架数据库链接和增删改查操作示例
2019/08/03 PHP
PHP查找一列有序数组是否包含某值的方法
2020/02/07 PHP
用html5 js实现点击一个按钮达到浏览器全屏效果
2014/05/28 Javascript
输入框过滤非数字的js代码
2014/09/18 Javascript
JavaScript实现仿网易通行证表单验证
2015/05/25 Javascript
Nodejs实现批量下载妹纸图
2015/05/28 NodeJs
Backbone View 之间通信的三种方式
2016/08/09 Javascript
js变量提升深入理解
2016/09/16 Javascript
Vue.js实现简单动态数据处理
2017/02/13 Javascript
js截取字符串功能的实现方法
2017/09/27 Javascript
快速搭建vue2.0+boostrap项目的方法
2018/04/09 Javascript
angularjs下ng-repeat点击元素改变样式的实现方法
2018/09/12 Javascript
从vue源码看props的用法
2019/01/09 Javascript
分析python服务器拒绝服务攻击代码
2014/01/16 Python
在Python的Django框架中包装视图函数
2015/07/20 Python
python批量制作雷达图的实现方法
2016/07/26 Python
PyCharm在新窗口打开项目的方法
2019/01/17 Python
Python代码实现删除一个list里面重复元素的方法
2019/04/02 Python
Python基于百度AI实现OCR文字识别
2020/04/02 Python
安装多个版本的TensorFlow的方法步骤
2020/04/21 Python
python不同系统中打开方法
2020/06/23 Python
Python基础教程之输入输出和运算符
2020/07/26 Python
python Tornado框架的使用示例
2020/10/19 Python
CSS3 分类菜单效果
2019/05/27 HTML / CSS
匈牙利超级网上商店和优惠:Alza.hu
2019/12/17 全球购物
入党自我鉴定范文
2013/10/04 职场文书
探亲邀请信范文
2014/01/30 职场文书
班主任寄语大全
2014/04/04 职场文书
继承公证书
2014/04/09 职场文书
捐献物资倡议书范文
2014/05/19 职场文书
悬崖上的金鱼姬观后感
2015/06/15 职场文书
小组口号霸气押韵
2015/12/24 职场文书
《静夜思》教学反思
2016/02/17 职场文书