篮球挑战达人

这是我第一次接触Cocos Cretor,博主之前学的是Unity3D开发,由于U3D的工作不怎么好找所以博主打算转2D。这也是我学Cocos Creator的第二天就面试上的公司,也是我的第一个项目。写的不好的地方希望大家多多包涵。
这个游戏是“最强灌篮大作战”,由于之前没写过类似的游戏,所以在我接触到这个项目时感觉亚历山大。不过在我每天加班加点的学习过程中,程序已经渐渐成型。虽然在很多的地方稍有不足。
第一步,先创建一个Cocos Cretor的项目,如图:

第二步,按照程序的设计样板,编辑相应的界面。

这里简单说一下,此类游戏的重点,是设置它的物理,碰撞等系统。在这个游戏里,博主为了防止篮球被弹出屏幕,楼主把游戏界面做成了盒子。

盒子的组成属性如上图,添加方法:点击添加组件=>物理=>Collider =>box。
即可完成所有盒子的添加。
第三步,物理组建的添加怎么可能少了篮球呢。篮球的物理大部分和盒子的物理类似,只是部分数据不同。请看图。
 

哦对了,物理和碰撞系统默认情况下是关闭的。所以如果要使用首先得开启物理系统和碰撞系统。
Game.js: onLoad()
 

扫描二维码关注公众号,回复: 2558781 查看本文章

这里还要补充一点的是设置蓝板框,因为大部分的物理检测都是在蓝板上

如图,在篮板上我添加了四个物理碰撞,首先是蓝板(防止球穿过篮板),其次是在进球的筐,让球能够从两个物理点进球(也是为了防止篮球穿过球筐),第四个点是用来检测球是否进筐。当球与该点接触,即进球。计分器加一。接触判断需要添加组。

第四步,物理设置好了接下来就是控制篮球的方向,及点击跳动了。我这里就直接粘贴代码了。我把触摸写在了Canvas上也就是Game脚本上。然后调用控制Player节点。
Game.js
cc.Class({
    extends: cc.Component,

    properties: {
        //player 节点,用于获取主角弹跳的高度,控制主角行动
        player: {
            default: null,
            type: cc.Node
        },

        //更新分数的Label
        ScoreLabel: {
            default: null,
            type: cc.Label
        },  
    },

    onLoad () {
       
        //开启冲力,感觉没啥用
        cc.director.getPhysicsManager().enabled = true;
        cc.director.getPhysicsManager().debugDrawFlags = cc.PhysicsManager.DrawBits.e_aabbBit |
        // cc.PhysicsManager.DrawBits.e_pairBit |
        // cc.PhysicsManager.DrawBits.e_centerOfMassBit |
        cc.PhysicsManager.DrawBits.e_jointBit |
        cc.PhysicsManager.DrawBits.e_shapeBit;
        cc.director.getPhysicsManager().debugDrawFlags = 0;

        /*==========================开启碰撞检测系统==========================*/
        var manager = cc.director.getCollisionManager();
        manager.enabled = true;

        /*==========================开启物理碰撞==========================*/ 
        this.physicsManager = cc.director.getPhysicsManager();
        this.physicsManager.enabled = true;

        /*==========================触摸监听==========================*/
        this.node.on(cc.Node.EventType.TOUCH_START,function(touch){
          
            //角色绑定控件
            var hero = this.player.getComponent("Player");
            //实现onTouchBegan事件回调函数  
            cc.log(touch)
            var touchLocX = touch.getLocation().x;
            if(touchLocX < cc.winSize.width/2) {
                hero.node.runAction(hero.setJumpRightUpAction());//精灵跳跃
            }
            else if (touchLocX > cc.winSize.width/2) {
                hero.node.runAction(hero.setJumpLeftUpAction());//精灵跳跃
            }
            cc.log("touchLocX: " + touchLocX );
            //hero.node.runAction(hero.setJumpUpAction());//精灵跳跃
        }, this);   
    },

    /*=================================================================Update=================================================================*/
    update (dt) {
        this.ScoreLabel.string = ' ' + G_Score;
    },
});

上图中player就是篮球的组件。写惯了U3D,所以我就懒的用代码获取组件了。听说
Cocos Creator的开发者和U3D的开发者是同一个人。难怪我怎么感觉使用起来很熟悉呢。

