很久很久以前,差不多大半年前吧紊浩,筆者發(fā)布了一篇關(guān)于OC版貪食蛇開發(fā)的文章蔫饰,時隔多月,微信小程序橫空出世榔幸,于是閑來無事的我又寫了一個小程序版
下面這段話請務必閱讀
筆者是做iOS的允乐,而小程序大部分都是前端的知識,筆者之前沒有做過類似開發(fā)削咆,所以代碼寫的相當爛牍疏,很多東西都是一邊查資料一邊寫的,請各位輕噴拨齐,阿門鳞陨!
進入正題
頁面布局
關(guān)于小程序筆者就不做介紹了,官方有詳細文檔瞻惋,我們還是先來看張圖吧
就是這個樣子的厦滤,游戲界面跟之前的OC版是差不多的援岩,以筆者的水平,只能設計成這樣了掏导,畢竟不是專業(yè)的享怀,話說這蛇怎么長的像個J(和)B(諧)啊??
先來看看用來添加組件的wxml文件
<view class="backView">
<canvas canvas-id="snakeCanvas" class="canvas"/>
</view>
<view class="controlView">
<button class="btnClass" bindtap="changeDirection" id="up">up</button>
<view style="display:flex; height:33.33%">
<button class="btnClass" bindtap="changeDirection" id="left">left</button>
<button class="btnClass" bindtap="startGame" >{{btnTitle}}</button>
<button class="btnClass" bindtap="changeDirection" id="right">right</button>
</view>
<button class="btnClass" bindtap="changeDirection" id="down">down</button>
</view>
內(nèi)容是相當簡單滴,上面一個view趟咆,里面放一個畫布添瓷,下面一個view,里面放5個按鈕
再來看看wxss布局
內(nèi)容不多值纱,其實筆者對CSS也不是很了解仰坦,很多年前學習過,然而早隨著??排出去了计雌,也許還有更優(yōu)的布局方式悄晃,不過湊合著用吧
功能實現(xiàn)
布局還是很簡單的,雖然不熟凿滤,但是多嘗試幾下還是可以弄出來的妈橄,接下來功能邏輯的實現(xiàn)才是重點,編程語言當然是js了翁脆。
話說筆者當年學js的時候眷蚓,可是寫了滿滿一本的筆記,然而......算了反番,過去的就讓他過去吧沙热,往事不提也罷。
思路其實與OC版的一樣
蛇:創(chuàng)建一個點坐標數(shù)組罢缸,然后以坐標點為中心在畫布上畫矩形
食物:隨機一個坐標點篙贸,該點不能在蛇身上,否則重新隨機
蛇的移動:把蛇尾的坐標移到蛇頭前面就行了
吃到食物:每次蛇移動完畢后枫疆,如果蛇頭的坐標與食物的坐標一樣爵川,則蛇增長
蛇的增長:在蛇尾后面加一個點坐標即可
游戲結(jié)束:蛇頭越界或撞到自己身體即游戲結(jié)束
創(chuàng)建蛇
//創(chuàng)建蛇,初始為5節(jié)息楔,nodeWH為矩形的邊長
function createSnake(){
nodes.splice(0, nodes.length) //清空數(shù)組
for (var i = 4; i >= 0; i--) {
var node = new Node(nodeWH * (i + 0.5), nodeWH * 0.5)
nodes.push(node);
}
}
創(chuàng)建食物
function createFood(){
//矩形的邊長為10寝贡,畫布寬度為250,高度為350值依,所以x只能取5-245圃泡,y只能取5-345
var x = parseInt(Math.random() * 24) * nodeWH + nodeWH * 0.5
var y = parseInt(Math.random() * 34) * nodeWH + nodeWH * 0.5
//如果食物的坐標在蛇身上,則重新創(chuàng)建
for (var i = 0; i < nodes.length; i++) {
var node = nodes[i]
if (node.x == x && node.y == y) {
createFood()
return
}
}
//Node為自定義的類愿险,有兩個屬性x和y颇蜡,表示坐標
food = new Node(x,y)
}
蛇的移動
蛇的移動是有方向的,所以用一個變量direction來記錄蛇的移動方向,游戲開始時澡匪,默認是向右移動熔任。
上面有說到蛇的移動就是把蛇尾的坐標移到蛇頭前面,但是這個前面并不是固定的唁情,而是根據(jù)方向來判斷的疑苔,如果向右移動則右邊為前方,以此類推
吃到食物與蛇增長
每次移動完畢后甸鸟,判斷蛇頭的坐標是否與食物的坐標相等就OK了惦费,吃到食物后蛇的長度會增加,并且要創(chuàng)建一個新的食物
function isEatedFood(){
var head = nodes[0]
if (head.x == food.x && head.y == food.y) {
score++
nodes.push(lastPoint)
createFood()
}
}
上面的代碼中抢韭,lastPoint就是蛇每次移動前薪贫,蛇尾的坐標,如果移動后吃到食物刻恭,那么直接在移動前的蛇尾處加上一節(jié)即可
游戲結(jié)束
每次移動后瞧省,都要判斷蛇頭是否超過畫布,或者撞到自己的身體
function isDestroy(){
var head = nodes[0]
//判斷是否撞到自己身體
for (var i = 1; i < nodes.length; i++) {
var node = nodes[i]
if (head.x == node.x && head.y == node.y) {
gameOver()
}
}
//判斷水平方向是否越界
if (head.x < 5 || head.x > 245) {
gameOver()
}
//判斷垂直方向是否越界
if (head.y < 5 || head.y > 345) {
gameOver()
}
}
界面繪制
每次移動都要繪制鳍贾,所以需要一個定時器鞍匾,筆者用的setInterval
function move(){
lastPoint = nodes[nodes.length - 1]
var node = nodes[0]
var newNode = {x: node.x, y: node.y}
switch (direction) {
case 'up':
newNode.y -= nodeWH;
break;
case 'left':
newNode.x -= nodeWH;
break;
case 'right':
newNode.x += nodeWH;
break;
case 'down':
newNode.y += nodeWH;
break;
}
nodes.pop()
nodes.unshift(newNode)
moveEnd()
}
function startGame() {
if (isGameOver) {
direction = 'right'
createSnake()
createFood()
score = 0
isGameOver = false
}
timer = setInterval(move,300)
}
網(wǎng)上說setInterval的性能并不怎么好,建議用requestAnimationFrame骑科,但是很遺憾橡淑,筆者不會用,準確的說是不知道怎么暫停
var animateId = 0
function move(){
.
.
.
animateId = requestAnimationFrame(move)
}
function startGame(){
.
.
.
animateId = requestAnimationFrame(move)
}
使用上面的方法可以實現(xiàn)蛇的移動與界面重繪咆爽,然而每次執(zhí)行animateId都會被賦予新的值梁棠,所以使用cancelAnimationFrame(animateId)無法暫停,如果有懂前端開發(fā)的大神請指導下
差不多整個邏輯就是這樣的斗埂,喜歡研究的可以自己嘗試下符糊,需要源碼的請自行下載,不要問我怎么打開蜜笤,不要問我怎么打開濒蒋,不要問我怎么打開!0淹谩!