運行起來,雖然主角飛機和敵機都在互相發射子彈,但是子彈打中了就和沒打中效果是一樣的。。
這一章我們就來處理子彈和飛機的碰撞問題。
我們所有的操作都是基於Main這個容器來做的。所以我就把這個處理放到Main里面,監聽Main的ENTER_FRAME事件
this.addEventListener(egret.Event.ENTER_FRAME, (e) => { //判斷子彈是否和飛機碰撞 let isHit = this._bullets.IsHit(this._Hero) // console.log("Hit:" + isHit) //判斷Enemy是否和主角碰撞 }, this)
這里面就兩個操作,一個是判斷主角子彈是否擊中敵機,敵機子彈是否擊中主角,因為是判斷子彈是否打中飛機,那么我們就在子彈的工廠類BulletFactory.ts里面做這個檢測操作
public IsHit(e: egret.DisplayObjectContainer): boolean { let arr = EnemyFactory.Init().GetIsUsePlane(); //1.從敵機對象池中取出已經在使用的飛機 let isHit = false; let hitevent = new HitEvent(HitEvent.EventString); for (var i = 0; i < this._bullet.length; i++) { if (this._bullet[i].IsUse == true) { //2.循環遍歷子彈對象池,使用IsUse狀態為true的子彈 if (this._bullet[i].btype == IdentityType.ENEMY) { //3.判斷子彈類型,如果是敵機發射的,那么就和主角進行碰撞檢測 isHit = GameUtils.hitTest(e, this._bullet[i]) hitevent.htype = HitType.ENEMY_TO_HERO; } if (this._bullet[i].btype == IdentityType.HERO) { //4.如果是主角發射的。那么就和第一步的取出來的數組進行碰撞檢測 for (var j = 0; j < arr.length; j++) { if (arr[j].IsUse) { isHit = GameUtils.hitTest(arr[j], this._bullet[i]) hitevent.enemy = arr[j]; hitevent.htype = HitType.HERO_TO_ENEMY; } } } if (isHit) { //如果碰撞檢測為true,那么觸發HitEvent事件,並傳遞檢測結果,並手動調用子彈的回收方法 this.dispatchEvent(hitevent); this._bullet[i].Recycle(); } } } return isHit; }
從敵機對象池中取出已經使用的敵機對象
public GetIsUsePlane(): EnemyPlane[] { let planes = []; for (var i = 0; i < this._enemys.length; i++) { if (!this._enemys[i].IsUse) { planes.push(this._enemys[i]) } } return planes; }
然后監聽HitEvent來對擊中的事件做操作。
判斷事件類型,知道是誰被擊中了,然后對應做出不同的處理,如果主角被擊中,那么可以做扣除HP值等操作,敵機被擊中,可以做主角加分,把敵機抹除掉等操作
this._bullets.addEventListener(HitEvent.EventString, (e: HitEvent) => { console.log("子彈碰撞事件觸發:" + e.htype) if (e.htype == HitType.ENEMY_TO_HERO) { //Hero被擊中 } if (e.htype == HitType.HERO_TO_ENEMY) { //Enemy被擊中 e.enemy.Recycle(); this._Score += 1; console.log("當前分數:" + this._Score); } }, this)
然后運行,就可以看到子彈擊中飛機,會被回收,然后觸發HitEvent事件。