cocos creator |《合成大西瓜》源码 解读

更多源码请扫码关注公众号

编者荐语:

不辜负每一份热爱

以下文章来源于懒惰的An ,作者懒惰的An

懒惰的An

《合成大西瓜》原版开发者,cocos游戏开发小辣鸡,会发一些自己做的游戏源码或功能教程,搬运一些大老的技术分享~因为我比较懒,所以也可能不发~

大家好,我是An~wx公众号也申请了半年了,第一次写文,水平很低,凑活看吧

大西瓜火了,这两天也是在网上看到了各种模仿的大西瓜作品,可能也有朋友想知道这么简单的小游戏是怎么做的,今天我们也来模仿还原一下原版手感的合成大西瓜

正题:

第一步:打开CocosCreator,今天我们用2.4.3来制作

新建工程,导入素材~~

因为是竖屏游戏,Canvas参数设置成720*1288

在Canvas下加入一个新的精灵节点Sprite,size设置成720*1280,命名为BG

 

再把地板素材拖到BG下面,名字为Floor,在BG新建两个新的单色精灵Sprite节点,大小设置为20*1280,放在背景图片两侧

图片

同时给Floor,WallLeft,WallRight挂上RigidBody刚体组件和PhysicsBoxCollider碰撞器组件,RigidBody组件的Type设置为Static

图片

这样一个场景就做好了

 

下面做一个水果的预制体

在Canvas下新建一个空节点,用于存放我们下落的水果 名字就叫FruitNode,再新建一个空节点叫TargetFruitNode,用于存放我们当前控制的水果节点,我们从水果素材里随便拿出一个放在FruitNode节点下,改名叫FruitPre,同时给FruitPre加上RigidBody和PhysicalCircleCollider,参数也设置好

图片

还要记得设置好分组 墙壁设置成wall,水果设置成fruit

图片

然后把节点拖到Perfab文件夹里,这样预制体就做好了

图片

然后把场景里的FruitPre删掉

这样基本工作就做好了

 

下面我们写代码

在scripts创建一个ts脚本,名字为GameManager,脚本设置成单例

  •  
  •  
  •  
  •  
  •  
  •  
  •  
