更详细的讲解和代码调试演示过程,请点击链接
上一节我们完成了右边扑克牌向左边扑克牌发出冲击波后的动画特效,现在我们接着完成余下的动画效果,接下来左边扑克牌将向右边扑克牌发出冲击波,然后右边扑克牌也要展现颤动效果。
在template标签中添加如下代码:
我们要增加三个变量:cardAShake, cardBShake, cardCShake,当某个变量的值设定为true时,对应的div元素其class属性会添加上shake,这样的话,他就会像左边的扑克牌一样,产生左右摇摆的颤抖效果。
在script标签中,我们添加如下代码:
import Constant from './constant'
export default {
data () {
return {
...
blazeTowwardRightObject: null,
...
blazeAttackRight: false,
cardAShake: false,
cardBShake: false,
cardCShake: false
};
},
mounted () {
....
this.blazeTowwardRightObject = document.querySelector('.blaze.toward-right')
}
....
handleTransitionEvent (e) {
switch (this.transitionState) {
case Constant.OPPONENT_CARD_TRANSITION_END:
if (this.cardOpponentOut === false) {
this.transitionState = Constant.BLAZE_TOWARD_LEFT_ANIMATION_END
this.blazeAttackLeft = true
this.handleAnimationEnd(this.blazeTowardLeftObject)
}
break
case Constant.BLAZE_TOWARD_LEFT_ANIMATION_END:
this.handleAnimationEnd(this.opponentCardObject)
this.opponentCardShake = true
this.transitionState = Constant.OPPONENT_CARD_ANIMATION_END
break
case Constant.OPPONENT_CARD_ANIMATION_END:
this.handleAnimationEnd(this.blazeTowwardRightObject)
this.blazeAttackRight = true
this.transitionState = Constant.BLAZE_TOWARD_RIGHT_ANIMATION_END
break
case Constant.BLAZE_TOWARD_RIGHT_ANIMATION_END:
if (this.cardASelected) {
console.log('card A shake')
this.cardAShake = true
} else if (this.cardBSelected) {
this.cardBShake = true
} else if (this.cardCSelected) {
this.cardCShake = true
}
break
}
}
}
在data()函数中添加新的变量定义,在加载函数mounted中,我们通过querySelector得到属性为'blaze toward-right'的div元素的实例,因为像上一节,我们需要监听这个元素在动画完成后所发出的消息。
当左边的扑克牌完成颤抖效果后,handleTransitionEvent函数又会被调用,此时transitionState的值是Constant.OPPONENT_CARD_ANIMATION_END,因此当它执行时,代码会进入相应的case,于是我们监听属性为'blaze toward-right'这个div元素所发出的webkitAnimationEnd消息,同时把blazeAttackRight设置成true,这样一个从左向右的冲击波动画就会发生,由于我们把transitionState设置成Constant.BLAZE_TOWARD_RIGHT_ANIMATION_END,那么当动画结束后,该函数会再次被调用,然后进入对应分支。以下是向右冲击波的动画:
当向右冲击波动画结束后,handleTransitionEvent再次被调用,此时进入的分支就是case Constant.BLAZE_TOWARD_RIGHT_ANIMATION_END, 代码先判断哪张牌被选中了,然后设置对应的变量,例如如果第一张牌被选中,那么cardASelected就会是true,于是我们就可以将其对应的cardAShake变量设置为true, 于是其对应的div具备了shake属性,由此就引发图片产生左右摇摆的动画,从而出现扑克牌颤抖的效果,具体效果请参看视频
接下来我们进入能量槽的开发。首先打开gamecontainer.vue,在sytle部分的css代码做一些修改:
#game {
width: 480px;
height: 600px;
margin: 0 auto;
border-radius: 8px;
text-align: center;
position: relative;
overflow: hidden;
}
.row {
width: 480px;
margin: 0 auto;
}
上面修改完后,我们的游戏场景会转移到页面中央。回到gamescenecomponent.vue,在template标签中的开头部分添加如下代码:
接着到style标签部分,添加如下代码:
.battle-indicator {
position: absolute;
width: 80px;
height: 80px;
top: 0;
left: 200px;
background: url(../../static/images/battle.png)
}
.hp-background {
border-bottom: 1px solid #333;
background: #ababab;
height: 30px;
}
.hp {
position: absolute;
width: 210px;
height: 30px;
transition: all .3s ease-out;
}
.hp.opponent {
background: url(../../static/images/blue-hp.png) repeat;
left: 0;
}
.hp.player {
background: url(../../static/images/red-hp.png) repeat;
right: 0;
}
接着我们在script标签的代码里,增加有关变量的定义:
import Constant from './constant'
export default {
data () {
return {
....
playerHP: 100,
opponentHP: 100,
opponentHPWidth: '210px',
playerHPWidth: '210px'
}
....
}
上面代码完成后,可以看到游戏场景的上方出现了蓝色和红色两截能量槽:
接着我们要做的是,当两张扑克牌发射冲击波后,上面的能量槽根据情况进行相应变化,在style标签中对代码做相应的修改和添加:
methods: {
randomizePower () {
this.selectedCardPower = Math.round(Math.random() * 60) + 40
this.opponentCardPower = Math.round(Math.random() * 60) + 40
},
isSomeoneDead () {
return (this.playerHP <= 0 || this.opponentHP <= 0)
},
isPlayerDead () {
if (this.playerHP <= 0) {
return true
}
return false
},
hurtPlayer (attackPower, defensePower) {
var diff = attackPower - defensePower
if (diff > 0) {
this.playerHP = Math.max(this.playerHP - diff, 0)
this.playerHPWidth = this.playerHP / 100 * 210 + 'px'
}
console.log('player width:' + this.playerHPWidth)
},
hurtOpponent (attackPower, defensePower) {
var diff = attackPower - defensePower
if (diff > 0) {
this.opponentHP = Math.max(this.opponentHP - diff, 0)
this.opponentHPWidth = this.opponentHP / 100 * 210 + 'px'
}
console.log('opponent width' + this.opponentHPWidth)
}
}
hurtPlayer 和 hurtOpponent分别用来计算用户选中的牌和敌对牌经过厮杀后,各自该减去多少能量,randomizePower用来为两张牌随机的产生能量值。一旦两张牌互相发射冲击波后,我们就利用上面的函数计算各自能量的损耗,然后把损耗结果在能量槽上反映出来,于是我们需要对函数handleTransitionEvent进行相应修改:
handleTransitionEvent (e) {
....
case Constant.BLAZE_TOWARD_LEFT_ANIMATION_END:
this.handleAnimationEnd(this.opponentCardObject)
this.opponentCardShake = true
this.transitionState = Constant.OPPONENT_CARD_ANIMATION_END
this.hurtOpponent(this.selectedCardPower, this.opponentCardPower)
break
....
case Constant.BLAZE_TOWARD_RIGHT_ANIMATION_END:
if (this.cardASelected) {
this.cardAShake = true
} else if (this.cardBSelected) {
this.cardBShake = true
} else if (this.cardCSelected) {
this.cardCShake = true
}
this.hurtPlayer(this.opponentCardPower, this.selectedCardPower)
break
}
当从右向左的冲击波动画结束后,我们使用hurtOpponent计算敌对扑克牌的能量减少了多少,从左向右的冲击波动画结束后,我们使用hurtPlayer来计算用户这边的能量槽应该减少多少,上面的代码完成后,运行起来结果如下:
下一节我们将完成游戏的收尾工作,经过一系列艰苦的努力,我们终于看到了胜利的曙光。
更多技术信息,包括操作系统,编译器,面试算法,机器学习,人工智能,请关照我的公众号: