一、实验目标
1、综合应用所学的知识创建完整的推箱子游戏;2、熟练掌握<canvas>和绘图API。
二、实验步骤
步骤一 添加文件
添加images uilts>-data.js
步骤二 导航栏设计
在app.json写如下代码
步骤三 页面设计
步骤四 游戏页面设计
在game里写以下wxml和wxss
<!--pages/games/games.wxml--> <view class="container"> <view class="title">第1关</view> <canvas canvas-id="myCanvas"></canvas> <view class="btnBox"> <button type="warn" id="btn">↑</button> <view> <button type="warn" id="btn">←</button> <button type="warn" id="btn">↓</button> <button type="warn" id="btn">→</button> </view> </view> <button type="warn">重新开始</button> </view> /* pages/games/games.wxss */ canvas{ border: 1rpx solid; width: 320px; height: 320px; } .btnBox{ display: flex; flex-direction: column; align-items: center; } .btnBox view { display: flex; flex-direction: row; } .btnBox #btn{ width: 90rpx; height: 90rpx; margin: 10rpx; } button{ margin: 10rpx; }
上面这个button的样式需要用到id,否则显示不出来
步骤五 逻辑实现
1.公共逻辑
var map1 = [ [0,1,1,1,1,1,0,0] [0,1,2,2,1,1,1,0] [0,1,5,4,2,2,1,0] [1,1,1,2,1,2,1,1] [1,3,1,2,1,2,2,1] [1,3,4,2,2,1,2,1] [1,3,2,2,2,4,2,1] [1,1,1,1,1,1,1,1] ] var map2 = [ [0,0,1,1,1,0,0,0] [0,0,1,3,1,0,0,0] [0,0,1,2,1,1,1,1] [1,1,1,4,2,4,3,1] [1,3,2,4,5,1,1,1] [1,1,1,1,4,1,0,0] [0,0,0,1,3,1,0,0] [0,0,0,1,1,1,0,0] ] var map3 = [ [0,0,1,1,1,1,0,0] [0,0,1,3,3,1,0,0] [0,1,1,2,3,1,1,0] [0,1,2,2,4,3,1,0] [1,1,2,2,5,4,1,1] [1,2,2,1,4,4,2,1] [1,2,2,2,2,2,2,1] [1,1,1,1,1,1,1,1] ] var map4 = [ [0,1,1,1,1,1,1,0] [0,1,3,2,3,3,1,0] [0,1,3,2,4,3,1,0] [1,1,1,2,2,4,1,1] [1,2,4,2,2,4,2,1] [1,2,1,4,1,1,2,1] [1,2,2,2,5,2,2,1] [1,1,1,1,1,1,1,1] ] module.exports = { maps:[map1,map2,map3,map4] }
然后在game.js中引用data.js就可以了
在games.js加入
initMap:function(level){ let mapData = data.maps[level] for(var i=0;i<8;i++) { for(var j =0;j<8;j++) { box[i][j]=0 map[i][j]=mapData[i][j] if(mapData[i][j]==4){ box[i][j]=4 map[i][j]=2 }else if(mapData[i][j] == 5){ map[i][j] = 2 row = i col = j } } } }, drawCanvas:function() { let ctx = this.ctx ctx.clearRect(0,0,320,320) for(var i = 0;i<8;i++) { for(var j = 0;j<8;j++) { let img = 'ice' if(map[i][j] == 1){ img='stone' }else if(map[i][j]==3){ img='pig' } ctx.drawImage('/images/icons/'+img+'.png',j*w,i*w,w,w) if(box[i][j] == 4){ ctx.drawImage('/images/icons/box.png',j*w,i*w,w,w) } } } ctx.drawImage('/images/icons/bird.png',col*w,row*w,w,w) ctx.draw() }, /** * 生命周期函数--监听页面加载 */ onLoad: function(options) { let level = options.level this.setData({ level:parseInt(level) + 1 }) this.ctx = wx.createCanvasContext('myCanvas') this.initMap(level) this.drawCanvas() },
这样画布上的内容就布置好了 现在要做的是怎么让它动起来 我们先给每个按钮绑定事件
接着把函数补齐
up:function(){ if(row>0){ if(map[row-1][col]!=1&&box[row-1][col!=4]){ row = row-1 } } else if(box[row-1][col]==4){ if(row-1>0){ if(map[row-2][col]!= 1&& box[row-2][col]!=4){ box[row-2][col] = 4 box[row-1][col] = 0 row = row - 1 } } this.drawCanvas() } },
向上的函数 接着按照这个把剩下的几个写完
移动判断实现以后,就可以判断是否成功,成功后直接给出信息提示即可
isWin:function(){ for(var i = 0;i<8;i++) { for(var j = 0;j<8;j++){ if(box[i][j] == 4&& map[i][j]!= 3){ return false } } } return true }, checkWin:function() { if(this.isWin()){ wx.showModal({ title: '恭喜', content: '游戏成功', showCancel:false }) } },
再把这个加入到每次的移动当中去检测就可以了
对了,还有一个restart的按钮
三、程序运行结果
四、问题总结与体会
这次实验是复刻推箱子,还是比较有意思的,整体比较简单,游戏的逻辑利用二维数组也比较容易实现,主要是版本更新的缘故,有些代码规范不一样导致效果不一样,主要还是学到了canvas的使用,可以用数组配合图片进行布置,小游戏不想新闻网页需要那么多的信息传递,逻辑上也比较好实现
最后感谢海子哥的倾情帮助@shineahead