1. 程式人生 > >VUE+WebPack遊戲設計:實現盒子動畫和鍵盤特效

VUE+WebPack遊戲設計:實現盒子動畫和鍵盤特效

繼上一節我們已經在畫面上完成了數字盒子的繪製,現在我們就啟動遊戲主迴圈,在主迴圈中驅動遊戲流程,在此,我們先實現盒子從上往下落的效果。在gamescenecomponent.vue中新增一下程式碼:

<script>
 export default {
   data () {
     return {
     fallingSpeed: 0.8,
     ticksPerNewBox: 80
     ....
     }

程式碼中新增的兩個變數將用來控制數字盒子下落的速度。createjs庫給我們提供一種有效的動畫實現機制,它會匯出一個Ticker類,該類提供了一個介面setFPS, 例如通過呼叫createjs.Ticker.setFPS(40), 那麼createjs就能對頁面在一秒內進行40次重新整理,每次重新整理時會發出一個’tick’訊息,我們只要監聽這個訊息,並提供會調函式,那麼createjs就會在一秒內回撥我們的函式40次,在該函式中,我們再通過createjs提供的其他介面繪製頁面就能實現動畫效果了。因此我們繼續新增相關程式碼:

methods: {
     init () {
       this.createjs = window.createjs
       this.canvas = document.getElementById('canvas')
       this.stage = new this.createjs.Stage(this.canvas)
       this.createjs.Ticker.setFPS(40)
       this.createjs.Ticker.addEventListener('tick', this.tick)
     },
     tick (e) {
       this
.stage.update() if (!e.paused) { this.moveObjects() var ticksCount = this.createjs.Ticker.getTicks(true) if (ticksCount % this.ticksPerNewBox === 0) { this.generateNumberBox() } } }, moveObjects () { for (var i = 0, len = this
.numberBoxes.length; i < len; i++) { var box = this.numberBoxes[i] box.y += this.fallingSpeed } }, .... }

在初始化函式init中,我們讓createjs一秒內回撥我們提供的tick回撥函式40次,createjs不斷的回撥我們的tick函式,這個情況實質上構成了遊戲的主迴圈,在上一個遊戲神廟逃亡中,我們是通過一個for迴圈來實現遊戲主迴圈的,這裡我們通過createjs的定時回撥機制實現遊戲的主迴圈。

在tick函式被回撥時,createjs會給它傳遞一個引數,我們通過讀取這個引數的paused值用於判斷遊戲是否處於暫停狀態,如果不是,那麼我們呼叫moveObjects,移動頁面上各個成員的位置,這種移動就構成了一種動畫效果,由於頁面裡的成員都是數字盒子,因此呼叫moveObjects將實現數字盒子從上往下落的效果。

通過getTicks介面,我們能獲得當前函式被回調了多少次,如果回撥的次數正好是80的倍數,也就是this.ticksPerNewBox的值的倍數時,我們通過this.generateNumberBox()在頁面上繪製新的數字盒子。

moveObjects()介面的實現邏輯是,遍歷當前所有數字盒子,分別把他們的y座標加上this.fallingSpeed,也就是0.8, 於是每次頁面重新整理時,頁面上的數字盒子座標總往下挪動0.8個單位。以上所有程式碼完成後,載入頁面得到效果如下:

這裡寫圖片描述

可以看到有很多數字盒子在單位時間內從頂部紛紛往下落。

接下來我們需要完成的,是在底部新增一個數字鍵盤,遊戲的玩法是,玩家在底部數字鍵盤點選選取兩個值後,如果兩個值的乘機與盒子中的數值相等,那麼盒子就會被爆破掉。首先在template標籤中新增以下程式碼:

<template>
  <div>
    <canvas id="canvas" width="300" height="480">
    </canvas>
    <div id="control-box">
      <a class="control" v-for="n in 12" :data-value="n" href=# @click="controlClicked">
      {{n}}
      </a>
    </div>
  </div>
</template>

我們通過VUE的v-for指令,迴圈生成12個下面程式碼所描述的DOM元素:

<a class="control" data-value="1" href="#" @click="controlClicked"></a>

這些元素將在頁面上被繪製成兩排數字鍵盤,接著再style標籤區域新增樣式程式碼:

<style scoped>
  #canvas {
    background: #333; 
  }
  #control-box {
    width: 100%;
    overflow: auto;
    position: absolute;
    bottom: 0;
  }

  .control {
    display: block;
    float: left;
    width: 50px;
    height: 50px;
    background: gray;
    text-align: center;
    line-height: 50px;
    font-size: 24px;
    font-family: impact;
  }

  .control.active {
    background: white;
    color: red;
  }
</style>

程式碼完成後,載入如瀏覽器,你可以看到如下效果:
這裡寫圖片描述

現在點選鍵盤的話,頁面是沒有反應的,接下來我們新增鍵盤點選後的響應函式,在script標籤中新增如下程式碼:

export default {
   data () {
     return {
     ....
     calculationText: null,
     controlHeight: 100,
     inputs: [],
     result: 1
    }
  },
  methods: {
     init () {
       this.createjs = window.createjs
       this.canvas = document.getElementById('canvas')
       this.stage = new this.createjs.Stage(this.canvas)
       this.createjs.Ticker.setFPS(40)
       this.createjs.Ticker.addEventListener('tick', this.tick)

       this.calculationText = new this.createjs.Text('1X1=1', '18px Impact', 'White')
       this.calculationText.textAlign = 'center'
       this.calculationText.x = this.gameWidth / 2
       this.calculationText.y = this.gameHeight - this.controlHeight - 30
       this.stage.addChild(this.calculationText)
     },
     updateText (string) {
       this.calculationText.text = string
     },
     controlClicked (e) {
       var value = e.target.dataset.value
       var string = this.addInput(value)
       this.updateText(string)
     },
     addInput (value) {
       if (this.inputs.length >= 2) {
         this.clearInputs()
       }

       this.inputs.push(value)
       this.result *= value
       return this.inputs.join('X') + '=' + this.result
     },
     clearInputs () {
       this.inputs.length = 0
       this.result = 1
     },
     ....
     }
}

calculationText是顯示在頁面上的字串物件,在init函式裡初始化後加入到stage容器中,當鍵盤的按鍵被點選時,由於我們通過@click指令進行繫結的緣故,一旦按鍵點選後,controlClicked函式會被呼叫,該函式呼叫時會把點選事件物件當做引數傳給我們,通過該物件的target成員,我們就能獲得按鍵的DOM物件,注意我們在前面實現的12個按鍵物件時,在裡面新增一個屬性叫data-value,該屬性的值就是按鍵在頁面上顯示的值,通過e.target.dataset就是在讀取data-value屬性,e.target.dataset.value就是獲得data-value對應的屬性值。

讀取到按鍵的data-value屬性值後,我們就知道使用者點選了哪個按鍵,並獲得了按鍵的數值,然後把該數值傳遞給addInput函式,這個函式的作用是把使用者點選的按鈕值構建成一個字串,加入使用者點選了按鈕”1”和”2”,那麼addInput就會構造出字串”1X2=2”,接著呼叫updateText把該字串顯示到頁面上,完成這些程式碼後,載入頁面,可以看到如下效果:

這裡寫圖片描述

再下一節,我們將在此基礎上完成盒子被爆破的效果,並實現介面美化,最後使得我們的遊戲變得像本節剛開始介紹時得樣子。

更多技術資訊,包括作業系統,編譯器,面試演算法,機器學習,人工智慧,請關照我的公眾號:
這裡寫圖片描述