/*====================================================================*/

Player.js
cc.Class({
    extends: cc.Component,
 
    properties: {
        /*======球体的影子======*/
        Ball_2 : {
            default: null,
            type: cc.Node
        },

        /*======分数特效实体======*/
        ScorePrefab: {
            default: null,
            type: cc.Prefab
        },

        /*======蓝板框左======*/
        BasketMoveLeft: {
            default: null,
            type: cc.Node
        },       

        /*======蓝板框右======*/
        BasketMoveRight: {
            default: null,
            type: cc.Node
        },

       //主角跳跃持续时间
       jumpTime:1,
       //主角跳跃高度
       jumpHeight:200,
       //掉落速度
       maxMoveSpeed:1,
        //球的左右移动大小
        xSpeed: 150,  
        accel:1
    },
   
/*==================================================================================================================================================== */

    //球体上跳
    setJumpUpAction:function(){
        // this.jumpHeight = 200;
        //向上跳动
        var jumpUp = cc.moveBy(this.jumpTime, cc.p(0,this.jumpHeight)).easing(cc.easeCubicActionOut());
        return jumpUp;
    },
   
    //球体右上角跳
    setJumpRightUpAction:function(){
       // this.jumpHeight = 200;
        //向上跳动
        var rotate = cc.rotateBy(1, -720);
        cc.log("xSpeed = " + this.xSpeed);
        var jumpUp = cc.moveBy(this.jumpTime, cc.p(-this.xSpeed,this.jumpHeight)).easing(cc.easeCubicActionOut());
        return cc.spawn(rotate , jumpUp);
    },

    //球体左上角跳
    setJumpLeftUpAction:function(){
        //向上跳动
        var rotate = cc.rotateBy(1, 720);
        cc.log("xSpeed = " + this.xSpeed);
        var jumpUp = cc.moveBy(this.jumpTime, cc.p(this.xSpeed,this.jumpHeight)).easing(cc.easeCubicActionOut());
       
        return cc.spawn(rotate , jumpUp);
    },

    //掉落
    setJumpDownAction: function(){
        var jumpDown = cc.moveBy(this.jumpTime, cc.p(0,this.jumpHeight)).easing(cc.easeCubicActionIn());
        return jumpDown;
    },

    setJumpRunAction:function(){
        //初始化跳跃动作
        this.jumpAction = this.setJumpUpAction();
        //掉落动作
        this.maxMoveSpeed = this.setJumpDownAction();      

        var seq = cc.sequence(this.jumpAction, this.maxMoveSpeed);
        this.node.runAction(seq);
    },

    BallDownMove:function(){
        //下落
        var heroDown = cc.moveBy(0.8, cc.p(0, -5));
        return heroDown;
    },   
   

    // ScoreLabelAction: function() { 
    //     this.ScoreLabel.active = true; 
    //     var moveby = this.ScoreLabel.runAction(cc.moveBy(1, cc.p(0,50)));
    //     var Score = this.ScoreLabel.runAction(cc.fadeOut(1));
    //     var calfun = cc.callFunc(function(){
    //         this.ScoreLabel.active = false;
    //         this.ScoreLabel.opacity = 255;
    //         this.ScoreLabel.runAction(cc.fadeIn(0));
    //     }, this);


    //     var seq = cc.sequence( moveby, Score, calfun);
    //     this.ScoreLabel.runAction(seq);
    // },

    //蓝板框前进移动特效
    Basket_MoveIn: function(){
        var PosY = (cc.random0To1() * 350) - 200;
        this.BasketMoveLeft.setPosition(-255, PosY);
        this.BasketMoveRight.setPosition(445, PosY);
        G_Temp = 1;
    },
   
    //蓝板框回退移动特效
    Basket_MoveBack: function(){
        var PosY = (cc.random0To1() * 350) - 200;
        this.BasketMoveLeft.setPosition(-455, PosY);
       
        this.BasketMoveRight.setPosition(255, PosY);
        G_Temp = -1;
    },

    //碰撞系统回掉
    onBeginContact: function (contact, selfCollider, otherCollider) {
        if( (otherCollider.node.groupIndex == 2) ){
            var pref = cc.instantiate(this.ScorePrefab);    
            pref.parent = this.node.parent;
            var Vecx = this.node.getPositionX();
            var Vecy = this.node.getPositionY();
            console.log("Vecx: " + Vecx);
            console.log("Vecy: " + Vecy);
            //node.convertToNodeSpaceAR(cc.v2(100, 100));
            pref.setPosition(Vecx,Vecy + 100);
 
            /*======= 分数实体化运动轨迹特效 =======*/
            var moveby = pref.runAction(cc.moveBy(2, cc.p(0,50)));
            var Score = pref.runAction(cc.fadeOut(2.0)); 
            var seq = cc.spawn( moveby, Score);
            //pref.runAction(cc.fadeIn(1.0));            
            pref.runAction(seq);
            /*======= 球进篮计分器+1 =======*/
            G_Score = G_Score + 1;
            /*======重置时间进度条======*/
            this.Prog.progress = 1;
           
            // if (G_Temp == 1) {
            //     this.Basket_MoveBack();
            // }else if (G_Temp == -1) {
            //     this.Basket_MoveIn();
            // }
            /*=====延迟一秒执行下列函数=====*/
            this.scheduleOnce(function() {
                pref.removeFromParent();
                console.log("111111111111");                          
            }.bind(this), 1);
        }
    }, 
   
/*==================================================================================================================================================== */

    // use this for initialization
    onLoad: function () { 
        //cc.log("X: ");
        G_Temp = 1;

        G_Score = 0;

        /*=========================进一球,得一分,时间重置========================= */
        this.Bar = cc.find("Canvas/ProgressBarTest");
        this.Prog = this.Bar.getComponent(cc.ProgressBar);

        /*=========================调用运动函数=========================*/
        this.setJumpRunAction();
        // 主角当前水平方向速度
        this.xSpeed = 50;       
    },
   

    //
     update: function (dt) {      
        /*=========================设置篮球的影子跟随篮球运动=========================*/
        this.Ball_2.setPosition(cc.v2( this.node.x , -480));
       
        //精灵下落移动
        this.node.runAction(this.BallDownMove());
    },
});

