2021-06-10 09:15:41 +08:00

541 lines
9.3 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// 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
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) {
}
})