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


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中简单的实现像C#中using功能(有源码下载)
Jan 09 Javascript
jQuery 表格插件整理
Apr 27 Javascript
javaScript实现浮点数转十六进制字符
Oct 29 Javascript
原生javascript 学习之js变量全面了解
Jul 14 Javascript
深入理解Node.js的HTTP模块
Oct 12 Javascript
微信小程序 wx.uploadFile在安卓手机上面the same task is working问题解决
Dec 14 Javascript
AngularJS指令与控制器之间的交互功能示例
Dec 14 Javascript
EasyUI的DataGrid绑定Json数据源的示例代码
Dec 16 Javascript
详解从买域名到使用pm2部署node.js项目全过程
Mar 07 Javascript
vue安装和使用scss及sass与scss的区别详解
Oct 15 Javascript
layui给下拉框、按钮状态、时间赋初始值的方法
Sep 10 Javascript
JavaScript实现图片上传并预览并提交ajax
Sep 30 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
一个从别的网站抓取信息的例子(域名查询)
2006/10/09 PHP
php 分页函数multi() discuz
2009/06/21 PHP
php集成环境xampp中apache无法启动问题解决方案
2014/11/18 PHP
php+mysqli使用面向对象方式更新数据库实例
2015/01/29 PHP
高质量PHP代码的50个实用技巧必备(下)
2016/01/22 PHP
KindEditor在php环境下上传图片功能集成的方法示例
2020/07/20 PHP
jQuery库与其他JS库冲突的解决办法
2010/02/07 Javascript
JavaScript 原型学习总结
2010/10/29 Javascript
扩展IE中一些不兼容的方法如contains、startWith等等
2014/01/09 Javascript
JavaScript正则表达式中的ignoreCase属性使用详解
2015/06/16 Javascript
javascript模块化简单解析
2016/04/07 Javascript
使用get方式提交表单在地址栏里面不显示提交信息
2017/02/21 Javascript
jQuery插件FusionCharts绘制2D双折线图效果示例【附demo源码】
2017/04/14 jQuery
Angular指令之restict匹配模式的详解
2017/07/27 Javascript
Vue2.0利用vue-resource上传文件到七牛的实例代码
2017/07/28 Javascript
利用js编写网页进度条效果
2017/10/08 Javascript
如何从零开始利用js手写一个Promise库详解
2018/04/19 Javascript
详解Angular6.0使用路由步骤(共7步)
2018/06/29 Javascript
js中script的上下放置区别,Dom的增删改创建操作实例分析
2019/12/16 Javascript
详解Node.js使用token进行认证的简单示例
2020/05/25 Javascript
Javascript基于OOP实实现探测器功能代码实例
2020/08/26 Javascript
vue-video-player 断点续播的实现
2021/02/01 Vue.js
[43:57]LGD vs Mineski 2018国际邀请赛小组赛BO2 第二场 8.19
2018/08/21 DOTA
python根据距离和时长计算配速示例
2014/02/16 Python
Python挑选文件夹里宽大于300图片的方法
2015/03/05 Python
浅谈Python2获取中文文件名的编码问题
2018/01/09 Python
Python File(文件) 方法整理
2019/02/18 Python
Python内置数据类型list各方法的性能测试过程解析
2020/01/07 Python
python可视化分析的实现(matplotlib、seaborn、ggplot2)
2021/02/03 Python
大学生大二自我鉴定
2013/10/28 职场文书
新闻学专业大学生职业生涯规划范文
2014/03/02 职场文书
2014年清明节寄语
2014/04/03 职场文书
《九寨沟》教学反思
2014/04/08 职场文书
安全生产大检查方案
2014/05/07 职场文书
群众路线自查报告及整改措施
2014/11/04 职场文书
Spring Boot接口定义和全局异常统一处理
2022/04/20 Java/Android