VUE+WebPack游戏设计:实现子弹发射击打外星人效果

本节将要实现的游戏效果是,当用户在页面上拖拽了一个炮台后,炮台会自动发射出子弹,当飞跃的子弹打中外星人时,外星人就会从页面上消失,本节代码完成后效果如下:

我们看看代入如何实现。第一步是构建子弹对象,代码如下:

// change 1
      bullet (damageDeal) {
        var obj = new this.cjs.Container()
        obj.addChild(new this.assetsLib.Bullet())
        obj.cache(-25, -25, 50, 50)
        obj.damageDeal = damageDeal | 1
        return obj
      },
      // change 2
      bulletTick (bullet) {
        if (this.cjs.Ticker.getPaused()) {
          return
        }

        bullet.y -= 1.5
      }

bullet函数构造一个cjs容器对象,然后从资源库中加载子弹图片资源,并调用cache缓存在页面里,damgeDeal用于设置子弹的攻击力。bulletTick在时钟循环函数中被调用,它会不断的修改子弹对象在页面上的y坐标,从而实现子弹在页面上的飞升效果。

图片中发射子弹的炮台是我们以前实现的castle对象,我们要把所有的castle对象加入到一个列表中,这样我们才能知道有多少炮台要发射子弹,所以代码修改如下:

castle () {
        var b = this.building()
        b.addChild(new this.assetsLib.Castle())
        b.hp = 300
        b.shield = 5
        b.damageDeal = 2
        b.attackSpeed = 120

        // change 3
        b.tick = 0

        // change 10
        this.castleList.push(b)

        return b
      },

代码用castleList数组来记录所有炮台,其中的tick变量用来设置炮台发射子弹的时间间隔。接着我们要增加一个castleTick函数,在主时钟函数中调用,代码如下:

// change 4
      castleTick () {
        if (this.cjs.Ticker.getPaused()) {
          return
        }

        for (var i = 0; i < this.castleList.length; i++) {
          var castle = this.castleList[i]
          castle.tick += 1
          if (castle.tick % castle.attackSpeed === 0) {
            this.summonBullet(castle)
          }
        }

        for (i = 0; i < this.bulletList.length; i++) {
          this.bulletTick(this.bulletList[i])
        }
      },

主时钟循环函数里,它会反复调用castleTick函数,该函数轮询castleList数组,从中取出炮台对象,增加炮台对象的tick计数器,一旦计数器达到指定值时,它会调用summonBullet函数创建子弹对象,然后该函数又会轮询子弹对象数组,然后调用blletTick函数设置页面上子弹对象的y坐标,从而使得子弹产生往上飞的效果。我们再看summonBullet函数的实现:

// change 5
      summonBullet (castle) {
        var bullet = this.bullet(castle.damageDeal)
        bullet.x = castle.x + Math.random() * 20 - 10
        bullet.y = castle.y
        this.addBullet(bullet)
      },
// change 7
addBullet (bullet) {
    this.effectLayer.addChild(bullet)
    this.bulletList.push(bullet)
},

该函数就是调用原先实现的bullet函数创建子弹对象,并把子弹在页面上的坐标设置成与对应的炮台一致,然后调用addBullet函数把子弹对象加入特效图层和bulletList数组。这里用到的几个变量要在data()函数中增加:

data () {
   return {
   ....
   // change 6
   bulletList: [],
   // change 9
   castleList: []
   }   
}

接着我们要在主轮询函数中添加代码,驱动上面代码的调用,在boardTick函数中增加如下代码:

boardTick () {
    ....
            // change 11
        this.castleTick()

        // change 8 轮询敌人队列和子弹队列,看看两者是否相撞
        for (i = this.enemyList.length - 1; i >= 0; i--) {
          for (var j = this.bulletList.length - 1; j >= 0; j--) {
            var bullet = this.bulletList[j]
            var pos = bullet.localToLocal(0, 0, this.effectLayer)
            rowCol = this.screenToRowCol(pos.x, pos.y)
            if (this.enemyMap[rowCol.col][rowCol.row] !== undefined) {
              var enemyHit = this.enemyMap[rowCol.col][rowCol.row]
              this.enemyDamage(enemyHit, bullet.damageDeal)
              if (enemyHit.hp <= 0) {
                this.enemyMap[rowCol.col][rowCol.row] = undefined
                this.removeItem(this.enemyList, enemyHit)
                this.boardLayer.removeChild(enemyHit)
              }
              this.removeItem(this.bulletList, bullet)
              this.effectLayer.removeChild(bullet)
            }
          }
        }
},
....
 enemyDamage (enemy, damage) {
        enemy.hp -= damage
      },

boardTick函数会被主循环函数调用,它会调用castleTick函数,于是炮台对象会不断的创建子弹对象。然后代码通过两个循环轮询外星人数组和子弹数组,它从子弹数组中取出子弹对象,将子弹所在的坐标转换成页面上的行和列,接着根据行和列到外星人分布图,也就是enemyMap中查询,如果对应的位置有外星人对象,那表明子弹击中了外星人。此时代码调用enemyDamage函数计算外星人被击中后会掉多少血,如果外星人的能力耗尽,那么if(enemyHit.hp <=0)部分的代码会被执行,于是外星人对象就会从页面上被删除。同时不管外星人是否被摧毁,最后的两句代码:

this.removeItem(this.enemyList, bullet)
this.effectLayer.removeChild(bullet)

都会把子弹从页面上去除。完成以上代码后,图片所示的效果就可以完成了。

原文发布于微信公众号 - Coding迪斯尼(gh_c9f933e7765d)

原文发表时间:2018-05-04

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏转载gongluck的CSDN博客

WaitForMultipleObjects用法详解,一看就懂

WaitForMultipleObjects是Windows中的一个功能非常强大的函数,几乎可以等待Windows中的所有的内核对象 函数原型为: DWORD...

3427
来自专栏数据结构与算法

1098 均分纸牌

1098 均分纸牌 2002年NOIP全国联赛提高组  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 黄金 Gold 题解 题目描述 D...

3648
来自专栏iOSer成长记录

OpenGL ES(二) 三角形

1463
来自专栏Windows Community

Windows Community Toolkit 4.0 - DataGrid - Part01

在上面一篇 Windows Community Toolkit 4.0 - DataGrid - Overview 中,我们对 DataGrid 控件做了一个概...

1152
来自专栏一枝花算不算浪漫

[Java拾遗一] XML的书写规范与解析.

47720
来自专栏Android知识点总结

看得见的数据结构Android版之单链表篇

621
来自专栏Hongten

spring开发_Annotation_AOP_Before增强处理

http://www.cnblogs.com/hongten/gallery/image/112691.html

952
来自专栏三流程序员的挣扎

Flutter 学习记3 - Widget 框架

通过 widgets 构建 UI,描述当前的配置和状态,当状态改变时,框架找出前后的变化,以确定底层 Render Tree 要做的最小更改,在内部变成另一个状...

1311
来自专栏跟着阿笨一起玩NET

运行时自定义PropertyGrid显示属性项目

在PropertyGrid所显示的属性内容包括属性分类(Category)及组件属性,

1772
来自专栏码匠的流水账

springboot2增加diskspace指标

spring-boot-actuator-autoconfigure-2.0.1.RELEASE-sources.jar!/org/springframewor...

3001

扫码关注云+社区

领取腾讯云代金券