關(guān)于于小程序筆者就不做介紹了,官方有詳細(xì)文檔,我們還是先來看張圖吧

就是這個(gè)樣子的,游戲界面跟之前的OC版是差不多的,以筆者的水平,只能設(shè)計(jì)成這樣了,畢竟不是專業(yè)的,話說這蛇怎么長(zhǎng)的像個(gè)J(和)B(諧)啊??
先來看看用來添加組件的wxml文件
upleft{{btnTitle}}rightdown
內(nèi)容是相當(dāng)簡(jiǎn)單滴,上面一個(gè)view,里面放一個(gè)畫布,下面一個(gè)view,里面放5個(gè)按鈕
再來看看wxss布局

內(nèi)容不多,其實(shí)筆者對(duì)CSS也不是很了解,很多年前學(xué)習(xí)過,然而早隨著??排出去了,也許還有更優(yōu)的布局方式,不過湊合著用吧
功能實(shí)現(xiàn)
布局還是很簡(jiǎn)單的,雖然不熟,但是多嘗試幾下還是可以弄出來的,接下來功能邏輯的實(shí)現(xiàn)才是重點(diǎn),編程語(yǔ)言當(dāng)然是js了。
話說筆者當(dāng)年學(xué)js的時(shí)候,可是寫了滿滿一本的筆記,然而......算了,過去的就讓他過去吧,往事不提也罷。
思路其實(shí)與OC版的一樣
蛇:創(chuàng)建一個(gè)點(diǎn)坐標(biāo)數(shù)組,然后以坐標(biāo)點(diǎn)為中心在畫布上畫矩形
食物:隨機(jī)一個(gè)坐標(biāo)點(diǎn),該點(diǎn)不能在蛇身上,否則重新隨機(jī)
蛇的移動(dòng):把蛇尾的坐標(biāo)移到蛇頭前面就行了
吃到食物:每次蛇移動(dòng)完畢后,如果蛇頭的坐標(biāo)與食物的坐標(biāo)一樣,則蛇增長(zhǎng)
蛇的增長(zhǎng):在蛇尾后面加一個(gè)點(diǎn)坐標(biāo)即可
游戲結(jié)束:蛇頭越界或撞到自己身體即游戲結(jié)束
創(chuàng)建蛇
//創(chuàng)建蛇,初始為5節(jié),nodeWH為矩形的邊長(zhǎng)function createSnake(){? nodes.splice(0, nodes.length) //清空數(shù)組? for (var i =4; i >=0; i--) {? ? varnode= newNode(nodeWH* (i +0.5), nodeWH *0.5)? ? nodes.push(node);
}
}
創(chuàng)建食物
functioncreateFood(){//矩形的邊長(zhǎng)為10,畫布寬度為250,高度為350,所以x只能取5-245,y只能取5-345varx =parseInt(Math.random() *24) * nodeWH + nodeWH *0.5vary =parseInt(Math.random() *34) * nodeWH + nodeWH *0.5//如果食物的坐標(biāo)在蛇身上,則重新創(chuàng)建for(vari =0; i < nodes.length; i++) {varnode = nodes[i]if(node.x == x && node.y == y) {? ? ? createFood()return}? }//Node為自定義的類,有兩個(gè)屬性x和y,表示坐標(biāo)food =newNode(x,y)}
蛇的移動(dòng)
蛇的移動(dòng)是有方向的,所以用一個(gè)變量direction來記錄蛇的移動(dòng)方向,游戲開始時(shí),默認(rèn)是向右移動(dòng)。
上面有說到蛇的移動(dòng)就是把蛇尾的坐標(biāo)移到蛇頭前面,但是這個(gè)前面并不是固定的,而是根據(jù)方向來判斷的,如果向右移動(dòng)則右邊為前方,以此類推
吃到食物與蛇增長(zhǎng)
每次移動(dòng)完畢后,判斷蛇頭的坐標(biāo)是否與食物的坐標(biāo)相等就OK了,吃到食物后蛇的長(zhǎng)度會(huì)增加,并且要?jiǎng)?chuàng)建一個(gè)新的食物
function isEatedFood(){varhead = nodes[0]if(head.x== food.x&& head.y== food.y) {? ? score++? ? nodes.push(lastPoint)? ? createFood()? }}
上面的代碼中,lastPoint就是蛇每次移動(dòng)前,蛇尾的坐標(biāo),如果移動(dòng)后吃到食物,那么直接在移動(dòng)前的蛇尾處加上一節(jié)即可
游戲結(jié)束
每次移動(dòng)后,都要判斷蛇頭是否超過畫布,或者撞到自己的身體
functionisDestroy(){varhead = nodes[0]//判斷是否撞到自己身體for(vari =1; i < nodes.length; i++) {varnode = 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()? }}
界面繪制
每次移動(dòng)都要繪制,所以需要一個(gè)定時(shí)器,筆者用的setInterval
functionmove(){? lastPoint = nodes[nodes.length -1]varnode = nodes[0]varnewNode= {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()}functionstartGame() {if(isGameOver) {? ? direction ='right'createSnake()? ? createFood()? ? score =0isGameOver =false}? timer = setInterval(move,300)}
網(wǎng)上說setInterval的性能并不怎么好,建議用requestAnimationFrame,但是很遺憾,筆者不會(huì)用,準(zhǔn)確的說是不知道怎么暫停
varanimateId =0functionmove(){? ? .? ? .? ? .? ? animateId = requestAnimationFrame(move)}functionstartGame(){? ? .? ? .? ? .? ? animateId = requestAnimationFrame(move)}
使用上面的方法可以實(shí)現(xiàn)蛇的移動(dòng)與界面重繪,然而每次執(zhí)行animateId都會(huì)被賦予新的值,所以使用cancelAnimationFrame(animateId)無法暫停,如果有懂前端開發(fā)的大神請(qǐng)指導(dǎo)下
差不多整個(gè)邏輯就是這樣的,喜歡研究的可以自己嘗試下,需要源碼的請(qǐng)自行下載,不要問我怎么打開,不要問我怎么打開,不要問我怎么打開?。?!