介绍一下,Ball_2 是篮球的影子组建。因为在游戏中需要使用篮球的影子使游戏更加逼真,所以我这里直接使用。
ScorePrefab 是加分特效,这里我做成了Prefab。BasketMove是我之前打算做的篮板框随机产生位置。因为出现了BUG到目前还没解决,所以我打算放一边。其他的属性请看代码注释吧。

progressBar是进度条的设置,我这边是用来控制游戏的时间的。这里主要的属性是progress,只要调整progress的大小就可以控制进度条的加载了。当进度条为0时,代表游戏结束,将会弹出结算界面。具体请看代码:
ProgressBarTest.js
cc.Class({
    extends: cc.Component,

    properties: {
        speed: 0.1,
        horizontalBarReverse: {       
            default: null,
            type: cc.ProgressBar
        },
    },

   


    // LIFE-CYCLE CALLBACKS:

    onLoad: function () {
        //this.horizontalBarReverse.progress = 1;
        //this.game = this.node.parent.getComponent('game');
    },

    start: function () {
        this.horizontalBarReverse.progress = 1;
    },

    update: function (dt){
        this._updateProgressBar(this.horizontalBarReverse, dt);
    },

    _updateProgressBar: function(progressBar, dt){
        var progress = progressBar.progress;
        this._pingpong = progress >= 0;
        if(progress > 0 && this._pingpong){
            progress -= dt * this.speed;            
          
        }
        else {
            // //游戏时间到弹出游戏结算界面
             cc.director.preloadScene("SettlementScene");
             cc.director.loadScene("SettlementScene");         
        }
        progressBar.progress = progress;
    },   
});