public static Instance: GameManager = null;onLoad () {       if (GameManager.Instance != null) {            GameManager.Instance.destroy();      }              GameManager.Instance = this;             cc.director.getPhysicsManager().enabled = true;//物理游戏,开启物理    }

 

脚本挂在Canvas上,首先获取到节点和预制体

  •  
  •  
  •  
  •  
  •  
  •  
  •  
@property(cc.Node)fruitNode: cc.Node = null;@property(cc.Node)targetfruitNode: cc.Node = null;@property(cc.Prefab)fruitPre: cc.Prefab = null;targetFruit: cc.Node = null;

 

然后写第一个方法,在屏幕上方生成一个水果,直接上代码

   

  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
createOneFruit(_pos: cc.Vec2) {        let fruit = cc.instantiate(this.fruitPre);//实例化一个预制体                fruit.setParent(this.targetfruitNode)//更改fruit父节点                fruit.setPosition(_pos);//设置坐标                fruit.setScale(0)//出生时scale设置为0                fruit.getComponent(cc.RigidBody).type = cc.RigidBodyType.Static;//刚体类型设置为Static防止下落                fruit.getComponent(cc.PhysicsCircleCollider).radius = 0;//碰撞器半径先设置位0,下落时再改到相应水果大小                fruit.getComponent(cc.PhysicsCircleCollider).apply();//保存碰撞器更改的参数                //水果生成时执行一个缩放动作                cc.tween(fruit)                    .to(0.5, { scale: 1 }, { easing: 'backOut' })                    .call(() => {                            this.targetFruit = fruit;//将我们控制的水果targetFruit设置为刚生成的fruit                    })                    .start()    }

在start()里调用一下

  •  
  •  
  •  
start() {          this.createOneFruit(cc.v2(0,500))    }

运行:

这样只能生成固定的一个水果,我们应该在代码里随意生成我们想要的水果,该怎么写呢。首先声明一个SpriteFrame数组,存放我们所有的水果素材

  •  
  •  
@property(cc.SpriteFrame)Allfruit: cc.SpriteFrame[] = [];

然后改一下生成水果的代码

  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
/**     * 生成一个水果/只用于生成上方的水果     * @param _fruitNum 水果类型 0是葡萄 以此类推     * @param _pos 水果生成的位置     */    createOneFruit(_fruitNum: number, _pos: cc.Vec2) {        let fruit = cc.instantiate(this.fruitPre);//实例化一个预制体        fruit.setParent(this.targetfruitNode)//更改fruit父节点                fruit.getComponent(cc.Sprite).spriteFrame = this.Allfruit[_fruitNum];//更改fruit的图片                fruit.getComponent("FruitCollision").fruitNumber = _fruitNum;//fruit碰撞回调脚本,里面有一个当前水果类型 如果是葡萄 fruitNumber为0 用于相同合成检测                fruit.setPosition(_pos);//设置坐标                fruit.setScale(0)//出生时scale设置为0                fruit.getComponent(cc.RigidBody).type = cc.RigidBodyType.Static;//刚体类型设置为Static防止下落                fruit.getComponent(cc.PhysicsCircleCollider).radius = 0;//碰撞器半径先设置位0,下落时再改到相应水果大小                fruit.getComponent(cc.PhysicsCircleCollider).apply();//保存碰撞器更改的参数                //水果生成时执行一个缩放动作                cc.tween(fruit)                    .to(0.5, { scale: 1 }, { easing: 'backOut' })                    .call(() => {                            this.targetFruit = fruit;//将我们控制的水果targetFruit设置为刚生成的fruit                    })                    .start()    }        

 

继续新建一个InputController脚本 挂在Canvas上 ,该脚本控制水果,点击哪里水果就会移动到那个位置的坐标x,滑动时水果会跟随,松开水果下落

直接上代码

    

  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
    touchNum: number = 0;    // LIFE-CYCLE CALLBACKS:
    // onLoad () {}

    start() {        this.openTouch();    }
    // update (dt) {}    openTouch() {        this.node.on(cc.Node.EventType.TOUCH_START, this.onTouchStart, this);        this.node.on(cc.Node.EventType.TOUCH_MOVE, this.onTouchMove, this);        this.node.on(cc.Node.EventType.TOUCH_END, this.onTouchEnd, this);        this.node.on(cc.Node.EventType.TOUCH_CANCEL, this.onTouchEnd, this);    }    onTouchStart(e) {        if (GameManager.Instance.targetFruit != null) {//检测targetFruit是否为空 空就不执行任何动作            this.touchNum = 1;            let posx = this.node.convertToNodeSpaceAR(e.getLocation()).x;//获取点击位置的x值            let posy = GameManager.Instance.targetFruit.y;//获取上方水果的y值            cc.tween(GameManager.Instance.targetFruit)                .to(0.1, { position: cc.v3(posx, posy, 0) })                .start()        }
    }
    onTouchMove(e) {        if (GameManager.Instance.targetFruit != null) {            this.touchNum = 1;            GameManager.Instance.targetFruit.x = this.node.convertToNodeSpaceAR(e.getLocation()).x; //水果跟随鼠标移动        }    }
    onTouchEnd(e) {        if (GameManager.Instance.targetFruit != null && this.touchNum == 1) { //this.touchNUm 是防止下落位置错误            this.touchNum = 0;            //  给targetFruit重新设置物理参数            //  碰撞器的半径为fruit高度的一半            GameManager.Instance.targetFruit.getComponent(cc.PhysicsCircleCollider).radius = GameManager.Instance.targetFruit.height / 2;            //  保存            GameManager.Instance.targetFruit.getComponent(cc.PhysicsCircleCollider).apply();            //  刚体类型改为动态            GameManager.Instance.targetFruit.getComponent(cc.RigidBody).type = cc.RigidBodyType.Dynamic;            //  给一个初始的下落线速度            GameManager.Instance.targetFruit.getComponent(cc.RigidBody).linearVelocity = cc.v2(0, -800)            //  属性改完后,targetFruit设置为空,防止连续操作            GameManager.Instance.targetFruit = null;            this.scheduleOnce(() => {                GameManager.Instance.createOneFruit(Math.floor(Math.random() * 5), cc.v2(0, 500));            }, 0.5)        }    }

运行起来:

下面就剩合成方法了,继续搞。。。好累

新建脚本FruitCollision,挂在水果预制体上

    

  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
fruitNumber: number = 0;//代表自身是那种类型的水果    returnNumber: boolean = false;    getNumberTime: number = 0;    // LIFE-CYCLE CALLBACKS:    // onLoad () {}    start() {    }    update(dt) {        if (this.returnNumber) {            this.scheduleOnce(() => {                this.getNumberTime = 0;            }, 0.25)            this.returnNumber = false;        }   }     //  防止多次碰撞     getNumber() {            let ad = this.getNumberTime;            this.getNumberTime++;           this.returnNumber = true;            return ad;      }     onBeginContact(contact, selfCollider, otherCollider) {        if (otherCollider.node.group == "fruit") {            //this.endCtrl = true;            //  只有下方的水果触发碰撞回调            if (selfCollider.node.y < otherCollider.node.y) {                return            }            //  水果一下落,放在FruitNode节点下            selfCollider.node.parent = cc.find("Canvas/FruitNode");            if (selfCollider.node.getComponent(cc.RigidBody) != null) {                selfCollider.node.getComponent(cc.RigidBody).angularVelocity = 0;                // 限制一下线速度            }
            let selfNum = this.fruitNumber;            let otherNum = otherCollider.node.getComponent("FruitCollision").fruitNumber;            //  水果类型相同的合成            if (selfNum == otherNum && selfNum < 9 && otherNum < 9) {                if (selfCollider.node.getComponent("FruitCollision").getNumber() == 0) {                    otherCollider.node.getComponent(cc.PhysicsCircleCollider).radius = 0;                    otherCollider.node.getComponent(cc.PhysicsCircleCollider).apply()                    this.node.getComponent(cc.PhysicsCircleCollider).radius = 0;                    this.node.getComponent(cc.PhysicsCircleCollider).apply();                    cc.tween(selfCollider.node)                        .to(0.1, { position: otherCollider.node.position })                        .call(() => {                            //生成下一个等级的水果                            GameManager.Instance.score += this.fruitNumber + 1;                            GameManager.Instance.createLevelUpFruit(this.fruitNumber + 1, otherCollider.node.position);                            otherCollider.node.active = false;                            selfCollider.node.active = false;                            otherCollider.node.destroy();                            selfCollider.node.destroy();                        })                        .start()                }            } else if (selfNum == otherNum && selfNum == 9 && otherNum == 9) {                if (selfCollider.node.getComponent("FruitCollision").getNumber() == 0) {                    otherCollider.node.getComponent(cc.PhysicsCircleCollider).radius = 0;                    otherCollider.node.getComponent(cc.PhysicsCircleCollider).apply()                    this.node.getComponent(cc.PhysicsCircleCollider).radius = 0;                    this.node.getComponent(cc.PhysicsCircleCollider).apply();                    cc.tween(selfCollider.node)                        .to(0.1, { position: otherCollider.node.position })                        .call(() => {                            GameManager.Instance.score += this.fruitNumber + 1;                            GameManager.Instance.createLevelUpFruit(this.fruitNumber + 1, otherCollider.node.position);                            otherCollider.node.active = false;                            selfCollider.node.active = false;                            otherCollider.node.destroy();                            selfCollider.node.destroy();                        })                        .start()
                }            }        }    }

再次运行,已经可以合成了,合成更高级的水果我换成了独立的方法 卸载GameManager里

  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
/**     * 生成高一级的水果     * @param _fruitNum 水果     * @param _pos 位置     */    createLevelUpFruit(_fruitNum, _pos) {        //AudioManager.Instance.Play(6, false, 1)        let fruit = cc.instantiate(this.fruitPre);        fruit.parent = this.fruitNode;
        fruit.getComponent(cc.Sprite).spriteFrame = this.Allfruit[_fruitNum];        fruit.getComponent("FruitCollision").fruitNumber = _fruitNum;        fruit.position = _pos;        fruit.scale = 0;        fruit.getComponent(cc.RigidBody).linearVelocity = cc.v2(0, -100);        fruit.getComponent(cc.PhysicsCircleCollider).radius = fruit.height / 2;        fruit.getComponent(cc.PhysicsCircleCollider).apply();        cc.tween(fruit)            .to(0.5, { scale: 1 }, { easing: 'backOut' })            .call(() => {                if (fruit.getComponent(cc.PhysicsCircleCollider) != null) {                    fruit.getComponent(cc.PhysicsCircleCollider).radius = fruit.height / 2;                    fruit.getComponent(cc.RigidBody).type = cc.RigidBodyType.Dynamic;                    fruit.getComponent(cc.PhysicsCircleCollider).apply();                }
            })            .start()
        GameManager.Instance.fruitHeigth = GameManager.Instance.findHighestFruit();
    }

 

后面红线预警方法,结束检测方法,结束方法, 加分等,我会另外加上并打成压缩包。

可以关注我公众号“懒惰的An” 回复“大西瓜”获取代码

图片

 

也可以在本公众号回复关键字获取源码:

大西瓜

cocos creator是一个非常流行的游戏开发引擎,它具有开发简单、跨平台等优点,适用于制作各种类型的游戏。而“合成大西瓜”是一款非常火爆的休闲游戏,玩家需要通过合成各种水果来打造一个巨大的西瓜。下面我来简单介绍一下如何使用cocos creator开发合成大西瓜游戏的源码。 首先,我们可以通过cocos creator官方网站上的资源库或者其他第三方资源库下载一个适合的游戏模板或源码,例如乐逗游戏的开源项目“Hit Master 3D”。这个项目的玩法和合成大西瓜有些类似,可以作为我们开发合成大西瓜的基础。 接下来,在cocos creator中打开下载好的源码项目,我们可以看到项目的目录结构和主要代码文件。通常,游戏的主要逻辑会在脚本文件中进行编写,例如游戏的控制、碰撞检测、UI界面等等。我们需要根据合成大西瓜的特点,对源码进行一定的修改和添加。 首先,我们可以修改游戏的界面和资源,将原来的物品、人物等替换成合成大西瓜中的水果。同时,我们需要添加一些新的素材,例如切割水果的刀具、合成水果的材料等。 其次,我们需要修改游戏的逻辑部分。合成大西瓜的核心玩法是通过合成不同的水果来获得更大的西瓜,因此我们需要编写一套合成规则和算法。同时,我们需要添加合成界面,让玩家可以选择两个水果进行合成。 最后,我们还可以添加一些附加功能,如游戏关卡的设置、游戏得分的计算等,来丰富游戏的玩法和体验。 总的来说,使用cocos creator开发合成大西瓜游戏的源码,首先需要下载一个适合的游戏模板或源码,然后根据游戏的特点进行修改和添加。希望这些简单的介绍能够帮助你理解如何使用cocos creator开发合成大西瓜游戏的源码
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值