通过「解救人质」小游戏教你学会碰撞检测

获取源码

       关注公众号,发送【解救人质】获取源码。

       游戏开发中,碰撞检测无处不在,今天就通过一个简单的小游戏教你学会如何在 Cocos Creator 中进行碰撞检测。配合官方文档学习效果更加(官方文档传送门:https://docs.cocos.com/creator/manual/zh/physics/collision/),关注公众号「游戏开发小白变怪兽」后台回复「解救人质」获取美术资源及源码。

游戏玩法:

       通过控制手枪位置,松手发射子弹击中躲在人质后面的歹徒顺利解救人质,小心不要打中人质哦!

实现逻辑:

        分别给子弹、人质和歹徒添加碰撞组件,检测到子弹与歹徒发生碰撞时,营救成功;检测到子弹与人质发生碰撞时,营救失败。

步骤详解:

       1.按照图中节点树创建节点,分别将对应贴图拖给对应的节点,并设置节点位置如图,successLabel 和 failLabel 内容分别为「解救成功!」和「解救失败!」:

       2.给 hostage 节点添加碰撞组件,并设置组件 Tag 属性和 Size 属性:

        当一个节点上有多个碰撞组件时,在发生碰撞后,可以使用 Tag 来判断是节点上的哪个碰撞组件被碰撞了。此时,碰撞组件大小和节点大小一致,同样的步骤将 enemy 和 bullet 节点添加好碰撞组件。


        3.接下来在项目设置面板里添加分组:hostage、enemy 和 bullet(注:分组添加后是不可以删除的,不过你可以任意修改分组的名字),并勾选hostage 和 bullet、enemy 和 bullet:

        4.在项目设置添加好分组后,分别在 hostage、enemy 和 bullet 属性中的 Group 设置对应分组:

        5.接下来新建 Bullet.js 脚本挂载到 bullet 节点下,编辑脚本如下,主要在 update 方法内实现了子弹的移动和销毁,以及碰撞回调函数(注:使用碰撞检测之前一定要获取碰撞检测,且碰撞回调函数名称固定,无需注册!):

// Bullet.js


cc.Class({
    extends: cc.Component,


    properties: {
        mSpeed: 300,
    },


    // LIFE-CYCLE CALLBACKS:


    // onLoad () {},


    start() {
        var manager = cc.director.getCollisionManager();    // 获取碰撞检测系统
        manager.enabled = true;
    },


    update(dt) {    // 设置子弹移动,当超出屏幕范围未发生碰撞时自动销毁
        this.node.y += this.mSpeed * dt;


        if (this.node.y > 580) {
            console.log('超出屏幕范围,子弹销毁!');


            this.node.destroy();
        }
    },


    /**
    * 当碰撞产生的时候调用
    * @param  {Collider} other 产生碰撞的另一个碰撞组件
    * @param  {Collider} self  产生碰撞的自身的碰撞组件
    */
    onCollisionEnter: function (other, self) {
        console.log('on collision enter');


        if (other.tag == 1) {    // 子弹碰到人质时,解救失败!
            console.log('解救人质失败!');


            var failLabel = this.node.parent.getChildByName('failLabel');
            failLabel.active = true;


            this.node.destroy();


        } else if (other.tag == 2) {    // 子弹碰到敌人时,解救成功!
            console.log('解救人质成功!');


            var successLabel = this.node.parent.getChildByName('successLabel');
            successLabel.active = true;


            this.node.destroy();
        }
    },


    /**
    * 当碰撞产生后,碰撞结束前的情况下,每次计算碰撞结果后调用
    * @param  {Collider} other 产生碰撞的另一个碰撞组件
    * @param  {Collider} self  产生碰撞的自身的碰撞组件
    */
    onCollisionStay: function (other, self) {
        console.log('on collision stay');
    },


    /**
    * 当碰撞结束后调用
    * @param  {Collider} other 产生碰撞的另一个碰撞组件
    * @param  {Collider} self  产生碰撞的自身的碰撞组件
    */
    onCollisionExit: function (other, self) {
        console.log('on collision exit');
    }
});

编写完脚本后,将 bullet 节点保存为预制件待用。

6.然后编写 gun 节点的控制逻辑脚本 ControlGun.js:

// ControlGun.js


cc.Class({
    extends: cc.Component,


    properties: {
        mBullet: cc.Prefab
    },


    // LIFE-CYCLE CALLBACKS:


    onLoad() { },


    start() {
        this.node.on('touchstart', this.onTouchStart, this);
        this.node.on('touchmove', this.onTouchMove, this);
        this.node.on('touchend', this.ontouchEnd, this);
    },


    // update (dt) {},


    onTouchStart(event) {    // 每次点击之前,都要把结果关掉
        var successLabel = this.node.parent.getChildByName('successLabel');
        successLabel.active = false;


        var failLabel = this.node.parent.getChildByName('failLabel');
        failLabel.active = false;
    },


    onTouchMove(event) {    // 控制节点在屏幕范围内左右移动
        let rangePos = event.getDelta();


        this.node.x += rangePos.x;


        let minX = -this.node.parent.width / 2 + this.node.width / 2;
        let maxX = Math.abs(minX);


        let currentPos = this.node.getPosition();


        if (currentPos.x < minX) {
            currentPos.x = minX;
        } else if (currentPos.x > maxX) {
            currentPos.x = maxX;
        }


        this.node.setPosition(currentPos);
    },


    ontouchEnd(event) {    // 松开时发射子弹
        console.log('发射子弹');


        let bullet = cc.instantiate(this.mBullet);
        bullet.parent = this.node.parent;


        let currentPos = this.node.getPosition();


        bullet.parent = this.node.parent;
        bullet.setPosition(currentPos);
    }
});

7.最后编写 enemy 的移动脚本:

// ControlEnemy.js


cc.Class({
    extends: cc.Component,


    properties: {
        mSpeed: 300
    },


    // LIFE-CYCLE CALLBACKS:


    // onLoad () {},


    start() {
        this.minX = -this.node.parent.width / 2 + this.node.width / 2;
        this.maxX = Math.abs(this.minX);
    },


    update(dt) {
        let currentPos = this.node.getPosition();


        if (currentPos.x < this.minX) {
            this.mSpeed = Math.abs(this.mSpeed);
        } else if (currentPos.x > this.maxX) {
            this.mSpeed = -Math.abs(this.mSpeed);
        }


        this.node.x += this.mSpeed * dt;
    }
});

8.编写完所有的脚本之后,就可以预览游戏了,快来试试你能不能成功的就下人质吧!

更多游戏:

☞ 数钱      ☞ 左右跳    ☞ 重力球   ☞ 打地鼠 

☞ 推箱子   ☞ 扫雷       ☞ 跑酷      ☞ 动物同化

☞ 打飞机   ☞ 撑杆跳   ☞ 六边形   ☞ 口红机 

☞ 当官消消乐     ☞ 虚拟摇杆

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值