Cocos creator(JavaScript)轉盤抽獎

使用Cocos creator(JavaScript)轉盤抽獎

運行結果

在這裏插入圖片描述

思路

將轉盤分爲兩個階段(加速和減速),首先讓轉盤按照固定的加速度轉動,直到到達最大速度後按照設定好的減速度進行減速,速度減爲0 時停止.這裏我們需要計算出轉盤從最大速度減速到0 一共轉動的角度.然後通過目標Id 計算出目標角度,目標角度減去減速轉動的角度可求得減速前轉盤的角度(360°爲一圈,這裏最好將求得的角度求餘去[0,360)區間的度數).最後在減速前將轉盤置於計算出來的角度即可.
優化方向: 可以增加一個階段加速後的勻速轉動,以及轉盤按照最大速度轉動到求得的角度.

主要代碼

TurntableMgr.js

cc.Class({
    extends: cc.Component,

    properties: {
        boolRandom:{
            default : false,
            displayName : "隨機位置",
            tooltip : '確定結果區域後,是否在該區域內隨機落下'
        },

        intTotalPrize:{
            default : 6,
            type : cc.Integer,
            displayName : "獎品/區域總數",
            tooltip : '遊戲總獎品數'
        },

        intResultId:{
            default : 1,
            type : cc.Integer,
            displayName : "獎品/目標Id",
            tooltip : '中獎獎品'
        },

        floatAccelerated:{
            default : 360 * 2,
            type : cc.Float,
            displayName : "加速度",
            tooltip : '加速度值,每秒速度增加幾度,°/s²'
        },

        floatDeceleration:{
            default : -270,
            type : cc.Float,
            displayName : "減速度",
            tooltip : '加速度值,每秒速度減少幾度,°/s²'
        },

        floatMaxRangeSpeed:{
            default : 360 * 3,
            type : cc.Float,
            displayName : "最大速度",
            tooltip : '每秒速度減少幾度,°/s'
        }
    },

    // 初始化屬性
    initProperties() {
        // 旋轉角度範圍
        this._range = 360;
        // 當前旋轉速度
        this._currentRotationSpeed = 0; 
        // 目標角度
        this._targetRotation = 0;
        // 目標節點
        this._turntableBg = this.node.getChildByName("TurntableBg");
        // 說明節點
        this._labExplain = this.node.getChildByName("LabExplain").getComponent(cc.Label);
        this._labExplain.string = '初始化成功' 

        // 處理獎品Id
        if(this.intResultId <= 0 || this.intTotalPrize < this.intResultId || this.intTotalPrize <= 0)
        {
            this._labExplain.string = '區域總數或獎品Id不準確...'
        }
        this.intResultId = this.intTotalPrize + 1 - this.intResultId ;
        // 時間間隔
        this._interval = 0.02;   
    },

    onLoad() {
        this.initProperties();
    },

    /**
     * 隨機函數
     * 方法: 將目標區域分爲多個小塊,隨機落到除兩邊外其他位置(防止指針指到邊上指示不明確)
     */
    onRandomPlace() {
        cc.log("隨機該區域內位置")
        var random = (Math.random() - 0.5) * this._range / (this.intTotalPrize + 2);
        return random;
    },

    // 開始
    onStart()
    {
        if(this._currentState == undefined || this._currentState == 0)
        {
            this._currentState = 1; // 0:靜止 1:加速 2減速
            this._turntableBg.rotation = 0;
        }else{
            cc.log("轉盤已經開始轉動...");
        }
        this.schedule(this.updateRotation, this._interval);

    },

    // 暫停
    onStop()
    {
        if(this._currentState == undefined || this._currentState == 0)
        {
            cc.log("轉盤已經停止...");
        }else{
            // 當前狀態靜止
            this._labExplain.string = '轉盤已經暫停...'
            this.unschedule(this.updateRotation);
        }
    },

    // 計算開始減速時機
    onVirtualCompute()
    {
        // 虛擬轉動角度
        var virtualRotationAngle = 0;
        // 虛擬角度速度
        var rotationSpeed = this.floatMaxRangeSpeed;
        while(rotationSpeed > 0)
        {
            virtualRotationAngle = virtualRotationAngle + rotationSpeed * this._interval;
            rotationSpeed = rotationSpeed + this._interval * this.floatDeceleration;
        }

        return virtualRotationAngle;
    },

    // 獲取開始減速的時機 角度
    onGetValue(targetRotation)
    {
        var temp = targetRotation - this.onVirtualCompute();
        if(temp > 0) {
            while (temp >= 360) {
                temp -= this._range;
            }
        } else {
            while (temp < 0) {
                temp += this._range;
            }
        }
        return temp;
    },

    /**
     * 轉動檢測
     */
    detectionAngle() {
        cc.log("角度檢測中...")
        cc.log("尋找合適減速時機...")

        // 目標旋轉角度
        var targetRotation = this._range / this.intTotalPrize * this.intResultId;
        if(this.boolRandom) {
            targetRotation += this.onRandomPlace();
        }
        var tempRotation = this.onGetValue(targetRotation);
        this._turntableBg.rotation = tempRotation;

        cc.log("開始減速...");
        this._currentState = 2;
    },

    /**
     * 每一幀回調
     * @param {*}  
     */
    updateRotation() {
        switch (this._currentState) {
            case 0:
                this._labExplain.string = '靜止中...'
                break;
            case 1:
                {
                    if(this._currentRotationSpeed >= this.floatMaxRangeSpeed)
                    {
                        this._labExplain.string = '速度到達頂峯...'
                        this._currentRotationSpeed = this.floatMaxRangeSpeed;

                        this.detectionAngle();
                    }else
                    {
                        this._currentRotationSpeed += this.floatAccelerated * this._interval;
                        this._labExplain.string = '加速中...'
                    }
                }
                break;
            case 2:
                {
                    if(this._currentRotationSpeed <= 0)
                    {
                        this._labExplain.string = '速度到減爲0...'

                        this._currentRotationSpeed = 0; //當前速度設置爲 0rad/s
                        this._currentState = 0;         //當前狀態設置爲 0
                    }else{
                        this._labExplain.string = '減速中...'

                        this._currentRotationSpeed += this.floatDeceleration * this._interval;
                    }
                }
                break;
            default:
                {
                    this._labExplain.string = '未知定義狀態,強行停止旋轉...'

                    this._currentRotationSpeed = 0; //當前速度設置爲 0rad/s
                    this._currentState = 0;         //當前狀態設置爲 0
                }
                break;
        }
        cc.log("當前旋轉速度 : ",this._currentRotationSpeed);

        var tempRotationSpeed = this._currentRotationSpeed * this._interval;
        cc.log("當前轉盤轉動速度" + tempRotationSpeed + "°/" + this._interval + "s");

        this._labExplain.string = this._labExplain.string + "\n當前轉盤轉動速度: " +  Math.round(this._currentRotationSpeed) + "°/s";
        this._turntableBg.rotation += tempRotationSpeed;
    },

    /**
     * 統一回收組件
     */
    onDestroy() {
        this.node.onDestroy();
    }
});

屬性檢查器

在這裏插入圖片描述

碼雲鏈接:https://gitee.com/ls_qq2670813470/Turntable.
原文鏈接:https://blog.csdn.net/qq_14965517/article/details/103905761.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章