COCOS:(飞机大战09)敌机注册碰撞事件,控制敌机的销毁

先区分要监听谁,子弹打到飞机上,飞机去播放动画,并完成销毁操作,注册碰撞事件就写在飞机上。
在这里插入图片描述

飞机预制体都绑定了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分组

在使用cocos2d-x开发飞机大战游戏时,敌机发射子弹的逻辑可以分解为以下几个步骤: 1. 创建子弹类:首先需要创建一个子弹的类,继承自cocos2d-x中的`Sprite`类,用于管理子弹的属性和行为。 ```cpp class Bullet : public cocos2d::Sprite { public: Bullet(); // 构造函数 virtual ~Bullet(); // 析构函数 // 初始化子弹位置等属性的方法 void init(float x, float y); // 子弹移动的逻辑 void update(float delta); }; ``` 2. 在敌机类中添加子弹发射功能:敌机类中应该有一个方法用于控制子弹的发射。这个方法可以被定时调用,比如每一秒钟发射一次。 ```cpp class Enemy : public cocos2d::Sprite { public: virtual void onEnter(); // 敌机进入屏幕时的逻辑 virtual void shoot(); // 发射子弹的方法 // ... 其他敌机相关的方法和属性 }; ``` 3. 实现子弹的发射和移动:在子弹类中实现`update`方法来控制子弹的移动,比如让它向左上方移动一定的速度。 ```cpp void Bullet::update(float delta) { // 更新子弹的位置,使其向上和向左移动 this->setPosition(cocos2d::Vec2(getPositionX() - SPEED * delta, getPositionY() - SPEED * delta)); // 检查子弹是否出界,如果出界则移除子弹 if (getPositionX() < 0 || getPositionY() < 0) { removeFromParentAndCleanup(true); } } ``` 4. 控制敌机发射子弹:在敌机类中,实现`shoot`方法,让敌机定期生成子弹。 ```cpp void Enemy::shoot() { if (shouldShoot) { // 根据某种逻辑判断是否发射子弹 // 创建一个子弹实例 Bullet *bullet = Bullet::create(); // 初始化子弹位置在敌机的下方中心位置 bullet->init(getPositionX(), getPositionY() + this->getContentSize().height / 2); // 将子弹添加到游戏中,比如可以添加到Layer或者Director中 this->getParent()->addChild(bullet); // 让子弹开始移动 bullet->runAction(cocos2d::MoveBy::create(BULLET_DURATION, cocos2d::Vec2(0, -BULLET_SPEED))); } } ``` 5. 调度敌机发射子弹:在敌机的`onEnter`方法中设置定时器来定期调用`shoot`方法。 ```cpp void Enemy::onEnter() { // ... 省略其他初始化代码 // 设置定时器,每1秒发射一次子弹 this->schedule_selector(Enemy::shoot, 1.0f); } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值