CocosCreator之KUOKUO带你做疯狂炮台-分裂(源码分享)(3)

本次引擎2.0.5

编辑工具VSCode

目标:

第三部分:物体碰撞分裂效果。

这个跟第二部分独立,第二部分是一种游戏玩法,第三部分将是另一种玩法。

文章最后给出源码下载!!!!

好,我们拿出第一部分完成的部分(可以看我之前的博客:疯狂炮台(1)),

(第一部分我们完成了:炮台随手指移动,有边界检测,无限子弹。)

我们在此基础上把画布和背景弄成竖屏的,就是640*960(炮台的边界也改一下);

然后我们加个地面(单色精灵)高100;

好,然后我们弄出一个大物体stone_big;

记录最低点y:-280;

设定最高点y:250;

然后我们写个脚本让它能在画布左右往复;

stone_big.js

cc.Class({
    extends: cc.Component,

    properties: {
        // 方向标志,默认先往左
        fangxiang : -1,
        // 速度
        speed : 200,
    },

    update (dt) {
        // 过边界就换方向
        if (this.node.x >= 500){
            this.fangxiang = -1;
        }
        if (this.node.x <= -500){
            this.fangxiang = 1;
        }
        // 改变位置
        this.node.x += this.fangxiang * this.speed * dt;
    },
});

在往复运动;

接下来,分组;

给stone_big加上碰撞盒子,设定分组为stone,拖过去成预制体:

建个预制体文件夹,然后顺手把层级里的删了;

好了,我们弄个空节点stoneManager来管理石头(坐标统一为与根节点相同便于计算):

绑定上脚本stoneManager.js

cc.Class({
    extends: cc.Component,

    properties: {
        stone_big : cc.Prefab,
    },
    
    onLoad () {
        // 开启碰撞检测
        cc.director.getCollisionManager().enabled = true;
        this.stone_big_Pool = new cc.NodePool();
        let initCount = 15;
        for (let i = 0; i < initCount; ++i) {
            let stone_big = cc.instantiate(this.stone_big); // 创建节点
            this.stone_big_Pool.put(stone_big); // 放入对象池
        }
    },

    start () {
        this.createStone_big();
    },

    createStone_big () {
        let stone_big = null;
        // 通过 size 接口判断对象池中是否有空闲的对象
        if (this.stone_big_Pool.size() > 0) { 
            stone_big = this.stone_big_Pool.get();
        } 
        // 如果没有空闲对象,也就是对象池中备用对象不够时,我们就用 cc.instantiate 重新创建
        else {
            stone_big = cc.instantiate(this.stone_big);
        }
        // 将生成的石头加入节点树
        stone_big.parent = this.node; 
        // 设定位置,之前设定高度250
        stone_big.position = cc.v2(500,250);
        // 设定动作,我示范就写简单点
        // 之前记录最低-280,最高250
        // 280 + 250 = 530
        let act_1 = cc.moveBy(1,0,-530);
        let act_2 = cc.moveBy(1,0,530);
        // 重复序列动作
        stone_big.runAction(cc.repeatForever(cc.sequence(act_1,act_2)));
    },
});

这样大石头就会往复运动了。

(这里我只调用一次,你们按需求)

好,我们写一下碰撞函数;

在stone_big.js中写:

cc.Class({
    extends: cc.Component,

    properties: {
        // 方向标志,默认先往左
        fangxiang : -1,
        // 速度
        speed : 200,
    },

    onCollisionEnter(other, self) {
        // 碰撞后,我们让子弹停下并回收
        other.node.stopAllActions();
        other.node.parent.getComponent('bulletManager').bulletPool.put(other.node);
        // 我们获取一下大石头位置
        let pos_big = self.node.position;
        // 回收大石头
        self.node.stopAllActions();
        self.node.parent.getComponent('stoneManager').stone_big_Pool.put(self.node);
    },

    update (dt) {
        // 过边界就换方向
        if (this.node.x >= 500){
            this.fangxiang = -1;
        }
        if (this.node.x <= -500){
            this.fangxiang = 1;
        }
        // 改变位置
        this.node.x += this.fangxiang * this.speed * dt;
    },
});

这里头获取碰撞位置留着给分裂后小石头用;

好,我们接下来再弄个蓝色的小石头;

同理:单色节点,记录位置,最低-330,最高设为200

加碰撞盒,分组为stone,成预制体,绑定脚本;

stone_small.js

cc.Class({
    extends: cc.Component,

    properties: {
        // 方向标志,默认先往左
        fangxiang : -1,
        // 速度
        speed : 200,
    },

    update (dt) {
        // 过边界就换方向
        if (this.node.x >= 500){
            this.fangxiang = -1;
        }
        if (this.node.x <= -500){
            this.fangxiang = 1;
        }
        // 改变位置
        this.node.x += this.fangxiang * this.speed * dt;
    },
});

在这里我们先不写碰撞,一会好观测现象。

然后在stoneManager.js中:

拖过去,然后写函数:

给出代码:

前面我声明了stone_small_Pool对象池,并加入10个stone_small;

这是创建小石头的方法:

 // 小石头 给两个参数:左右飞flag , 位置
    createStone_small ( flag , pos ) {
        let stone_small = null;
        if (this.stone_small_Pool.size() > 0) { 
            stone_small = this.stone_small_Pool.get();
        } 
        else {
            stone_small = cc.instantiate(this.stone_small);
        }
        stone_small.parent = this.node; 
        // 碰撞点位置
        stone_small.position = pos;
        // 设置飞的方向
        stone_small.getComponent('stone_small').fangxiang = flag;
        // 重点来了
        // 之前记录最低-330,最高200
        // 330 + 200 = 530
        // 从该位置向下落,按比例算时间,自己画画图就懂了
        let time = (pos.y - (-330))/530;
        // 方向为下
        let act_xia = cc.moveBy(time,0,-1*(pos.y - (-330)));
        // 往复
        let act_1 = cc.moveBy(1,0,-530);
        let act_2 = cc.moveBy(1,0,530);
        let act_3 = cc.sequence(act_2,act_1);
        // 注意这里不能连续嵌套cc.reaptForever,会报错。我们可以设置100次重复
        stone_small.runAction(cc.sequence(act_xia,cc.repeat(act_3,100)));
    },

这样小石头的代码搞定,我们去大石头碰撞那里调用这个函数:


    onCollisionEnter(other, self) {
        // 碰撞后,我们让子弹停下并回收
        other.node.stopAllActions();
        other.node.parent.getComponent('bulletManager').bulletPool.put(other.node);
        // 我们获取一下大石头位置
        let pos_big = self.node.position;
        // 分裂小石头
        let stoneManager = self.node.parent.getComponent('stoneManager'); 
        stoneManager.createStone_small(1,pos_big);
        stoneManager.createStone_small(-1,pos_big);
        // 回收大石头
        self.node.stopAllActions();
        stoneManager.stone_big_Pool.put(self.node);
    },

来,让我们看看效果:

要撞上啦:

撞上后分解为两个小物体:

它会运动100次后没有动作(跟Forever几乎一样了,目前不清楚为何动作的sequence和Forever连续嵌套会报错)

怎么样,是不是又Get一项技能呢!

我把源码分享给大家,也请大家多多支持,点个关注呗,console.log(滑稽)

点击下载
提取:ly3w 

O(∩_∩)O~~

猜你喜欢

转载自blog.csdn.net/kuokuo666/article/details/84328207