cocos creator 台球小游戏

所用平台:cocos creator
所用语言:js

游戏的实现点:
1.可碰撞物体:以白球、其他球、球袋、球杆、球桌分五类,使用creator内置的操作设置可产生碰撞的节点;添加刚体,以节点形状选择刚体形状。以节点属性选择刚体类型是静态还是动态,其中球袋要多设置一项:sensor,即不产生碰撞效果,只产生碰撞监测。
2.球杆的移动、拉伸:球杆要随着白球为中心移动,为不接触白球,要设置最小距离,达到此距离则隐藏。以点击点与白球中心得到一个向量,用得到的向量长度拉伸球杆并改变球杆冲量;向量和水平轴的夹角得到球杆旋转度数。
3.白球进洞操作区别其他球:白球缩小尺寸,其他球则在完全隐藏,这样可以继续对白球的操作,同时,对其他球可以通过每帧执行一个函数:检查球桌上是否还有其他球(除白球)来判断游戏胜利。

代码

  • 挂在白球节点上
cc.Class({
    extends: cc.Component,

    properties: {
        cue: {
            type: cc.Node,
            default: null,
        },
        max_dis: 100,
        min_dis: 5, // 如果拖动的距离到白球的中心 < 这个距离,那么我们就隐藏球杆,否者的话,显示球杆;
    },

    start () {
        this.body = this.getComponent(cc.RigidBody);
        this.cue_inst = this.cue.getComponent("cue");
        this.start_x = this.node.x;
        this.start_y = this.node.y;

        this.node.on(cc.Node.EventType.TOUCH_START, function(e) {
        }.bind(this), this);

        this.node.on(cc.Node.EventType.TOUCH_MOVE, function(e) {
            var w_pos = e.getLocation();
            var dst = this.node.parent.convertToNodeSpaceAR(w_pos);
            //相对于this.node.parent(canvas)这个为参照物,AR为原点的坐标,(假设)白球移动到移动到世界坐标为 w_pos
            //就是去获得点击点的二维向量
            var src = this.node.getPosition();//白球二维向量
            var dir = cc.pSub(dst, src);//向量相减得到的一个方向向量
            var len = cc.pLength(dir);

            if (len < this.min_dis) {
                this.cue.active = false; // 设置球杆为隐藏;
                return;
            }
            if (len > this.max_dis) {
                this.cue.active = false; // 设置球杆为隐藏;
                return;
            }

            this.cue.active = true;

            var r = Math.atan2(dir.y, dir.x);//得到弧度
            var degree = r * 180 / Math.PI;
            degree = 360 - degree;

            this.cue.rotation = degree + 90; //旋转球杆

            var cue_pos = dst;
            var cue_len_half = this.cue.width * 0.1;//本来cue的锚点在中心的,应该是* 0.5的
            cue_pos.x += (cue_len_half * dir.x / len);
            cue_pos.y += (cue_len_half * dir.y / len);//使得球杆好像在随着点击点的后移向后拉

            this.cue.setPosition(cue_pos);
        }.bind(this), this);

        this.node.on(cc.Node.EventType.TOUCH_END, function(e) {
            if(this.cue.active === false) {
                return;
            }
            this.cue_inst.shoot_at(this.node.getPosition());//朝白球方向射击
        }.bind(this), this);

        this.node.on(cc.Node.EventType.TOUCH_CANCEL, function(e) {
            if(this.cue.active === false) {
                return;
            }
            this.cue_inst.shoot_at(this.node.getPosition());
        }.bind(this), this);
    },

    reset: function() {
        this.node.scale = 0.35;//当时加入的时候就是0.35
        this.node.x = this.start_x;
        this.node.y = this.start_y;

        this.body.linearVelocity = cc.p(0, 0);//线性转速
        this.body.angularVelocity = 0;//角转速 
    },

    onBeginContact: function(contact, selfCollider, otherCollider) {
        // 白球有可能,碰球杆,碰球,碰边,球袋
        if(otherCollider.node.groupIndex == 2) {
           // 隔1秒一种,要把白球放回原处;
           this.node.scale = 0;//消失
           this.scheduleOnce(this.reset.bind(this), 1);//1秒后白球重置
           // end  
           return;
        }
    },
    // update (dt) {},
});
  • 挂在其他球节点上

