微信小程序-貪食蛇

很久很久以前,差不多大半年前吧,筆者發布了一篇關于OC版貪食蛇開發的文章,時隔多月,微信小程序橫空出世,于是閑來無事的我又寫了一個小程序版

下面這段話請務必閱讀

筆者是做iOS的,而小程序大部分都是前端的知識,筆者之前沒有做過類似開發,所以代碼寫的相當爛,很多東西都是一邊查資料一邊寫的,請各位輕噴,阿門!

進入正題

頁面布局

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

就是這個樣子的,游戲界面跟之前的OC版是差不多的,以筆者的水平,只能設計成這樣了,畢竟不是專業的,話說這蛇怎么長的像個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>

內容是相當簡單滴,上面一個view,里面放一個畫布,下面一個view,里面放5個按鈕

再來看看wxss布局

內容不多,其實筆者對CSS也不是很了解,很多年前學習過,然而早隨著??排出去了,也許還有更優的布局方式,不過湊合著用吧

功能實現

布局還是很簡單的,雖然不熟,但是多嘗試幾下還是可以弄出來的,接下來功能邏輯的實現才是重點,編程語言當然是js了。

話說筆者當年學js的時候,可是寫了滿滿一本的筆記,然而......算了,過去的就讓他過去吧,往事不提也罷。

思路其實與OC版的一樣

蛇:創建一個點坐標數組,然后以坐標點為中心在畫布上畫矩形
食物:隨機一個坐標點,該點不能在蛇身上,否則重新隨機
蛇的移動:把蛇尾的坐標移到蛇頭前面就行了
吃到食物:每次蛇移動完畢后,如果蛇頭的坐標與食物的坐標一樣,則蛇增長
蛇的增長:在蛇尾后面加一個點坐標即可
游戲結束:蛇頭越界或撞到自己身體即游戲結束

創建蛇
//創建蛇,初始為5節,nodeWH為矩形的邊長
function createSnake(){
  nodes.splice(0, nodes.length) //清空數組
  for (var i = 4; i >= 0; i--) {
    var node = new Node(nodeWH * (i + 0.5), nodeWH * 0.5)
    nodes.push(node);
  }
}
創建食物
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

  //如果食物的坐標在蛇身上,則重新創建
  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來記錄蛇的移動方向,游戲開始時,默認是向右移動。

上面有說到蛇的移動就是把蛇尾的坐標移到蛇頭前面,但是這個前面并不是固定的,而是根據方向來判斷的,如果向右移動則右邊為前方,以此類推

吃到食物與蛇增長

每次移動完畢后,判斷蛇頭的坐標是否與食物的坐標相等就OK了,吃到食物后蛇的長度會增加,并且要創建一個新的食物

function isEatedFood(){
  var head = nodes[0]
  if (head.x == food.x && head.y == food.y) {
    score++
    nodes.push(lastPoint)
    createFood()
  }
}

上面的代碼中,lastPoint就是蛇每次移動前,蛇尾的坐標,如果移動后吃到食物,那么直接在移動前的蛇尾處加上一節即可

游戲結束

每次移動后,都要判斷蛇頭是否超過畫布,或者撞到自己的身體

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)
}

網上說setInterval的性能并不怎么好,建議用requestAnimationFrame,但是很遺憾,筆者不會用,準確的說是不知道怎么暫停

var animateId = 0
function move(){
    .
    .
    .
    animateId = requestAnimationFrame(move)
}
function startGame(){
    .
    .
    .
    animateId = requestAnimationFrame(move)
}

使用上面的方法可以實現蛇的移動與界面重繪,然而每次執行animateId都會被賦予新的值,所以使用cancelAnimationFrame(animateId)無法暫停,如果有懂前端開發的大神請指導下

差不多整個邏輯就是這樣的,喜歡研究的可以自己嘗試下,需要源碼的請自行下載,不要問我怎么打開,不要問我怎么打開,不要問我怎么打開?。。?/p>

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,002評論 6 542
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,400評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事?!?“怎么了?”我有些...
    開封第一講書人閱讀 178,136評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,714評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,452評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,818評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,812評論 3 446
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,997評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,552評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,292評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,510評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,035評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,721評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,121評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,429評論 1 294
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,235評論 3 398
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,480評論 2 379

推薦閱讀更多精彩內容

  • 關于于小程序筆者就不做介紹了,官方有詳細文檔,我們還是先來看張圖吧 就是這個樣子的,游戲界面跟之前的OC版是差不多...
    Programmer客棧閱讀 2,589評論 0 0
  • 前言 閑著沒事干,想起多年前學java時,筆者擼過的俄羅斯方塊,坦克大戰,貪食蛇,現如今已拋棄java多年,投入i...
    codingZero閱讀 8,116評論 12 54
  • 前天犯賤登錄了騙子的蘋果ID, 結果自己的ipad被騙子遠程鎖定了, 如今變磚頭, 心情很down, 故參考網友的...
    imbaWales閱讀 1,327評論 3 11
  • 最近在做一個貪吃蛇的項目,這是我第一次用js來實現做一款游戲,雖然很low,但出現預想的效果時還是很開心的,雖然做...
    風之傷_3eed閱讀 298評論 0 0
  • 今天我發小結婚了,婚禮我沒有去, 因為他沒有邀請我 我仔細想了下他為什么不邀請我 我覺得問題還是在我身上 可能是因...
    毛衣毛閱讀 557評論 0 0