零基础萌新的微信小程序DEMO
| 博客班级 | https://edu.cnblogs.com/campus/zjcsxy/SE2020/ |
| 作业要求 | https://edu.cnblogs.com/campus/zjcsxy/SE2020/homework/11334 |
| 作业目标 |
|
| 作业源代码 | https://github.com/zlc201910161013711/snakegame |
| 学号 | 31801130 |
| 姓名 | 章立晨 |
| 院系 | 浙大城市学院计算机系 |
前言
软件工程的第一次小作业,我之前没有微信小程序的编写经验和WEB前端的相关基础,所以刚刚收到要做这个作业的通知的时候是很慌的。在确定主题的时候也想过很多,咨询了学长,在CSDN和博客园上看了很多教程,最终跟着B站教程,一步一步做了这个粗糙的贪吃蛇小游戏。在这里写一些简单的心得体会,都是最基本的东西(实在是太弱了...)
首先是效果演示:

界面就这一个,游戏的主界面,可以通过手指的上下左右滑动调动蛇头的方向,并且蛇在吃了一个食物后会变长一个单位,并且加10分,在顶部会记录历史最高得分。
游戏界面设计
首先,刚刚创建一个新Project的时候,只有四个文件和一个基础界面。我在App.json文件里面增加了一个页面路径,创建游戏的主界面。
"pages":[ "pages/snake/snake","pages/index/index", "pages/logs/logs" ],
刚刚创建完的游戏主界面自带4个文件,分别是Js、Json、Wxss、Wxml。在学习过后我懂了,Js是用于申明整个页面的全局变量和函数的文件,这也是整个Project码量最大的文件。
Json是存放顶部导航栏样式的文件,而Wxss和Wxml分别对应WEB里的css和html文件,用于编写整个界面。
首先要在wxss和wxml文件里编写游戏界面,这里我对着视频学会了怎么调用块状元素View来完成标题块、当前分数块、最高分数块、游戏主操场的设计。
首先是标题块,这里采用的是嵌套的方法,在最外层开一个view,这样这一层里生成的所有块都是最外层指定的类型。这是最外层定义的样式:
.score{
display: flex;
}
然后标题块的样式,我对着视频学会了如何在wxss里编写来调整想要的标题块的大小、颜色、边框、位置。
这是Title采用的样式
.title{ flex: 1; background: pink; height: 150rpx; margin: 40rpx 20rpx 40rpx 40rpx; text-align: center; font-size: 70rpx; line-height: 150rpx; color: white; border-radius: 20rpx; }
然后是得分块。样式方面和得分是一样的,有一个问题是要在这个块里动态的展示当前的分数,每吃一个食物分数加10。
这里我学会了用两个大括号嵌套一个变量实现这个效果,像这样:
<view class="scoredetail">
<view class="scoredesc">得分</view>
<view class="scorenumber">{{score}}</view>
</view>
这个变量Score就定义在Js文件里。
历史最高分也是同理,在Js文件里多定义一个Maxscore即可。
然后是操场,我采用的方法是定义一个蓝色小块的样式表示操场的一个像素,打印28*22个小块实现操场的样式。这里采用wx:for渲染实现这个效果。
<view class="ground">
<view class="rows" wx:for="{{ground}}" wx:for-item="cols">
<view wx:for="{{cols}}" class="block block_{{item}}"></view>
</view>
</view>
最后是弹窗部分,当游戏失败的时候(蛇撞到边框),弹出一个重新开始的按钮,这里调用的是Modal组件和wx.showModal
<modal class="modal" hidden="{{modalHidden}}" no-cancel
bindconfirm="modalConfirm">
<view>游戏结束,需要重新开始嘛?</view>
</modal>
游戏核心代码
这个游戏是如何让贪吃蛇动起来的核心代码在Js文件中编写。首先,我们需要在data模块里定义好所有要用到的变量:
data: { score:0,//当前得分 maxscore:900,//历史最高分 startx:0,//触摸开始的横坐标 starty:0,//触摸开始的纵坐标 endx: 0,//触摸结束的横坐标 endy:0,//触摸结束的纵坐标 ground:[],//存储操场的每个方块 rows:28,//行数 cols:22,//列数 snake:[],//蛇 food:[],//食物 direction:"",//移动方向 timer:"",//初始化定时器 modalHidden:true,//modal是否隐藏 cnt: 0 },
学习之后我明白了Onload函数的意思是存储一进入界面就要调用的函数,
这里进入界面的时候我需要初始化操场、小蛇、食物、移动函数
onLoad: function (options) { var maxscore=wx.getStorageSync("maxscore") if(!maxscore){ maxscore=0 } this.setData({ maxscore:maxscore }) this.initGround(this.data.rows,this.data.cols) this.initSnake(3) this.createFood() this.move() },
初始化最高分的时候要调用Wx的一个接口叫getStorageSync,解决本地缓存问题。
然后是计分器函数的编写,就是当当前分数大于Maxscore的时候更新Maxscore,同时调用getStorageSync接口。
storeScore:function(){ if(this.data.maxscore<this.data.score){ this.setData({ maxscore:this.data.score }) } wx.setStorageSync("maxscore", this.data.maxscore) }
然后是操场界面的初始化:
initGround:function(rows,cols){ for(var i=0;i<rows;i++){ var arr=[]; this.data.ground.push(arr); for(var j=0;j<cols;j++){ this.data.ground[i].push(0) } } }
蛇的初始化:
initSnake:function(len){ for(var i=0;i<len;i++){ this.data.ground[0][i]=1 this.data.snake.push([0,i]) } }
食物的初始化:
createFood:function(){ this.data.cnt=3 for (var k=1;k<=1;k++) { var x = Math.floor(Math.random()*this.data.rows) var y = Math.floor(Math.random()*this.data.cols) var ground=this.data.ground var snake=this.data.snake ground[x][y]=3 //console.log(ground) for(var i=0;i<snake.length;i++){ var node = snake[i][1] // console.log(node) if (x == 0 && y == node) { this.createFood() return } else { this.setData({ ground: ground, food: [x, y] }) } } } }
这里用0 1 2 分别代表空的块、蛇身、食物。样式里分别定义了block_0 block_1 block_2 这样就可以分别调用三种样式。
编写到这里,贪吃蛇游戏的界面已经成型。但是小蛇还无法动起来。
在学习之后我明白了,可以在函数里加一个参数e,是事件event的简称,在函数里用e.touche[0].PageX e.touch[0].PageY获得当前手指触摸的坐标。
开始触摸函数:
tapStart:function(e){ // console.log("开始点击") // console.log(e) this.setData({ startx:e.touches[0].pageX, starty:e.touches[0].pageY }) },
手指触摸移动:
tapMove:function(e){ // console.log("移动") // console.log(e) this.setData({ endx:e.touches[0].pageX, endy:e.touches[0].pageY }) }
手指触摸结束实现蛇的形状变化:
tapEnd:function(){ //获取滑动距离 var heng=(this.data.endx)?(this.data.endx-this.data.startx):0 var zong=(this.data.endy)?(this.data.endy-this.data.starty):0 if(Math.abs(heng)>5||Math.abs(zong)>5){ var direction = Math.abs(heng) > Math.abs(zong) ? this.computerDir(1, heng) : this.computerDir(0, zong) switch(direction){ case "left": if(this.data.direction=="right"){ return; } break; case "right": if(this.data.direction=="left"){ return } break; case "top": if (this.data.direction == "bottom") { return } break; case "bottom": if (this.data.direction == "top") { return } break; } this.setData({ direction:direction, startx:0, starty:0, endx:0, endy:0 }) } // console.log(this.data.direction) },
获取滑动距离,用后续编写的判断滑动方向的函数来判断滑动方向
移动函数:
move:function(){ var that=this this.data.timer=setInterval(function(){ that.changeDirection(that.data.direction) that.setData({ ground:that.data.ground }) },300) },
学习之后我明白了,这里的Interval是设定一个定时器。按照指定的周期(以毫秒计)来执行注册的回调函数
变换蛇的形状:
changeLeft:function(){ var arr=this.data.snake; var len=this.data.snake.length; var snakeHEAD=arr[len-1][1] var snakeTAIL=arr[0] var ground=this.data.ground ground[snakeTAIL[0]][snakeTAIL[1]]=0 for(var i=0;i<len-1;i++){ arr[i]=arr[i+1] } var x=arr[len-1][0] var y=arr[len-1][1]-1 arr[len-1]=[x,y] this.checkGame(snakeTAIL) for(var i=1;i<len;i++){ ground[arr[i][0]][arr[i][1]]=1 } this.setData({ ground:ground, snake:arr }) return true },
这是向左变换的,剩余三个方向都是类似的,调整x 和 y的值就行。
游戏状态的判断:
checkGame: function (snakeTAIL){ var arr=this.data.snake; var len=this.data.snake.length; var snakeHEAD=arr[len-1] if(snakeHEAD[0]<0||snakeHEAD[0]>=this.data.rows||snakeHEAD[1]<0||snakeHEAD[1]>=this.data.cols){ clearInterval(this.data.timer) this.setData({ modalHidden:false }) } for(var i=0;i<len-1;i++){ if (snakeHEAD[0] == arr[i][0] && snakeHEAD[1] == arr[i][1]) { clearInterval(this.data.timer) this.setData({ modalHidden:false }) } } if(snakeHEAD[0]==this.data.food[0]&&snakeHEAD[1]==this.data.food[1]){ arr.unshift(snakeTAIL) this.setData({ score:this.data.score+10 }) this.createFood() this.storeScore() } }
先取出蛇头和蛇身长度,当蛇撞到边框时判游戏失败,当蛇撞到自己的时候判游戏失败,当蛇吃到食物时分数加10,同时蛇长度加一。
这就是这个小程序的全部了,我刚刚开始学,只能写一些在大佬们看来非常非常简单的东西,并且肯定有很多出错的地方,接受大家的批评...

浙公网安备 33010602011771号