随笔-自控概率的大转盘抽奖
最近项目需要做一个大转盘抽奖功能,抽奖的道具、数量及概率都有策划配置。废话不多说,先上配置表:
[
{"id":0,"type":1,"num":5,"proportion":20},
{"id":1,"type":0,"num":1500,"proportion":7},
{"id":2,"type":1,"num":20,"proportion":8},
{"id":3,"type":0,"num":500,"proportion":15},
{"id":4,"type":1,"num":5,"proportion":20},
{"id":5,"type":0,"num":1500,"proportion":7},
{"id":6,"type":1,"num":20,"proportion":8},
{"id":7,"type":0,"num":500,"proportion":15}
]
对应的C#的实体类如下:
public class PrizeWhellData
{/// <summary>/// id/// </summary>public int id;/// <summary>/// 类型(0:金币;1:钻石;2:装饰币;3:各种道具预留)/// </summary>public int type;/// <summary>/// 数值/// </summary>public int num;/// <summary>/// 占比/// </summary>public float proportion;
}
接下来就是转盘的功能了:
- 首先是初始化阶段,配表Json解析这里就不写了。已经存在prizeWhellDataDic这个字典里了。
public Transform RollPanel;//旋转的转盘public Button startBtn;//开始按钮private bool isClick;int rollID;#region 转盘相关RollState curState; //当前转盘的状态float allTime = 0;//旋转时间 总的时间float endAngle;//最终的角度//变速段float MaxSpeed = 800;//最大速度float factor;//速度因子float accelerateTime = 1;//加速到最大速度的时间 ---暂定为1float speedUpTime = 3;//加速段的总时间float tempAngle;//开始减速段时转盘此时的旋转角度float k = 2f; //减速阶段的速度系数 --减速快慢由此决定 #endregion//角度,分了8份,所以角度是以下8份private string[] angles = new string[8] { "0,45", "45,90", "90,135", "135,180", "180,225", "225,270", "270,315", "315,360" };private List<int> rates = new();//几率数组public Text[] itemTexts;public Image[] itemIcons;// 配表数据private Dictionary<int, PrizeWhellData> prizeWhellDataDic = new();private void Start(){startBtn.onClick.AddListener(StartBtnEvent);for (int i = 0; i < prizeWhellDataDic.Count; i++){if (prizeWhellDataDic[i].type == 0){//如果是金币,放金币的图片itemIcons[i].sprite = GameManager.Instance.GetSpriteAtlas("pw_icon_glodBig");}else if (prizeWhellDataDic[i].type == 1){//如果是钻石,放钻石的图片if (prizeWhellDataDic[i].num > 10){itemIcons[i].sprite = GameManager.Instance.GetSpriteAtlas("pw_icon_gemB");}else{ itemIcons[i].sprite = GameManager.Instance.GetSpriteAtlas("pw_icon_gemS");}}itemIcons[i].SetNativeSize();itemTexts[i].text = string.Format("x{0}", prizeWhellDataDic[i].num);rates.Add((int)prizeWhellDataDic[i].proportion);}//初始化数据isClick = true;rollID = 0;RollPanel.rotation = Quaternion.identity;//for (int i = 0; i < 100; i++)//{// Debug.LogError("testRandRate: " + randRate());//}}
- 接下来就是旋转的功能逻辑:
void Update(){if (curState == RollState.None){return;}allTime += Time.deltaTime;//先进入加速阶段if (curState == RollState.SpeedUp){factor = allTime / accelerateTime;factor = factor > 1 ? 1 : factor;RollPanel.Rotate(factor * MaxSpeed * Time.deltaTime * new Vector3(0, 0, -1), Space.Self);}//当旋转时间大于等于了加速段的时间就开始进行减速if (allTime >= speedUpTime && curState == RollState.SpeedUp){curState = RollState.SpeedDown;tempAngle = GetTempAngle();//Debug.Log("tempAngle:" + tempAngle);}if (curState == RollState.SpeedDown){//通过差值运算实现旋转到指定角度(球型插值无法实现大于360°的计算)tempAngle = Mathf.Lerp(tempAngle, endAngle, Time.deltaTime * k);RollPanel.rotation = Quaternion.Euler(0, 0, tempAngle);//旋转结束if (Mathf.Abs(tempAngle - endAngle) <= 1){curState = RollState.None;StartCoroutine(End());}}}private IEnumerator End(){ //奖励rollidif (prizeWhellDataDic.ContainsKey(rollID)){int numCount = prizeWhellDataDic[rollID].num;if (prizeWhellDataDic[rollID].type == 0){//金币UIController.Instance._uiMain._goldRec.GetComponent<Canvas>().overrideSorting = true;Vector3 endPos = UIController.Instance._uiMain._currentGoldImg.transform.position;TweenUtility.PlayBoomCoinFly(Vector3.zero, endPos, numCount, 1.2f);AudioManager.Instance.PlayAudio("box_gold");}else if (prizeWhellDataDic[rollID].type == 1){ //钻石UIController.Instance._uiMain._diamondRec.GetComponent<Canvas>().overrideSorting = true;Vector3 endPos = UIController.Instance._uiMain._currentDiamondImg.transform.position;TweenUtility.PlayBoomCoinFly(Vector3.zero, endPos, numCount, 1.2f);AudioManager.Instance.PlayAudio("box_gem");}}yield return new WaitForSeconds(1.5f);if (prizeWhellDataDic.ContainsKey(rollID)){if (prizeWhellDataDic[rollID].type == 0){//金币Debug.Log("获取到了金币:" + prizeWhellDataDic[rollID].num);}else if (prizeWhellDataDic[rollID].type == 1){ //钻石Debug.Log("获得了钻石:" + prizeWhellDataDic[rollID].num);}}startBtn.gameObject.SetActive(true);isClick = true;}private void StartBtnEvent(){startBtn.gameObject.SetActive(false);if (!isClick) return;StartTurnWheel();}/// <summary>/// 开始旋转转盘/// </summary>public void StartTurnWheel(){if (curState != RollState.None){return;}isClick = false;allTime = 0;tempAngle = 0;rollID = randRate();endAngle = GetEndAngle(rollID);//Debug.LogError("rollID: " + rollID + " endAngle: " + endAngle);curState = RollState.SpeedUp;}// 0 1 2 3 4 5 6 7 //(0,45)(45,90)(90,135)(135,180)(180,225)(225,270)(270,315)(315,360)//获取旋转的结果,通过设定的概率然后随机得到结果,我们可以自定义概率/// <summary>/// 得到当前转盘的旋转角度/// </summary>/// <returns></returns>private float GetTempAngle(){//Debug.Log("RollPanel.eulerAngles.z: " + RollPanel.eulerAngles.z);return (360 - RollPanel.eulerAngles.z) % 360;}/// <summary>/// 计算结束时的角度,因为是顺时针旋转所以是负的/// </summary>/// <param name="rollId"></param>/// <returns></returns>private float GetEndAngle(int rollId){float min = CFunc.ObjToFloat(angles[rollId].Split(",")[0]);float max = CFunc.ObjToFloat(angles[rollId].Split(",")[1]);return -(360 - Random.Range(min + 5, max - 5));}//rate:几率数组(%), total:几率总和(100%)public int randRate(int total = 100){int rand = Random.Range(0, total + 1);for (int i = 0; i < rates.Count; i++){rand -= rates[i];if (rand <= 0){return i;}}return 0;}/// <summary>/// 转盘旋转的四种状态/// </summary>public enum RollState{None,SpeedUp,SpeedDown,End}
这就是大转盘的基本功能。可以在其中添加一些特效和动画效果。
随笔-自控概率的大转盘抽奖相关推荐
- php 打乱数组顺序_PHP实现大转盘抽奖算法
php中文网最新课程 每日17点准时技术干货分享 本文通过具体的实例向大家介绍了PHP语言实现大转盘抽奖算法,希望对大家学习PHP抽奖有所帮助. 流程: 1.拼装奖项数组: 2.计算概率: 3.返回中 ...
- 幸运大转盘抽奖(前端)
采用Lottery.js插件, 无依赖, 简单易用(复制粘贴就能用) 效果图(可自己写算法定义概率,可自己定义奖项数量和名称) html <!DOCTYPE html> <html ...
- PHP+AJAX开发幸运大转盘抽奖
PHP+AJAX开发幸运大转盘抽奖 PHP+AJAX开发幸运大转盘抽奖,通过奖品库存.中奖次数来计算中奖概率 奖品设置 1 $prizes = array( 2 0 => array( 3 &q ...
- html 5抽奖特效,利用HTML5实现Canvas大转盘抽奖特效
特效描述:利用HTML5实现 Canvas 大转盘 抽奖特效.利用HTML5实现Canvas大转盘抽奖特效 代码结构 1. 引入JS 2. HTML代码 当前浏览器版本过低,请使用其他浏览器尝试 va ...
- 微信js 大转盘抽奖
看到网页上有不少大转盘抽奖的应用,心血来潮也想弄个.于是找了点资料自己研究了下 queryRotate 这个插件就可以实现这个功能 jqueryRotate: 支持Internet Explorer ...
- 微信小程序实现大转盘抽奖----踩坑之路
微信小程序实现大转盘抽奖----踩坑之路 需求:现在有一个小程序抽奖页面如下,此类抽奖方式为大转盘 思路:由服务端获取抽奖次数和奖品,根据服务端的中奖概率来决定是否中奖,最后利用小程序动画将转盘转起来 ...
- php抽奖算法,PHP实现大转盘抽奖算法(代码实例)
本文通过具体的实例向大家介绍了PHP语言实现大转盘抽奖算法,希望对大家学习PHP抽奖有所帮助. 流程: 1.拼装奖项数组: 2.计算概率: 3.返回中奖情况. 代码如下:中奖概率 ' v ' 可以在后 ...
- js框架jquery实现幸运大转盘抽奖程序代码,兼容多种浏览器
原文:js框架jquery实现幸运大转盘抽奖程序代码,兼容多种浏览器 源代码下载地址:http://www.zuidaima.com/share/1779633798073344.htm 看到网页上有 ...
- 大转盘抽奖实现总中奖率可控内部逻辑分享
近一个月都在围绕新年活动这个新需求进行开发,其中的核心功能就是大转盘抽奖,类似于pdd.网上找了很多方法都不符合本项目的业务需求,特此分享一下自己写的核心逻辑,首次发文欢迎批评指正. 1.首先需要有奖 ...
- html转盘游戏,html5大转盘抽奖实例源码(基于vue.js)
[实例简介] [调试步骤] # 安装依赖 npm install # 开启本地服务器localhost:8088 npm run dev # 发布环境 npm run build #然后静待你的浏览器 ...
最新文章
- leetcode-55 跳跃游戏
- Linux服务器防火墙白名单设置
- wxWidgets:wxTreeCtrl 示例
- Why is processing a sorted array faster than an unsorted array?
- php header什么意思,php header是什么意思
- phpcmsV9视频模块插件 - 手把手开发教程
- Swing 设置无边框Frame
- 【为了爱,为了pascal】【第三章】 认识PASCAL语言基础
- 2.tcpdump(2)
- NGN学习笔记4——软交换中的协议2—Megaco/H.248
- linux端口被墙了 开通端口
- mybatis数据库字段增加
- wow.js插件,让滚动动画更简单,让生活更美好
- 三维全景展示的特点 北京同创蓝天的专业性如何
- 基于 Java 机器学习自学笔记 (第51-53天:kNN)
- C#练习题答案: 寻找恩人【难度:1级】--景越C#经典编程题库,1000道C#基础练习题等你来挑战
- java-php-python-ssm基于移动端的选课系统的设计与实现服务器端计算机毕业设计
- InnoDB Persistent Statistics问题
- cdn详解 很全面的
- FFmpeg使用手册 - MP4的格式解析
热门文章
- oracle shutdown 很慢,oracle shutdown immediate等待时间很长之思考
- 关于AIDL接口定义中oneway的修饰符源码解析.
- PE系统优盘制作教程
- 分享一些图片懒加载组件的设计思路
- 【直播笔记】在临床研究中,如何利用SAS做更好的统计报表输出
- 行无疆靠谱讲述拼多多推广方法有哪些?
- 【原创 深度学习与TensorFlow 动手实践系列 - 4】第四课:卷积神经网络 - 高级篇...
- 【Trailhead题目解析】Prepare your salesforce org for users - 5Create Chatter Groups
- 机器人php接口,小I机器人接口[PHP版本 08.12.7]
- Visual Studio Code中设置HTML/HTML5模板