一、实验目标
1、综合应用所学知识创建完整的拼图游戏项目; 2、熟练掌握<canvas>组件。
二、实验步骤
1.创建项目
创建项目pintuGame,选择储存的文件夹,输入AppID,然后选择不使用云服务,并点击确定。
然后将app.json文件的pages内的logs改成games,再保存,可以自动生成game目录,并且删除index,utils目录,并删除index.wxml,index.wxss,index.js,app.wxss,app.js的全部代码,并在index.js和app.js内分别输入page和app自动补全函数。
创建images文件夹,将关卡图片存入images文件夹内。
2.界面设计
2.1导航栏设计
在app.json内将window的"navigationBarBackgroundColor"修改成"#87CEFA",并将"navigationBarTextStyle"修改成"拼图游戏"。
2.2首页设计
在index.wxml内进行首页页面设计,分为两部分进行设计,第一部分是标题区域,第二部分是关卡区域,标题区域使用view组件进行文字展示,关卡区域使用view、image、text组件进行设计,其中image组件用来显示关卡的略缩图,text用来显示第几个关卡。然乎在index.js的data内添加一个levels数组,储存所有的图片信息。其中显示关卡图片的一个view组件内使用wx:for属性来展示所有的关卡的列表数据和图片。
此时页面展示如下图所示:
然后在view组件内绑定chooseLevel事件,并且使用data-level属性携带图片信息,并且在index.js内实现chooseLevel函数。
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>
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;
}
index.js:
chooseLevel:function(e){
let level=e.currentTarget.dataset.level
wx.navigateTo({
url: '../game/game?level=' + level
})
}
2.3游戏页面设计
游戏页面分为三个区域,分别是提示图区域,游戏画布区域,重新启动区域。提示图区域使用view和image组件其中image组件的展示内容设置为变量url,然后在game.js内在监听页面加载函数onLoad内获取在首页中点击的图片信息,将图片地址赋给url,然后在游戏页面进行显示。
此时页面展示为:
在游戏画布区域使用canvas组件,并且添加属性canvas-id,作为该画布的唯一标识符。绑定事件touchBox,用来使方块移动。在game.js内编写shuffle函数,设定位置为(2,2)的方块为空白方块,然后每次随机生成0,1,2,3中的一个数字,当生成0时,空白方块和上面的方块交换位置;当生成1时,空白方块和下面的方块交换位置;当生成2时,空白方块和左边的方块交换位置;当生成3时,空白方块与右边的方块交换位置,重复循环100次进行交换。
然后再game.js内编写drawCanvas函数将打乱后的方块绘制到画布上。该函数首先清空画布的内容,然后获取每个方块的行和列,再使用drawImage方法进行绘制。
然后在onLoad函数内创建画布,并且调用shuffle和drawCanvas函数。
此时game页面如图所示:
继续编写moveBox函数。该函数需输入两个参数,分别是被触摸方框的横坐标和纵坐标,并且通过查看该方块的上下左右方块的编号,检测空白位置在该方块的什么方向,找到空白方块后,交换该方块和空白方块的位置。
然后编写isWin函数,循环遍历所有的方块,判断所有方块的位置是否都正确,若都正确,则返回true,否则返回false。
然后编写touchBox函数,该函数用来响应触摸事件,首先检验游戏是否成功,若游戏成功,则退出本函数,否则获取被点击方块的坐标,若该方块为非空白方块,则调用moveBox函数,然后再调用drawCanwas函数重新绘制画布内容,然后调用isWin函数判断游戏是否成功,若游戏成功,则在画布上绘制“游戏成功”提示文字。
最后是重新开始区域,在重新开始按钮上绑定restartGame函数,并在game.js内编写函数,更新isWin参数为false,调用shuffle和drawCanvas用来打乱方块顺序和重新绘制画布内容。
其中设计页面的相关代码如下:
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>
game.wxss:
image{
width: 250rpx;
height: 250rpx;
}
canvas{
border: 1rpx solid;
width: 300px;
height: 300px;
}
三、程序运行结果
游戏主页面:
选择第4关后的游戏页面:
点击第一行第二个方块后,移动情况:
游戏成功页面:
点击重新开始的页面:
四、问题总结与体会
在实验过程中,在完成拼图后,没有显示“游戏成功”字样,经过调试器的提示,发现是画布对象“setTextAlign”名称打错了,这让我明白在编写代码过程中,要善于使用调试器,查看抛出的错误以及查看变量是否正确携带信息。并且在此次实验中,第一次接触到canvas画布组件,在使用canvas画布时,需要注意画布的大小和位置,以及绘图时使用的坐标系。通过学习 Canvas 组件的使用,我可以自定义绘制图形,实现丰富的界面效果,我深刻体会到了它的灵活性和强大功能,让我在微信小程序开发中更加得心应手。