使用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.