继上一节我们已经在画面上完成了数字盒子的绘制,现在我们就启动游戏主循环,在主循环中驱动游戏流程,在此,我们先实现盒子从上往下落的效果。在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个单位。以上所有代码完成后,加载页面得到效果如下:

VUE+WebPack游戏设计:实现盒子动画和键盘特效_vue-js

可以看到有很多数字盒子在单位时间内从顶部纷纷往下落。

接下来我们需要完成的,是在底部添加一个数字键盘,游戏的玩法是,玩家在底部数字键盘点击选取两个值后,如果两个值的乘机与盒子中的数值相等,那么盒子就会被爆破掉。首先在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>

代码完成后,加载如浏览器,你可以看到如下效果:

VUE+WebPack游戏设计:实现盒子动画和键盘特效_vue-js_02

现在点击键盘的话,页面是没有反应的,接下来我们添加键盘点击后的响应函数,在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把该字符串显示到页面上,完成这些代码后,加载页面,可以看到如下效果:

VUE+WebPack游戏设计:实现盒子动画和键盘特效_字符串_03

再下一节,我们将在此基础上完成盒子被爆破的效果,并实现界面美化,最后使得我们的游戏变得像本节刚开始介绍时得样子。

更详细的讲解和代码调试演示过程,请点击链接

更多技术信息,包括操作系统,编译器,面试算法,机器学习,人工智能,请关照我的公众号: