小老鼠历险记Cocos Creator

1.设计思路

突发奇想设计一个游戏,游戏名是《小老鼠历险记》,设计思路是一只可怜的小老鼠,他的敌人是猫和狗,它的活动区间只能是他的窝窝附近,不时还有猫猫和狗狗想吃它,所以小老鼠要走位躲过他们的偷袭,然而因为狗狗还是比较喜欢是骨头,所以和老鼠达成一个协议,可以用一个骨头换帮我对付一只猫,如果我没有骨头,狗狗就把我吃了,所以我一边要躲他们,一边收集骨头和狗一起攻击猫,玩家操纵小老鼠,让小老鼠生存下去。

2.结果展示

在这里插入图片描述
在这里插入图片描述

3. 实现逻辑

3.1 操控小老鼠
在这里插入图片描述
小老鼠的操控方式为键盘操控,分别为
w->向上 s->向下 a->向左 d->向右
设计的方式为设置一个速度变量,分别为横轴和纵轴的速度,向右 向上为正,向下 向左为负。在update()中更新小老鼠的位置。
在这里插入图片描述
在这里插入图片描述
为小老鼠添加监听器,分别为w,a,s,d键的按下和松开。

    //键盘按下事件
    onKeyDown(event){
        switch(event.keyCode) {
            //按下a,则老鼠向前
            case cc.macro.KEY.w:
                console.log('老鼠前进');
                this.DirectionY = 1;
                break;
            case cc.macro.KEY.s:
                console.log('老鼠后退');
                this.DirectionY = -1;
                break;
            case cc.macro.KEY.a:
                console.log('老鼠向左');
                this.DirectionX = -1;
                break;
            case cc.macro.KEY.d:
                console.log('老鼠向右');
                this.DirectionX = 1;
                break;
        }
    }
    //按键松下事件
    onKeyUp(event){
        if(event.keyCode==cc.macro.KEY.w&&this.DirectionY==1){
            this.DirectionY=0;
        }
        if(event.keyCode==cc.macro.KEY.s&&this.DirectionY==-1){
            this.DirectionY=0;
        }
        if(event.keyCode==cc.macro.KEY.a&&this.DirectionX==-1){
            this.DirectionX=0;
        }
        if(event.keyCode==cc.macro.KEY.d&&this.DirectionX==1){
            this.DirectionX=0;
        }
    }

3.2 为小老鼠设置活动区间
在这里插入图片描述
小老鼠的活动区间为下方边界和木棍组成的区间,若没有区间限制,小老鼠就会在键盘的控制下,跃出游戏界面。
这里采用了刚体的方法,设置方法如下:
小老鼠的刚体:
在这里插入图片描述

设置为圆形的刚体,这里类型设置为Dynamic,
box2d 原本的刚体类型是三种:Static、Dynamic、Kinematic。Cocos Creator 多添加了一个类型:Animated。分别为静态、动态、运动学。取消睡眠,设置重力加速度为0.
为边界和木棍设置刚体,设置方式和小老鼠类似:
在这里插入图片描述
这里注意:一开始我在操纵老鼠的时候,老鼠可以越界,询问了一下,问题是刚体要全部设置为不休眠,这样才不会出现越界问题。
现在运行程序,就可以实现键盘控制小老鼠在制定区间活动了。

onLoad () {
        //给老鼠添加监听器
        cc.systemEvent.on(cc.SystemEvent.EventType.KEY_DOWN, this.onKeyDown, this);
        cc.systemEvent.on(cc.SystemEvent.EventType.KEY_UP, this.onKeyUp, this);
        //开启物理特性
        cc.director.getPhysicsManager().enabled = true;
        //开启碰撞检测
        cc.director.getCollisionManager().enabled = true;
    }

记得要开启物理特性,不然还是没有刚体的效果。
3.3 骨头,猫,狗掉落效果

他们的实现方法类似,都是先把图片拖到场景里面,然后加载脚本,再拖到资源管理器,成为预设体。
以骨头为例,脚本为:

const {ccclass, property} = cc._decorator;

@ccclass
export default class BoneControl extends cc.Component {

    // LIFE-CYCLE CALLBACKS:
    @property
    Speed: number = 100;//骨头移动速度

    // onLoad () {}

    start () {

    }

    update (dt) {
        this.node.y -= this.Speed*dt;
        if(this.node.y<-755){
            this.die();
        }
    }

    die(){
        this.node.destroy();
    }
}

注意越界后要去销毁。挂载好脚本后,设置为预设体
在这里插入图片描述
3.4 设置批量产生猫,狗,骨头
这里我设置了一个空节点,猫,狗,骨头都生成在该节点下面
在这里插入图片描述
为该空节点挂载脚本
要想实现批量产生猫,狗和骨头,就要引用他们的脚本和控件。
在这里插入图片描述
设置一个计时器,每隔一段时间就随机产生一个精灵。
这里利用schedule()方法,每隔0.8s就从猫,狗和骨头选一个生成,初始位置为空节点的高度,水平位置为游戏屏幕宽度之间的随机位置。

onLoad () {        
        this.schedule(function() {
            //随机产生一个随机数确定是产生猫还是狗还是骨头
            let randn = Math.random()*100;
            if(randn>=0&&randn<=30){
                //生成骨头
                this.chooseBorn = 1;
            }
            else if(randn>30&&randn<=70){
                //生成猫
                this.chooseBorn = 2;
            }
            else{
                //生成狗
                this.chooseBorn = 3;
            }

            let thing = null;
            switch(this.chooseBorn){
                case 1:
                    thing = cc.instantiate(this.BonePre);
                    break;
                case 2:
                    thing = cc.instantiate(this.CatPre);
                    break;
                case 3:
                    thing = cc.instantiate(this.DogPre);
                    break;
            }
            //获得当前的场景
            let scene = cc.director.getScene();
            //设置骨头的父节点
            thing.parent = scene;
            //设置位置
            thing.y = this.node.y;//y和节点位置相同
            thing.x = Math.random()*400;
        }, 0.8);
    }

生成后设置父节点,这样就产生随机生成猫,狗和骨头的效果了。
3.5 设置碰撞事件
为每个事物添加碰撞,以老鼠为例
在这里插入图片描述
这里设置为圆形碰撞,为每个事物设置不同的Tag,这里我设置为Tag=1为骨头,Tag=0是老鼠,Tag=2是猫,Tag=3是狗,可以在预设体中设置,也可以一开始就设置碰撞再设置为预设体,预设体中设置记得保存。
接下来,在老鼠的脚本中实现碰撞检测:
在onCollisionStay(other)函数中,根据other的tag值判断碰撞的是什么事物。

//检测碰撞
    onCollisionStay(other){
        if(other.tag==1){
            //如果接到的是骨头
            console.log("与骨头发生碰撞")
            this.BoneNumber++;
            this.num_Bones.string = this.BoneNumber+"";
            let bone = other.getComponent(BoneControl);
            bone.die();
        }
        if(other.tag==2){
            //如果接到的是猫
            console.log("与猫发生碰撞")
            let cat = other.getComponent(CatControl);
            //检测有没有和狗的协议
            if(this.DealNumber>0){
                //协议数减一
                this.DealNumber--;
                this.num_agreenments.string = this.DealNumber+"";
                //猫死亡
                cat.die();
                this.KillCatNumber++;
                this.num_kills.string = ""+this.KillCatNumber;
            }
            else{
                //猫胜利
                cat.vectory();
                //自己死亡
                this.die();
            }
        }
        if(other.tag==3){
            console.log("与狗发生碰撞")
            //如果接到的是狗
            let dog = other.getComponent(DogControl);
            //检测骨头数是否大于0,用于和狗狗交易
            if(this.BoneNumber>0){
                //骨头数减一
                this.BoneNumber--;
                this.num_Bones.string = this.BoneNumber+"";
                //狗狗离开
                dog.die();
                //协议数加一
                this.DealNumber++;
                this.num_agreenments.string = this.DealNumber+"";
            }
            else{
                //狗狗胜利
                dog.vectory();
                //狗狗吃了老鼠
                this.die();
            }
        }
    }

在这里插入图片描述

碰撞处理的方法大致为获得碰撞体的脚本,然后处理各种情况,更新结果。
情况分为:
1.碰到的是骨头
接收骨头,骨头数+1,然后销毁骨头
2.碰到的是猫
判断是否有协议,如果协议大于等于1,则协议数-1,销毁猫,杀死猫的个数+1。
否则,销毁老鼠和猫,游戏结束,猫胜利。
3.碰到的是狗
判断收集的骨头数,若大于等于1则和狗达成协议,协议数+1,骨头数-1,销毁狗,
否则,销毁老鼠和狗,游戏结束,狗胜利。

3.6 记录游戏中的参数
在这里插入图片描述
Killed Cat为杀死猫的个数
Left Bone为剩下的骨头数
Agreements为协议数
添加控制,每当参数改变的时候,更新Label的值
在这里插入图片描述
玩家在游戏过程中注意自己的骨头数是否大于0,才能和狗进行交易,并且只有当手中有协议的时候,才能和猫抗衡。

4.程序代码及框架

4.1 层级管理器
在这里插入图片描述
4.2 脚本代码
4.2.1 BoneControl.ts

const {ccclass, property} = cc._decorator;

@ccclass
export default class BoneControl extends cc.Component {

    // LIFE-CYCLE CALLBACKS:
    @property
    Speed: number = 100;//骨头移动速度

    

    // onLoad () {}

    start () {

    }

    update (dt) {
        this.node.y -= this.Speed*dt;
        if(this.node.y<-755){
            this.die();
        }
    }

    die(){
        this.node.destroy();
    }
}

4.2.2 CatControl.ts

const {ccclass, property} = cc._decorator;

@ccclass
export default class CatControl extends cc.Component {
    //计分控件
    @property(cc.Label)
    num_kills: cc.Label = null;

    //计分控件
    @property(cc.Label)
    num_Bones: cc.Label = null;

    @property
    Speed: number = 200;//猫移动的速度

    // onLoad () {}

    start () {

    }

    update (dt) {
        this.node.y -= this.Speed*dt;
        if(this.node.y<-755){
            this.die();
        }
    }

    die(){
        this.node.destroy();
    }

    vectory(){
        console.log("猫猫胜利");
    }
}

4.2.3 DogControl.ts


const {ccclass, property} = cc._decorator;

@ccclass
export default class DogControl extends cc.Component {

    @property
    Speed: number = 200;//猫移动的速度

    

    // onLoad () {}

    start () {

    }

    update (dt) {
        this.node.y -= this.Speed*dt;
        if(this.node.y<-755){
            this.die();
        }
    }

    die(){
        this.node.destroy();
    }

    vectory(){
        console.log("狗狗胜利")
    }
}

4.2.4 CreatorControl.ts

const {ccclass, property} = cc._decorator;

@ccclass
export default class CreatorControl extends cc.Component {

    // 骨头预设体
    @property(cc.Prefab)
    BonePre : cc.Prefab = null;

    //猫预设体
    @property(cc.Prefab)
    CatPre : cc.Prefab = null;

    //狗预设体
    @property(cc.Prefab)
    DogPre : cc.Prefab = null;


    chooseBorn: number = 0;
    
    onLoad () {        
        this.schedule(function() {
            //随机产生一个随机数确定是产生猫还是狗还是骨头
            let randn = Math.random()*100;
            if(randn>=0&&randn<=30){
                //生成骨头
                this.chooseBorn = 1;
            }
            else if(randn>30&&randn<=70){
                //生成猫
                this.chooseBorn = 2;
            }
            else{
                //生成狗
                this.chooseBorn = 3;
            }

            let thing = null;
            switch(this.chooseBorn){
                case 1:
                    thing = cc.instantiate(this.BonePre);
                    break;
                case 2:
                    thing = cc.instantiate(this.CatPre);
                    break;
                case 3:
                    thing = cc.instantiate(this.DogPre);
                    break;
            }
            //获得当前的场景
            let scene = cc.director.getScene();
            //设置骨头的父节点
            thing.parent = scene;
            //设置位置
            thing.y = this.node.y;//y和节点位置相同
            thing.x = Math.random()*400;
        }, 0.8);
    }

    start () {

    }

    // update (dt) {}
}

4.2.5 MouseControl.ts

import BoneControl from "./BoneControl";
import CatControl from "./CatControl";
import DogControl from "./DogControl";

const {ccclass, property} = cc._decorator;

@ccclass
export default class MouseControl extends cc.Component {

    @property
    Speed: number = 200;//老鼠移动速度

    //计分控件
    @property(cc.Label)
    num_kills: cc.Label = null;

    //计分控件
    @property(cc.Label)
    num_Bones: cc.Label = null;

    //计分控件
    @property(cc.Label)
    num_agreenments: cc.Label = null;

    DirectionX: number = 0;//0->不动,1->前,-1->后
    
    DirectionY: number = 0;//0->不动,1->右,-1->左

    /*
        游戏中记录结果的参数
    */

    BoneNumber: number = 0;//骨头的数目
    KillCatNumber: number = 0;//杀死猫的数目
    DealNumber: number = 0;//达成协议的个数

    onLoad () {
        //给老鼠添加监听器
        cc.systemEvent.on(cc.SystemEvent.EventType.KEY_DOWN, this.onKeyDown, this);
        cc.systemEvent.on(cc.SystemEvent.EventType.KEY_UP, this.onKeyUp, this);
        //开启物理特性
        cc.director.getPhysicsManager().enabled = true;
        //开启碰撞检测
        cc.director.getCollisionManager().enabled = true;
    }

    //键盘按下事件
    onKeyDown(event){
        switch(event.keyCode) {
            //按下a,则老鼠向前
            case cc.macro.KEY.w:
                console.log('老鼠前进');
                this.DirectionY = 1;
                break;
            case cc.macro.KEY.s:
                console.log('老鼠后退');
                this.DirectionY = -1;
                break;
            case cc.macro.KEY.a:
                console.log('老鼠向左');
                this.DirectionX = -1;
                break;
            case cc.macro.KEY.d:
                console.log('老鼠向右');
                this.DirectionX = 1;
                break;
        }
    }
    //按键松下事件
    onKeyUp(event){
        if(event.keyCode==cc.macro.KEY.w&&this.DirectionY==1){
            this.DirectionY=0;
        }
        if(event.keyCode==cc.macro.KEY.s&&this.DirectionY==-1){
            this.DirectionY=0;
        }
        if(event.keyCode==cc.macro.KEY.a&&this.DirectionX==-1){
            this.DirectionX=0;
        }
        if(event.keyCode==cc.macro.KEY.d&&this.DirectionX==1){
            this.DirectionX=0;
        }
    }
    start () {

    }

    //在update中修改位置更自然
    update (dt) {
        this.node.x+=this.DirectionX*this.Speed*dt;
        this.node.y+=this.DirectionY*this.Speed*dt;
    }

    //检测碰撞
    onCollisionStay(other){
        if(other.tag==1){
            //如果接到的是骨头
            console.log("与骨头发生碰撞")
            this.BoneNumber++;
            this.num_Bones.string = this.BoneNumber+"";
            let bone = other.getComponent(BoneControl);
            bone.die();
        }
        if(other.tag==2){
            //如果接到的是猫
            console.log("与猫发生碰撞")
            let cat = other.getComponent(CatControl);
            //检测有没有和狗的协议
            if(this.DealNumber>0){
                //协议数减一
                this.DealNumber--;
                this.num_agreenments.string = this.DealNumber+"";
                //猫死亡
                cat.die();
                this.KillCatNumber++;
                this.num_kills.string = ""+this.KillCatNumber;
            }
            else{
                //猫胜利
                cat.vectory();
                //自己死亡
                this.die();
            }
        }
        if(other.tag==3){
            console.log("与狗发生碰撞")
            //如果接到的是狗
            let dog = other.getComponent(DogControl);
            //检测骨头数是否大于0,用于和狗狗交易
            if(this.BoneNumber>0){
                //骨头数减一
                this.BoneNumber--;
                this.num_Bones.string = this.BoneNumber+"";
                //狗狗离开
                dog.die();
                //协议数加一
                this.DealNumber++;
                this.num_agreenments.string = this.DealNumber+"";
            }
            else{
                //狗狗胜利
                dog.vectory();
                //狗狗吃了老鼠
                this.die();
            }
        }
    }

    die(){
        // 停止 Player 节点的跳跃动作
        this.node.stopAllActions(); 
        // 重新加载场景 game
        cc.director.loadScene('Game');
        //销毁自己
        this.node.destroy();
    }
    

}

4.3 运行结果
在这里插入图片描述
4.4 资源及代码
链接:https://pan.baidu.com/s/1YOlpKq6HIwxoXAg4sIzaKg
提取码:vbua
–来自百度网盘超级会员V3的分享

Cocos Creator版本是2.4.7哦,如有错误还请指导。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Who_Am_I.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值