關(guān)于于小程序筆者就不做介紹了骂因,官方有詳細文檔炎咖,我們還是先來看張圖吧
就是這個樣子的,游戲界面跟之前的OC版是差不多的寒波,以筆者的水平乘盼,只能設(shè)計成這樣了陵且,畢竟不是專業(yè)的帝嗡,話說這蛇怎么長的像個J(和)B(諧)啊??
先來看看用來添加組件的wxml文件
upleft{{btnTitle}}rightdown
內(nèi)容是相當(dāng)簡單滴,上面一個view繁莹,里面放一個畫布页屠,下面一個view阴幌,里面放5個按鈕
再來看看wxss布局
內(nèi)容不多,其實筆者對CSS也不是很了解卷中,很多年前學(xué)習(xí)過矛双,然而早隨著??排出去了,也許還有更優(yōu)的布局方式蟆豫,不過湊合著用吧
功能實現(xiàn)
布局還是很簡單的议忽,雖然不熟,但是多嘗試幾下還是可以弄出來的十减,接下來功能邏輯的實現(xiàn)才是重點栈幸,編程語言當(dāng)然是js了。
話說筆者當(dāng)年學(xué)js的時候帮辟,可是寫了滿滿一本的筆記速址,然而......算了,過去的就讓他過去吧由驹,往事不提也罷芍锚。
思路其實與OC版的一樣
蛇:創(chuàng)建一個點坐標(biāo)數(shù)組,然后以坐標(biāo)點為中心在畫布上畫矩形
食物:隨機一個坐標(biāo)點蔓榄,該點不能在蛇身上并炮,否則重新隨機
蛇的移動:把蛇尾的坐標(biāo)移到蛇頭前面就行了
吃到食物:每次蛇移動完畢后,如果蛇頭的坐標(biāo)與食物的坐標(biāo)一樣甥郑,則蛇增長
蛇的增長:在蛇尾后面加一個點坐標(biāo)即可
游戲結(jié)束:蛇頭越界或撞到自己身體即游戲結(jié)束
創(chuàng)建蛇
//創(chuàng)建蛇逃魄,初始為5節(jié),nodeWH為矩形的邊長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(){//矩形的邊長為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為自定義的類秃流,有兩個屬性x和y,表示坐標(biāo)food =newNode(x,y)}
蛇的移動
蛇的移動是有方向的柳弄,所以用一個變量direction來記錄蛇的移動方向舶胀,游戲開始時,默認是向右移動碧注。
上面有說到蛇的移動就是把蛇尾的坐標(biāo)移到蛇頭前面嚣伐,但是這個前面并不是固定的,而是根據(jù)方向來判斷的萍丐,如果向右移動則右邊為前方轩端,以此類推
吃到食物與蛇增長
每次移動完畢后,判斷蛇頭的坐標(biāo)是否與食物的坐標(biāo)相等就OK了逝变,吃到食物后蛇的長度會增加基茵,并且要創(chuàng)建一個新的食物
function isEatedFood(){varhead = nodes[0]if(head.x== food.x&& head.y== food.y) {? ? score++? ? nodes.push(lastPoint)? ? createFood()? }}
上面的代碼中,lastPoint就是蛇每次移動前壳影,蛇尾的坐標(biāo)拱层,如果移動后吃到食物,那么直接在移動前的蛇尾處加上一節(jié)即可
游戲結(jié)束
每次移動后宴咧,都要判斷蛇頭是否超過畫布根灯,或者撞到自己的身體
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()? }}
界面繪制
每次移動都要繪制,所以需要一個定時器掺栅,筆者用的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,但是很遺憾氧卧,筆者不會用桃笙,準(zhǔn)確的說是不知道怎么暫停
varanimateId =0functionmove(){? ? .? ? .? ? .? ? animateId = requestAnimationFrame(move)}functionstartGame(){? ? .? ? .? ? .? ? animateId = requestAnimationFrame(move)}
使用上面的方法可以實現(xiàn)蛇的移動與界面重繪,然而每次執(zhí)行animateId都會被賦予新的值沙绝,所以使用cancelAnimationFrame(animateId)無法暫停搏明,如果有懂前端開發(fā)的大神請指導(dǎo)下
差不多整個邏輯就是這樣的,喜歡研究的可以自己嘗試下宿饱,需要源碼的請自行下載熏瞄,不要問我怎么打開脚祟,不要問我怎么打開谬以,不要問我怎么打開!S勺馈为黎!