ButtonEvent.js专门用来设置按钮的一些操作的。
cc.Class({
    extends: cc.Component,

    properties: {
        ScoreLabel: {
            default: null,
            type: cc.Label
        },
    },

    // LIFE-CYCLE CALLBACKS:

    // onLoad () {},

    start () {

    },

    update (dt) {
        /*=========================更新界面的分数=========================*/
        this.ScoreLabel.string = ' ' + G_Score;
    },

    /*=========================按钮事件=========================*/
   ClickEvent(event, customEventData) {
        switch (Math.floor(customEventData)) {
            case 0:
                //继续游戏
                cc.director.preloadScene("Dunk");
                cc.director.loadScene("Dunk")
                break;
            case 1:
                //返回主界面
                cc.director.preloadScene("Start");
                cc.director.loadScene("Start") 
                break;
            case 2:
                console.log("好友接力");

                break;
            case 3:
                console.log("邀请好友挑战");

                break;
            case 4:
                console.log("观看视频,接着玩");

                break;
            case 5:
                console.log("好友助力,接着玩");

                break;
            case 6:
                cc.director.preloadScene("GameOver");
                cc.director.loadScene("GameOver");
                console.log("立即跳过");

                break;
            default:
                cc.log("default");
                break;
        }
    }
});

时间进度为0时就会弹出上图的界面,由于之前想直接实体化该界面 的,但发现实体化之后出现了弹出该界面之后游戏还能继续,所以我这里就直接把它做成一个单独的场景。

开始界面。这里没啥重点,请看代码。
Start_Scene.js
cc.Class({
    extends: cc.Component,

    properties: {
        //player 节点,用于获取主角弹跳的高度,控制主角行动
        player: {
            default: null,
            type: cc.Node
        },

        //更新分数的Label
        ScoreLabel: {
            default: null,
            type: cc.Label
        },  
    },

    onLoad () {
       
        //开启冲力,感觉没啥用
        cc.director.getPhysicsManager().enabled = true;
        cc.director.getPhysicsManager().debugDrawFlags = cc.PhysicsManager.DrawBits.e_aabbBit |
        // cc.PhysicsManager.DrawBits.e_pairBit |
        // cc.PhysicsManager.DrawBits.e_centerOfMassBit |
        cc.PhysicsManager.DrawBits.e_jointBit |
        cc.PhysicsManager.DrawBits.e_shapeBit;
        cc.director.getPhysicsManager().debugDrawFlags = 0;

        /*==========================开启碰撞检测系统==========================*/
        var manager = cc.director.getCollisionManager();
        manager.enabled = true;

        /*==========================开启物理碰撞==========================*/ 
        this.physicsManager = cc.director.getPhysicsManager();
        this.physicsManager.enabled = true;

        /*==========================触摸监听==========================*/
        this.node.on(cc.Node.EventType.TOUCH_START,function(touch){
          
            //角色绑定控件
            var hero = this.player.getComponent("Player");
            //实现onTouchBegan事件回调函数  
            cc.log(touch)
            var touchLocX = touch.getLocation().x;
            if(touchLocX < cc.winSize.width/2) {
                hero.node.runAction(hero.setJumpRightUpAction());//精灵跳跃
            }
            else if (touchLocX > cc.winSize.width/2) {
                hero.node.runAction(hero.setJumpLeftUpAction());//精灵跳跃
            }
            cc.log("touchLocX: " + touchLocX );
            //hero.node.runAction(hero.setJumpUpAction());//精灵跳跃
        }, this);   
    },

    /*=================================================================Update=================================================================*/
    update (dt) {
        this.ScoreLabel.string = ' ' + G_Score;
    },
});
这里还有一个,是我设置的全局变量的脚本,里面包含一些常用的变量。在上面的场景中我们可以看到一个经常被使用到的变量,Score。这是用来更新分数的,所以我这里把他做成了全局变量。具体请看代码。
GlobalVariable.js
/*======分数全局变量====== */
window.G_Score = 0;

/*======= 判断篮板的移动方向 =======*/
window.G_Temp = 1;

/*======空心球的个数====== */
window.G_Hollow_Number = 0;

/*======擦板球的个数====== */
window.G_Bank_Number = 0;

/*======压哨球的个数====== */
window.G_Buzzer_Number = 0;

/*======高抛求的个数====== */
window.G_SellHigh_Number = 0;

先这样,后期有补充再添加。不喜勿喷啊。我是第一次接触cocos Creator。

猜你喜欢

转载自blog.csdn.net/ji2570489271/article/details/81110468
今日推荐