cc.Class({
    extends: cc.Component,
    // 属性列表,它将会作为组件实例的数据成员,到组件里面,绑定到我们的编辑器上;
    properties: {

        value: 1,
    },

    onLoad () {//每帧比update先
        // this,指的就是当前的组件实例
    },

    start () {//初始化时
        // this,指的就是当前的组件实例
        this.body = this.getComponent(cc.RigidBody);//同一节点的其他组件
        this.start_x = this.node.x;
        this.start_y = this.node.y;
    },

    // dt: 距离上一次刷新的时间;
    update (dt) {//每帧
        // this,指的就是当前的组件实例
    },

    reset: function() {
        this.node.active = true;
        this.node.x = this.start_x;
        this.node.y = this.start_y;

        this.body.linearVelocity = cc.p(0, 0);
        this.body.angularVelocity = 0;
    },

    onBeginContact: function(contact, selfCollider, otherCollider) {
        // 白球有可能,碰球杆,碰球,碰边,球袋
        if(otherCollider.node.groupIndex == 2) {
            this.node.active = false;
            return;
        }
    },
});
  • 挂在canvas节点上的游戏引擎
cc.Class({
    extends: cc.Component,

    properties: {

        is_debug: false,
        gravity: cc.p(0, -320), 

    },


    // onLoad () {},
    onLoad: function() {
        cc.director.getPhysicsManager().enabled = true;
        if(this.is_debug)
        {
            var Bits = cc.PhysicsManager.DrawBits;
            cc.director.getPhysicsManager().debugDrawFlags = Bits.e_jointBit | Bits.e_shapeBit;
        }
        else
            cc.director.getPhysicsManager().debugDrawFlags = 0;

        cc.director.getPhysicsManager().gravity = this.gravity;
    },

    // update (dt) {},
});
  • 挂在canvas节点上总场景
cc.Class({
    extends: cc.Component,

    properties: {

        ball_root: {
            type: cc.Node,
            default: null,
        },

        w_ball: {
            type: cc.Node,
            default: null,
        },
    },


    // onLoad () {},

    start () {
        this.is_game_started = true;
    },

    restart_game: function() {
        for(var i = 0; i < this.ball_root.childrenCount; i ++) {
            var b = this.ball_root.children[i];
            b.getComponent("ball").reset();
        }

        this.w_ball.getComponent("w_ball").reset();
        this.is_game_started = true;
    },

    check_game_over: function() {
        for(var i = 0; i < this.ball_root.childrenCount; i ++) {
            var b = this.ball_root.children[i];
            if(b.active === true) {
                return;
            }
        }

        this.is_game_started = false; // game_over;
        this.scheduleOnce(this.restart_game.bind(this), 3);
    },

    update (dt) {
        if (!this.is_game_started) {
            return;
        }

        // 是否所有的球都打入进去了;   
    },
});

挂在球杆节点上

cc.Class({
    extends: cc.Component,

    properties: {

        SHOOT_POWER: 18, // 合适的值就可以了
    },


    // onLoad () {},

    start () {
        this.body = this.getComponent(cc.RigidBody);

    },


    shoot_at: function(dst) {
        // 冲量: 给这个球杆一个方向的冲量,矢量,大小,有方向;
        // 方向问题:  src---> dst;
        var src = this.node.getPosition();//此时的球杆头位置
        var dir = cc.pSub(dst, src);//dst白球位置


        // 大小问题;
        var cue_len_half = this.node.width * 0.5;
        var len = cc.pLength(dir);
        var distance = len - cue_len_half;
        // end 

        var power_x = distance * this.SHOOT_POWER * dir.x / len;
        var power_y = distance * this.SHOOT_POWER * dir.y / len;

        //对该点施加冲量 applyLinearImpulse(冲量大小向量, 球杆的原点转成世界坐标, true)
        this.body.applyLinearImpulse(cc.p(power_x, power_y), this.node.convertToWorldSpaceAR(cc.p(0, 0)), true);

    },

    onPreSolve: function(contact, selfCollider, otherCollider) {
        this.node.active = false;
    },
    // update (dt) {},
});

你可能感兴趣的:(游戏)