前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >VUE+WebPack前端游戏设计:实现外星人攻击建筑物时的冒烟效果

VUE+WebPack前端游戏设计:实现外星人攻击建筑物时的冒烟效果

作者头像
望月从良
发布2018-07-19 11:53:36
4960
发布2018-07-19 11:53:36
举报
文章被收录于专栏:Coding迪斯尼

玩过红警或是星际的玩家都知道,当子弹或对手攻击建筑物时,建筑物会产生冒烟效果,并且逐步变形,当攻击足够大后,建筑物会爆炸毁灭,这种动态特效极大的增强了游戏的视觉观赏性和娱乐性,本节我们就实现外星人与玩家的道具碰撞时所产生的冒烟效果,这种效果提醒玩家道具正在遭受攻击,完成本节后,效果如下:

我们看看上图效果是如何实现的。我们先修改建筑物的属性,使得它具有能量值,一旦能量值降为0后,它就相当于被外星人摧毁:

代码语言:javascript
复制
building () {
        var b = new this.cjs.Container()
        b.cost = 0
        // change here
        b.shield = 10
        b.damageDeal = 0
        b.attackSpeed = 9999
        return b
      },

每种具体的建筑物会根据自身特点修改上面代码添加的属性值。当建筑物受到攻击时,它要掉血,一旦掉血过多就得从页面上被抹除,实现代码如下:

代码语言:javascript
复制
 buildingDamage (building, damage) {
        var realDamage = Math.max(damage, building.shield, 0)
        building.hp -= realDamage
        if (building.hp <= 0 && building.parent) {
          this.removeBuilding(building)
        }
      },
removeBuilding (building) {
     this.boardLayer.buildingMap[building.col][building.row] = undefined
     this.boardLayer.removeChild(building)
 },

代码中的hp值对应的就是建筑物的能量,传入的参数damage是外星人的攻击力,sheild对应的是建筑物的抵抗力,如果攻击力大于抵抗力,那么建筑物就会收到打击,于是hp的值就会减少,一旦该值减少到小于0后,建筑物就会被从页面上清除。建筑物在拖动到页面上时,会根据它所在的行和列将建筑物对应的对象记录在数组buildingMap里,这个数组在后面会用来判断建筑物和外星人是否产生碰撞,当建筑物从页面上消除时,数组对应的位置设置成undefined,然后建筑物从板块图层对象中删除掉。

外星人有两种状态,一是正在发动攻击,一是正在从上往下落,因此我们要增加外星人对象的相关属性用于标记这两种状态:

代码语言:javascript
复制
enemy () {
        var enemyObj = new this.cjs.Container()
        enemyObj.originalSpeed = 0.5
        enemyObj.deceleration = 0.4
        enemyObj.hp = 10
        enemyObj.damageDeal = 10
        enemyObj.attackSpeed = 100
        enemyObj.speed = enemyObj.originalSpeed

        // change here
        enemyObj.isAttacking = false
        enemyObj.attackingTarget = undefined
        enemyObj.attackingSmoke = new this.assetsLib.Explode()
        enemyObj.attackingSmoke.y = 50
        return enemyObj
      },

isAttacking用于记录外星人是否处于攻击状态,attackingTarget用于记录被攻击的建筑物,当攻击发生时会产生出冒烟的动画效果,冒烟效果其实是一种动态的图片资源,这个资源我们调用assetsLib.Explode()加载到页面,而attackingSmoke属性对应的就是冒烟图片资源,attackingSmoke.y表示冒烟特效图片在页面上的y坐标,这个在后面代码中会有所改变。

外星人对象对应着一个时钟回调函数,在这个函数里会修改外星人在页面上的y坐标,使得外星人产生从高处往下落的动态效果,我们利用这个回调函数来检测外星人是否属于攻击状态,代码如下:

代码语言:javascript
复制
enemyTick (enemyObj) {
    ....
     // change here
        if (this.cjs.Ticker.getTicks() % enemyObj.attackSpeed === 0) {
          if (enemyObj.isAttacking && enemyObj.attackingTarget) {
            this.buildingDamage(enemyObj.attackingTarget, enemyObj.damageDeal)
          }
        }
      }

在修改外星人属性时,我们增加一个attackSpeed属性,该属性用于设置检测外星人是否处于攻击状态的频率,这个值设置的是100,也就是主循环没经过100个ticks就去检测外星人对象是否跟道具相碰撞了。如果isAttacking属性为真,并且它对应的attackingTarget指向具体的对象,这个对象就是外星人要攻击的道具,于是调用buildingDamage函数实现道具的hp值减少。

接着我们实现外星人与道具碰撞的检测,一旦两者遇上,我们在页面上释放出冒烟特效。添加如下代码:

代码语言:javascript
复制
enemyAttackBuilding () {
        // 当外星人与道具相遇时,攻击道具
        for (var i = this.enemyList.length - 1; i >= 0; i--) {
          var enemy = this.enemyList[i]
          var row = enemy.row
          var col = enemy.col
          var target
          if (this.boardLayer.buildingMap[col][row] !== undefined) {
            target = this.boardLayer.buildingMap[col][row]
          } else if (this.boardLayer.buildingMap[col][row + 1] !== undefined) {
            target = this.boardLayer.buildingMap[col][row]
          }

          if (target !== undefined) {
            enemy.speed -= enemy.deceleration
            this.enemyStartAttack(enemy, target)
          } else {
            this.enemyStopAttack(enemy)
          }

          target = undefined
        }
      },

当道具拖动到页面上时,我们会计算道具在板块图层行和列,根据它所在的行和列把道具对象存储在buildingMap数组里。在外星人从上外下坠落的过程中,代码也随着根据外星人所在的坐标计算其在板块图层上的行和列,然后用计算的行和列到数组buildingMap里面查询,一旦查询到的对象不为空,那意味着外星人当前所在的位置有一个道具对象,于是两种就相遇了,然后代码调用enemyStartAttack()接口启动攻击流程,如果当前位置没有道具对象,或者说原来这个位置有道具对象,由于道具对象的hp值减少为0然后从页面上抹除后,那么就调用enemyStopAttack()接口停止攻击流程。我们看看这两个函数的实现:

代码语言:javascript
复制
enemyStartAttack (enemy, target) {
        if (!enemy.isAttacking) {
          enemy.isAttacking = true
          enemy.addChild(enemy.attackingSmoke)
        }
        enemy.attackingTarget = target
      },
      // change here
      enemyStopAttack (enemy) {
        if (enemy.isAttacking) {
          enemy.removeChild(enemy.attackingSmoke)
        }

        enemy.isAttacking = false
        enemy.attackingTarget = undefined
        enemy.speed = enemy.originalSpeed
      },

当调用enemyStartAttack时,它会把外星人的isAttacking属性设置为True,然后将attackingSmoke对象通过addChild加载到页面上,前面我们说过,这个对象对应的是冒烟的动画资源,当加载到页面上时,我们就可以看到冒烟动画呈现出来了。enemyStopAttack调用时,代码会通过removeChild把冒烟动画资源从页面上去除,这样页面上就不再显示冒烟的动画。

最后我们在boardTick函数里调用上面的enemyAttackingBuilding函数:

代码语言:javascript
复制
boardTick() {
....
this.enemyAttackBuilding()
}

完成上面的代码后,本节的功能就完成了,外星人会徐徐往下落,一旦途中遇到道具对象,那么它就启动冒烟动画,一旦道具的hp值减少为0,程序会消除冒烟动画,同时外星人继续往下回落。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2018-03-23,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Coding迪斯尼 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
对象存储
对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档