iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 16
0
Modern Web

關於你關於我關於phaser系列 第 16

Day 16 塔防遊戲 ~ 發射子彈

  • 分享至 

  • xImage
  •  

我們要加入子彈,並且讓炮塔可以偵測敵人的位置是否進入自己的半徑範圍,有的話可以發射子彈,當子彈射中敵人就會有碰撞事件,而敵人會扣血,扣到血量爲零就消失

創建我們的子彈

var Bullet = new Phaser.Class({
    Extends: Phaser.GameObjects.Image,
    initialize:
    function Bullet (scene)
    {
        Phaser.GameObjects.Image.call(this, scene, 0, 0, 'bullet');
 
        this.dx = 0;
        this.dy = 0;
        this.lifespan = 0;
 
        this.speed = Phaser.Math.GetSpeed(600, 1);
    },
    fire: function (x, y, angle)
    {
        this.setActive(true);
        this.setVisible(true);
        
        this.setPosition(x, y);
 
        this.dx = Math.cos(angle);
        this.dy = Math.sin(angle);
 
        this.lifespan = 300;
    },
 
    update: function (time, delta)
    {
        this.lifespan -= delta;
 
        this.x += this.dx * (this.speed * delta);
        this.y += this.dy * (this.speed * delta);
 
        if (this.lifespan <= 0)
        {
            this.setActive(false);
            this.setVisible(false);
        }
    }
});

有幾個要注意的地方,我們會透過 sin 跟 cos 算他的斜率,讓他可以朝偵測到敵人的位置飛過去,並且設定兩個參數: this.speed 、 this.lifespan ,子彈速度越快、子彈存活時間越長就可以達到越遠的敵人,

將子彈加入地圖

function create(){
    bullets = this.add.group({ classType: Bullet, runChildUpdate: true });
}

撰寫獲取敵人半徑與發射子彈的方法

function getEnemy(x, y, distance) {
    var enemyUnits = enemies.getChildren();
    for(var i = 0; i < enemyUnits.length; i++) {       
        if(enemyUnits[i].active && Phaser.Math.Distance.Between(x, y, enemyUnits[i].x, enemyUnits[i].y) <= distance)
            return enemyUnits[i];
    }
    return false;
}
function addBullet(x, y, angle) {
    var bullet = bullets.get();
    if (bullet)
    {
        bullet.fire(x, y, angle);
    }
}

並讓炮塔可以偵測敵人半徑與射出子彈

var Turret = new Phaser.Class({
     // ...
  initialize: 
  
  function Turret(scene) {
    //...
    this.nextTic = 0
  },
  //...
  fire: function() {
    //偵測敵人是否到半徑的範圍(第三個參數)
    var enemy = getEnemy(this.x, this.y, 500)
    if (enemy) {
      var angle = Phaser.Math.Angle.Between(this.x, this.y, enemy.x, enemy.y)
      addBullet(this.x, this.y, angle)
      this.angle = (angle + Math.PI / 2) * Phaser.Math.RAD_TO_DEG
    }
  },
  update: function(time, delta) {
    if (time > this.nextTic) {
      this.fire()
      this.nextTic = time + 1000
    }
  }
})

炮塔的射擊速度取決於 nextTic ,每隔多久就射一發子彈

如果都沒有報錯,這邊就可以偵測到敵人並且射出子彈,但是會發現子彈會穿過敵人,這就是明天要完成的最後:碰撞與扣血

學習的網站
我的github


上一篇
Day 15 塔防遊戲 ~ 建立炮塔
下一篇
Day 17 塔防遊戲 ~ 完成啦
系列文
關於你關於我關於phaser30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言