先区分要监听谁,子弹打到飞机上,飞机去播放动画,并完成销毁操作,注册碰撞事件就写在飞机上。
飞机预制体都绑定了Enemy.ts
,注册事件就写到这个文件内
import { _decorator, Animation, Collider2D, Component, Contact2DType, IPhysics2DContact, Node } from 'cc';
const { ccclass, property } = _decorator;
@ccclass('Enemy')
export class Enemy extends Component {
/**
* collider:Collider2D 注册碰撞事件
* speed:number 控制敌机 从上到下的移动,多少米每秒的向下移动
* hp:number 控制飞机的血量,默认小飞机血量为1,不同的飞机血量也不同
* anim:Animation 控制飞机的销毁动画
* animHit 飞机被击中的动画
* animDown 飞机没有血量后,坠落的动画
*/
collider:Collider2D = null;
@property
speed:number = 300;
@property
hp:number = 1
@property(Animation)
anim:Animation = null;
@property(String)
animHit:string = '';
@property(String)
animDown:string = '';
start() {
// 注册单个碰撞体的回调函数
this.collider = this.getComponent(Collider2D);
if (this.collider) {
this.collider.on(Contact2DType.BEGIN_CONTACT, this.onBeginContact, this);
}
}
protected onDestroy(): void {
// 销毁
if (this.collider) {
this.collider.off(Contact2DType.BEGIN_CONTACT, this.onBeginContact, this);
}
}
// 发生接触的方法
/**
*
* @param selfCollider 指的是回调脚本的节点上的碰撞体(当前的飞机);
* @param otherCollider 指的是发生碰撞的另一个碰撞体(子弹);
* @param contact
*/
onBeginContact(selfCollider: Collider2D, otherCollider: Collider2D, contact: IPhysics2DContact | null){
/**
* otherCollider.getComponent:判断碰撞类型是否是子弹,
* otherCollider.enabled = false 这段代码理解为子弹和飞机碰撞发生后,销毁碰撞的子弹。
* 但是这里有个BUG,如果飞机A碰撞到了飞机B,也会触发otherCollider,可能会把飞机销毁。
* 需要修改为:只让子弹和敌机发生碰撞,飞机A和飞机B之间不能发生碰撞
* 在触发器:BoxCollider2D中有一个Group选项,可以设置那些组和哪些组之间发生碰撞
*
*
* 如果血量>0,播放被击中的动画
* 如果血量<0,播放坠落的动画
* 如果血量<=0了
* 就要禁用这个监听,否则会出现重复播放动画的BUG
* scheduleOnce:定时器1秒后,就销毁掉当前这个飞机
*/
if(otherCollider.getComponent(Bullet)){
otherCollider.enabled = false;
}
this.hp -= 1;
if(this.hp>0){
this.anim.play(this.animHit)
}else{
this.anim.play(this.animDown)
}
if(this.hp<=0){
// 血量==0了,就需要禁用这个监听。否则会重复播放动画。
if(this.collider){
this.collider.enabled = false;
}
// 等动画播放完成,1秒后在销毁
this.scheduleOnce(function(){
this.node.destroy()
},1)
}
}
update(deltaTime: number) {
// 如果血量大于0,就沿Y轴自上向下运动
if(this.hp>0){
const pos = this.node.position;
this.node.setPosition(pos.x,pos.y-this.speed*deltaTime,pos.z)
}
// 以最大的飞机为例,超出屏幕边界是-600,超过这个边界,就销毁掉
if(this.node.position.y<-600){
this.node.destroy()
}
}
}
触发器:BoxCollider2D的Group选项,可以设置那些组和哪些组之间发生碰撞
设置好分组之后,去预制体中勾选对应的分组完成
子弹设置分组也一样,选择Bullet
分组