aircraft-war(四)
敵機分為三種類型,所以需要三種Prefab,分別有自己的爆炸動畫,可以共用一套腳本,要隨機出現X軸初始位置。
接下來先制作一個“可以被擊落的敵機”:
敵機Demo
從資源選擇器中拖拽素材到層級選擇器 → 添加碰撞組件 → 添加動畫組件(在資源管理器創建動畫資源) → 編寫腳本 → (將組建從層級選擇器拖拽到資源選擇器(Prefab資源))
碰撞組件之前剛做過,再次跳過,下圖為添加動畫組件:
image.png
接下來編寫腳本:
// enemy.js
cc.Class({
extends: cc.Component,
properties: {
HP: {
default: 0,
type: cc.Integer,
tooltip: '敵機血量',
},
speedMax: 0,
},
// use this for initialization
onLoad: function () {
this.speed = cc.random0To1() * this.speedMax;
let manager = cc.director.getCollisionManager();
manager.enabled = true;
},
//碰撞檢測
onCollisionEnter: function(other, self){
},
// called every frame, uncomment this function to activate update callback
update: function (dt) {
this.node.y -= dt * this.speed;
},
onHandleDestroy: function () {
// Demo中零時使用,后續要使用對象池,參考bullet
this.node.destroy();
}
});
接下來需要給子彈Prefab添加碰撞組件。
在這里會遇到一個問題,各個組件都有碰撞組件,那敵機相互不就撞毀了嗎?有沒有什么辦法可以限制碰撞對象?
碰撞分組管理
使用碰撞分組管理:
image.png
之后在組件的屬性檢查器中選擇分組:
image.png
接下來修改腳本:
cc.Class({
extends: cc.Component,
properties: {
HP: {
default: 0,
type: cc.Integer,
tooltip: '敵機血量',
},
speedMax: 0,
},
// use this for initialization
onLoad: function () {
// 速度隨機[speedMax, speedMin]
this.speed = Math.random() * (this.speedMax - this.speedMin + 1) + this.speedMin;
let manager = cc.director.getCollisionManager();
manager.enabled = true;
},
//碰撞檢測
onCollisionEnter: function(other, self){
if (other.node.group !== 'bullet') {
return;
}
if (this.HP === 0) {
this.HP--;
let anim = this.getComponent(cc.Animation);
let animName = this.node.name + '_exploding';
anim.play(animName);
anim.on('finished', this.onHandleDestroy, this);
return;
}
if (this.HP > 0) {
this.HP--;
}
},
// called every frame, uncomment this function to activate update callback
update: function (dt) {
this.node.y -= dt * this.speed;
},
onHandleDestroy: function () {
// Demo中零時使用,后續要使用對象池,參考bullet
this.node.destroy();
}
});
Bullet:
cc.Class({
// ...
//碰撞檢測
onCollisionEnter: function(other, self){
this.bulletGroup.destroyBullet(self.node);
},
// ...
});
第一步就算完成了,實現功能是第一步,接下來要做的就是使用對象池,制作大批敵機,處理敵機出現的位置:
image.png
敵機組
先將其他兩種類型的敵機做成Prefab作為準備資源,然后創建參考bulletGroup的制作方式,來制作enemyGroup。
image.png
腳本代碼請參考——敵機組起飛代碼
現在敵機組也起飛了,但是有個問題,被銷毀的敵機回歸對象池后,下一次出場時,還保持著被銷毀時的狀態,所以需要初始化一下:
image.png
給enemy.js添加初始化函數:
// enemy.js
enemyInit: function () {
// 初始化血量
this.enemyHp = this.HP;
// 找到node的Sprite組件
let nSprite = this.node.getComponent(cc.Sprite);
// 初始化spriteFrame
if (nSprite.spriteFrame != this.initSpriteFrame){
nSprite.spriteFrame = this.initSpriteFrame;
}
},
// 碰撞檢測
onCollisionEnter: function(other, self){
if (other.node.group !== 'bullet') {
return;
}
if (this.enemyHp === 0) {
this.enemyHp--;
let anim = this.getComponent(cc.Animation);
let animName = this.node.name + '_exploding';
anim.play(animName);
anim.on('finished', this.onHandleDestroy, this);
return;
}
if (this.enemyHp > 0) {
this.enemyHp--;
}
},
然后在創建敵機的時候,要執行一遍初始化函數:
// enemyGroup.js
// 生成敵機
genNewEnemy: function (enemyInfo) {
let poolName = enemyInfo.name + 'Pool';
let newNode = D.common.genNewNode(this[poolName], enemyInfo.prefab, this.node);
let pos = this.getNewEnemyPosition(newNode);
newNode.setPosition(pos);
newNode.getComponent('enemy').enemyGroup = this;
// 初始化敵機狀態
newNode.getComponent('enemy').enemyInit();
},
參考代碼在這里
到這里,整體主要功能都已經實現,接下來要完成的,是游戲的積分、開始暫停與音效。