1. 程式人生 > >Cocos Creator 實現摩天輪效果

Cocos Creator 實現摩天輪效果

第一次寫部落格 導致緊張嚇得我直接貼程式碼
cc.Class({
    extends: cc.Component,

    properties: {
        selecNode: {
            default: null,
            type: cc.Node
        },
        item: {
            default: null,
            type: cc.Prefab
        },
        radius: 0,  //半徑
        pCenter: cc.Vec2, //圓心
        angleInterval: 0, //每個預製體之間的間隔角度
        angleFx: 0, //阻力系數
        speedMin: 0.1, //最小轉速
        itemNum: 0, //預製體個數
        //滑動的最終角度,用來設定最小角度和最大角度
        angleMin: 0,
        angleMax: 0,
        beginVec: cc.Vec2,
        touchVec: cc.Vec2,
        backNum: 0,
        oldVec: 0,//記錄上一次角度的位置
        beginPoint: cc.Vec2, //開始的位置
        movePoint: cc.Vec2,
        guanxing: cc.repeatForever,
        count: cc.repeatForever,
        angleDx: null,
        angleS: 0,
        time: 0,
        angleSpeed: 0,
        stopTime: 0,
        angleDx_Save: null,
        direction: 0,
        beRotation: 0,
        Speed: 0,
        i: 0

    },

    // use this for initialization
    onLoad: function () {
        this.initSelecScene();

    },
    buttonEvent: function (event, data) {
        if (data === 'back') {
            cc.director.loadScene('MainScene');
        }
    },
    initSelecScene: function () {
        this.initData();
        this.loadUI();
        this.loadTouchStartEvent();
        this.loadTouchEndEvent();
        this.loadTouchMoveEvent();
        this.updateItemAngle();
    },
    initData: function () {
        this.selecNode.rotation = 47;
        this.radius = 1600;
        this.pCenter = cc.v2(this.radius, this.radius);
        this.angleInterval = 6;
        this.angleFx = 1 / 6;
        this.speedMin = 0.1;
        this.itemNum = 6;
        this.angleMin = 47;
        this.angleMax = -2;
        this.backNum = 3;
        this.Speed = 1.9;
    },
    loadUI: function () {
        for (var i = 0; i < this.itemNum; ++i) {
            var angle = this.angleInterval * i + 1.1;
            var vec = cc.p(0, this.radius).rotate(angle);
            // var addHeight = vec.add(cc.v2(this.pCenter.x, this.pCenter.y));
            var itemNode = cc.instantiate(this.item);
            itemNode.position = vec;
            itemNode.getComponent('selecItem').initSelecImg(i);
            this.selecNode.addChild(itemNode);
            itemNode.setTag(i);
            cc.log(vec);
        }
    },

    loadTouchStartEvent: function () {
        var self = this;
        this.node.on(cc.Node.EventType.TOUCH_START, function (event) {
            self.savaOldVec(cc.v2(event.getLocation().x, event.getLocation().y));
            self.beginVec = self.selecNode.getRotation();
            self.touchVec = self.pCenter.sub(cc.v2(event.getLocation().x, event.getLocation().y));
            self.beginPoint = cc.v2(event.getLocation().x, event.getLocation().y);
            self.setRotate1();
            self.countAngleSpeed();
        }, this.node);
    },
    loadTouchEndEvent: function () {
        var self = this;
        this.node.on(cc.Node.EventType.TOUCH_END, function (event) {
            self.guanxingFunc();
        }, this.node);
    },
    loadTouchMoveEvent: function () {
        var self = this;
        this.node.on(cc.Node.EventType.TOUCH_MOVE, function (event) {
            if (self.selecNode.getRotation() > self.angleMin + 5 || self.selecNode.getRotation() < self.angleMax - 5) {
                cc.log('rotation Error');
                return;
            }
            self.movePoint = cc.v2(event.getLocation().x, event.getLocation().y);
            var vec = self.pCenter.sub(cc.v2(event.getLocation().x, event.getLocation().y));
            var angle = cc.pToAngle(self.touchVec) - cc.pToAngle(vec);
            self.rotationNode(self.beginVec - (angle * 180 / Math.PI));
            self.angleDx = angle * 180 / Math.PI;
        }, this.node);

    },
    updateItemAngle: function () {
        for (var i = 0; i < this.itemNum; ++i) {
            var item = this.selecNode.getChildByTag(i);
            var angle = this.angleInterval * i + 1.1;
            var vec = cc.p(0, this.radius).rotate(-angle);
            item.getComponent('selecItem').rotationItem(cc.pToAngle(vec) * 180 / Math.PI - 90);

        }
    },
    update: function () {
        //模擬旋轉
        // this.selecNode.rotation = this.i++;
        this.updateItemAngle();
    },
    rotationNode: function (vec) {
        this.selecNode.rotation = vec;
    },
    guanxingFunc: function () {

        this.selecNode.stopAction(this.count);
        if (this.angleS === 0 || this.time === 0) {
            return this.trainBack();
        }
        this.angleSpeed = this.angleS / (this.time / 5);
        if (this.angleS > 0) {
            this.direction = 1;
        } else {
            this.direction = -1;
        }
        //限制最大轉速
        if (this.angleSpeed > 2.5) {
            this.angleSpeed = 2.5;
        } else if (this.angleSpeed < -2.5) {
            this.angleSpeed = -2.5;
        }
        this.beRotation = this.selecNode.getRotation();
        var guanxingFunction = cc.callFunc(this.updateGuanxin, this);
        var delayTime = cc.delayTime(1 / 60);
        var repeat = cc.repeatForever(cc.sequence(delayTime, guanxingFunction));
        this.guanxing = repeat;
        this.selecNode.runAction(this.guanxing);

    },
    trainBack: function () {
        var angle = this.selecNode.getRotation();
        var rotateTo;
        if (angle >= this.angleMin - this.backNum) {
            rotateTo = cc.rotateTo(0.2, 47);

            if (rotateTo != null) {
                this.selecNode.runAction(rotateTo);
            } else {
                this.trainBack();
            }

        }

        if (angle <= this.angleMax + this.backNum) {
            rotateTo = cc.rotateTo(0.2, -2);
            if (rotateTo != null) {
                this.selecNode.runAction(rotateTo);
            } else {
                this.trainBack();
            }

        }

    },

    getDirection: function () {
        if (this.beginPoint.x > this.movePoint.x) {
            return 1;
        } else if (this.beginPoint.x < this.movePoint.x) {
            return -1;
        }
        return '';
    },
    savaOldVec: function (vec) {
        var vecs = this.pCenter.sub(vec);
        var angle = cc.pToAngle(this.touchVec) - cc.pToAngle(vecs);
        this.oldVec = this.beginVec - (angle * 180 / Math.PI);
    },

    // 獲得控制權
    setRotate1: function () {
        this.angleS = 0
        this.time = 0
        this.angleDx = 0
        // 取消慣性強制停止
        if (this.guanxing != null) {
            this.selecNode.stopAction(this.guanxing);
            // this.guanxing = null;
        }

    },
    countAngleSpeed: function () {
        var delayTime = cc.delayTime(1 / 60);
        var callfunc = cc.callFunc(this.callFunctionAction, this);
        var repeat = cc.repeatForever(cc.sequence(delayTime, callfunc));
        this.count = repeat;
        this.selecNode.runAction(this.count);
    },
    callFunctionAction: function () {

        var self = this;
        self.time = 0 // 同方向旋轉過時間
        self.angleS = 0 // 同方向旋轉過的角度
        self.stopTime = 0 // 轉動過程停留

        if (self.angleDx != null) {
            if (self.angleDx_Save === null) {
                self.angleDx_Save = self.angleDx;
            }
            if (self.angleDx * self.angleDx_Save < 0) {
                //改變方向 資料清零
                // cc.log('改變方向');
                self.time = 0;
                self.angleS = 0;
            } else if (Math.abs(self.angleDx_Save - self.angleDx) >= 0.1) {
                //同方向旋轉
                // cc.log('同方向旋轉1');
                self.time = self.time + 1;
                self.angleS = self.angleDx + self.angleS;
                self.stopTime = 0
            } else if (Math.abs(self.angleDx_Save - self.angleDx) < 0.1) {
                //同方向旋轉
                // cc.log('同方向旋轉2');
                self.stopTime = self.stopTime + 1;
                if (self.stopTime >= 4) {
                    self.stopTime = 0
                    self.time = 0
                    self.angleS = 0
                }
            }
            self.angleDx_Save = self.angleDx;
        }
        // cc.log('time:' + self.time + ' stopTime:' + self.stopTime + ' angleS:' + self.angleS);
    },
    updateGuanxin: function () {
        var self = this;
        // cc.log(this.i++);
        // by tanp 讓回車滑的更加正常,所以把阻力系數angleFx改為“math.abs(self.angleSpeed)*self.angleFx + .01”了。  
        // by tanp 讓回車滑的更加順暢,所以把阻力系數angleFx改回0.05了。  

        var angleFx = Math.abs(self.angleSpeed) * self.angleFx + 0.01;
        //阻力=速度*阻力系數*方向
        var angleF = (Math.abs(self.angleSpeed) * angleFx) * self.direction;
        //更新速度             
        self.angleSpeed = self.angleSpeed - angleF;
        //更新角度
        // cc.log('angleFx:' + angleFx + ' angleF:' + angleF + ' angleSpeed:' + self.angleSpeed);
        self.selecNode.rotation = self.beRotation - self.angleSpeed * self.Speed;
        self.beRotation = self.beRotation - self.angleSpeed * self.Speed;
        if (Math.abs(self.angleSpeed) < self.speedMin || self.beRotation > self.angleMin || self.beRotation < self.angleMax) {
            self.selecNode.stopAction(self.guanxing)
            // self.guanxing = null;
            self.trainBack();
        }
    }






});