最近项目需要做一个大转盘抽奖功能,抽奖的道具、数量及概率都有策划配置。废话不多说,先上配置表:

[
{"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}

这就是大转盘的基本功能。可以在其中添加一些特效和动画效果。

随笔-自控概率的大转盘抽奖相关推荐

  1. php 打乱数组顺序_PHP实现大转盘抽奖算法

    php中文网最新课程 每日17点准时技术干货分享 本文通过具体的实例向大家介绍了PHP语言实现大转盘抽奖算法,希望对大家学习PHP抽奖有所帮助. 流程: 1.拼装奖项数组: 2.计算概率: 3.返回中 ...

  2. 幸运大转盘抽奖(前端)

    采用Lottery.js插件, 无依赖, 简单易用(复制粘贴就能用) 效果图(可自己写算法定义概率,可自己定义奖项数量和名称) html <!DOCTYPE html> <html ...

  3. PHP+AJAX开发幸运大转盘抽奖

    PHP+AJAX开发幸运大转盘抽奖 PHP+AJAX开发幸运大转盘抽奖,通过奖品库存.中奖次数来计算中奖概率 奖品设置 1 $prizes = array( 2 0 => array( 3 &q ...

  4. html 5抽奖特效,利用HTML5实现Canvas大转盘抽奖特效

    特效描述:利用HTML5实现 Canvas 大转盘 抽奖特效.利用HTML5实现Canvas大转盘抽奖特效 代码结构 1. 引入JS 2. HTML代码 当前浏览器版本过低,请使用其他浏览器尝试 va ...

  5. 微信js 大转盘抽奖

    看到网页上有不少大转盘抽奖的应用,心血来潮也想弄个.于是找了点资料自己研究了下 queryRotate 这个插件就可以实现这个功能 jqueryRotate: 支持Internet Explorer ...

  6. 微信小程序实现大转盘抽奖----踩坑之路

    微信小程序实现大转盘抽奖----踩坑之路 需求:现在有一个小程序抽奖页面如下,此类抽奖方式为大转盘 思路:由服务端获取抽奖次数和奖品,根据服务端的中奖概率来决定是否中奖,最后利用小程序动画将转盘转起来 ...

  7. php抽奖算法,PHP实现大转盘抽奖算法(代码实例)

    本文通过具体的实例向大家介绍了PHP语言实现大转盘抽奖算法,希望对大家学习PHP抽奖有所帮助. 流程: 1.拼装奖项数组: 2.计算概率: 3.返回中奖情况. 代码如下:中奖概率 ' v ' 可以在后 ...

  8. js框架jquery实现幸运大转盘抽奖程序代码,兼容多种浏览器

    原文:js框架jquery实现幸运大转盘抽奖程序代码,兼容多种浏览器 源代码下载地址:http://www.zuidaima.com/share/1779633798073344.htm 看到网页上有 ...

  9. 大转盘抽奖实现总中奖率可控内部逻辑分享

    近一个月都在围绕新年活动这个新需求进行开发,其中的核心功能就是大转盘抽奖,类似于pdd.网上找了很多方法都不符合本项目的业务需求,特此分享一下自己写的核心逻辑,首次发文欢迎批评指正. 1.首先需要有奖 ...

  10. html转盘游戏,html5大转盘抽奖实例源码(基于vue.js)

    [实例简介] [调试步骤] # 安装依赖 npm install # 开启本地服务器localhost:8088 npm run dev # 发布环境 npm run build #然后静待你的浏览器 ...

最新文章

  1. leetcode-55 跳跃游戏
  2. Linux服务器防火墙白名单设置
  3. wxWidgets:wxTreeCtrl 示例
  4. Why is processing a sorted array faster than an unsorted array?
  5. php header什么意思,php header是什么意思
  6. phpcmsV9视频模块插件 - 手把手开发教程
  7. Swing 设置无边框Frame
  8. 【为了爱,为了pascal】【第三章】 认识PASCAL语言基础
  9. 2.tcpdump(2)
  10. NGN学习笔记4——软交换中的协议2—Megaco/H.248
  11. linux端口被墙了 开通端口
  12. mybatis数据库字段增加
  13. wow.js插件,让滚动动画更简单,让生活更美好
  14. 三维全景展示的特点 北京同创蓝天的专业性如何
  15. 基于 Java 机器学习自学笔记 (第51-53天:kNN)
  16. C#练习题答案: 寻找恩人【难度:1级】--景越C#经典编程题库,1000道C#基础练习题等你来挑战
  17. java-php-python-ssm基于移动端的选课系统的设计与实现服务器端计算机毕业设计
  18. InnoDB Persistent Statistics问题
  19. cdn详解 很全面的
  20. FFmpeg使用手册 - MP4的格式解析

热门文章

  1. oracle shutdown 很慢,oracle shutdown immediate等待时间很长之思考
  2. 关于AIDL接口定义中oneway的修饰符源码解析.
  3. PE系统优盘制作教程
  4. 分享一些图片懒加载组件的设计思路
  5. 【直播笔记】在临床研究中,如何利用SAS做更好的统计报表输出
  6. 行无疆靠谱讲述拼多多推广方法有哪些?
  7. 【原创 深度学习与TensorFlow 动手实践系列 - 4】第四课:卷积神经网络 - 高级篇...
  8. 【Trailhead题目解析】Prepare your salesforce org for users - 5Create Chatter Groups
  9. 机器人php接口,小I机器人接口[PHP版本 08.12.7]
  10. Visual Studio Code中设置HTML/HTML5模板