游戏的趣味性在与各种关卡和难度,游戏的难度如上台阶,具有层层递进的性质。本节我们为太空防御游戏增加关卡功能,让游戏的难度由低到高,每一关我们称作一个冲击波,前面的冲击波,外星人的数量比较少,下落速度也相对较慢,等到后面的冲击波时,外星人的数量会越来越多,速度和攻击力越来越大,于是游戏的难度也逐渐变大。
当完成本节代码后,我们会得到如下效果,在每一轮冲击波开始时,界面会出现如下信号:
这里写图片描述
当游戏进行到后几轮冲击波时,外星人数量和种类越来越多,战况越来越激烈:
这里写图片描述
我们看看代码的实现,在gamescenecomponent.vue中添加新的数据结构:
export default { data () { return { .... // change 1 waves: {} } }, methods: { init () { .... // change 2 this.initWaves() this.startWave() ... }, // change 3 initWaves () { console.log('begin init wave') this.waves.nextWave = 0 this.waves.isActive = false // 定义一轮冲击波中外星人从天而降的次序 this.waves.enemySummonOrder = ['EnemyDummy', 'Enemy1', 'Enemy2', 'Enemy3', 'Boss', 'Boss2'] console.log('init wave data') this.waves.data = [ // 第一轮冲击波 {'EnemyDummy': 1, frequency: 10}, // 第二轮冲击波 {'EnemyDummy': 8, 'Enemy1': 5, 'Enemy2': 5, 'Boss': 2, frequency: 150}, // 第三轮冲击波 {'EnemyDummy': 1, 'Enemy1': 1, 'Enemy2': 1, 'Enemy3': 1, 'Boss': 1, 'Boss2': 30, frequency: 50} ] console.log('init wave sprite') this.nextWaveSprite = new this.assetsLib.WaveCleared() this.stage.addChild(this.nextWaveSprite) this.nextWaveSprite.x = 999 }, // change4 启动一轮外星人攻击的冲击波 startWave () { this.energies = 120 this.waves.currentWave = this.waves.data[this.waves.nextWave] this.waves.isActive = true this.waves.enemiesSummoned = 0 }, // change 5 wavesCleared () { this.waves.nextWave += 1 if (this.waves.nextWave >= this.waves.data.length) { this.waves.nextWave = this.waves.data.length - 1 } }, }
上面代码定义了外星人攻击冲击波的数据结构,其中定义了每一轮攻击过程中,外星人的种类和数量,在每一轮冲击波启动前,页面会出现“wave cleared"的字体显示特效,startWave启动新一轮冲击波流程,wavesCleared在冲击波结束后,负责清理页面和各种数据结构。接下来我们实现冲击波流程的动态效果:
// change 6 waveTick () { if (!this.waves.isActive) { return } if (this.cjs.Ticker.getTicks() % this.waves.currentWave.frequency === 0) { // 依次把不同种类的外星人召唤出来 var accumunateTargetCount = 0 for (var i = 0, len = this.waves.enemySummonOrder.length; i < len; i++) { var enemyType = this.waves.enemySummonOrder[i] // 获得外星人个数 var targetCount = this.waves.currentWave[enemyType] || 0 accumunateTargetCount += targetCount if (this.waves.enemiesSummoned < accumunateTargetCount) { break } } if (this.waves.enemiesSummoned >= accumunateTargetCount) { this.waves.isActive = false } else { this.addEnemy(enemyType) this.waves.enemiesSummoned += 1 } } }, tick () { .... // change 9 this.wavesSpan.textContent = this.waves.nextWave + 1 this.boardTick() // change 7 this.waveTick() if (!this.waves.isActive && this.areEnemiesCleared()) { this.boardLayer.isAddingBuilding = false this.removeAllBuildings() this.removeAllBullets() this.wavesCleared() // 显示字体动画 this.cjs.Tween.get(this.nextWaveSprite).to({x: this.canvas.width / 2, y: this.canvas.height / 2, alpha: 0}).to({alpha: 1.0}, 300).wait(1000).to({alpha: 0}, 300).to({x: 999}) this.startWave() } }, // change 8 removeAllBuildings () { for (var i = 0; i < this.boardLayer.cols; i++) { for (var j = 0; j < this.boardLayer.rows; j++) { this.removeBuilding(this.boardLayer.buildingMap[i][j]) } } this.satelliteList = [] this.castleList = [] }, areEnemiesCleared () { return this.enemyList.length === 0 }, removeAllBullets () { this.bulletList.length = 0 this.effectLayer.removeAllChildren() },
waveTick函数用于在冲击波进行的过程中不断的更新页面。每一轮冲击波有哪些种类的外星人已经外星人数量是多少,都是由wave.data中定义的数据决定的。waveTick的作用是把wave.data中定义的外星人种类和数量加载到页面上,然后刷新页面,实现页面动态效果。waveTick是在时钟函数tick中被调用的,在tick函数中,一旦判断到一轮冲击波结束时,他们把"wave cleared"的字体特效显示到页面上,就如开头图片展示的那样。removeAllBuildings和removeAllBullets负责在一轮冲击波结束时,将页面上的建筑物和飞翔的子弹清除掉。最后我们从资源库中将不停种类的外星人资源加载到浏览器里,并在合适的时候将他们描绘在页面上:
// change 9 enemy1 () { console.log('enemy1') var enemy1 = this.enemy() enemy1.addChild(new this.assetsLib.Enemy1()) enemy1.attackSpeed = 50 enemy1.speed = enemy1.originalSpeed enemy1.name = 'enemy1' return enemy1 }, enemy2 () { console.log('enemy2') var enemy2 = this.enemy() enemy2.addChild(new this.assetsLib.Enemy2()) enemy2.originalSpeed = 1.0 enemy2.attackSpeed = 40 enemy2.hp = 8 enemy2.deceleration = 0.008 enemy2.speed = enemy2.originalSpeed enemy2.name = 'enemy2' return enemy2 }, boss2 () { var bossEnemy = this.enemy() bossEnemy.addChild(new this.assetsLib.Boss2()) bossEnemy.originalSpeed = 0.2 bossEnemy.deceleration = 0.002 bossEnemy.hp = 300 bossEnemy.attackSpeed = 50 bossEnemy.name = 'boss' return bossEnemy }, enemy3 () { console.log('enemy3') var enemy3 = this.enemy() enemy3.addChild(new this.assetsLib.Enemy3()) enemy3.originalSpeed = 3.0 enemy3.attackSpeed = 10 enemy3.hp = 8 enemy3.deceleration = 0.002 enemy3.speed = enemy3.originalSpeed enemy3.name = 'enemy3' return enemy3 },
完成上面代码后,我们就可以看到如开头第二幅图那样的,五花八门的外星人从天而降,我们在底部架起各种炮台和建筑打击外星人,整幅画面具有星球大战般的绚丽感。
作者:望月从良
链接:https://www.jianshu.com/p/83ea9f01a3b6