游戏中转盘抽奖算法实现

前言

最近游戏中要加一个转盘抽奖的功能,大体的需求是这样的:

  1. 转盘有加速-匀速-减速的过程
  2. 可以控制转盘的停止角度

本来觉得这么常见的功能,应该已经现成的代码了,但是在搜索了一番之后,还是没有找到比较合适的。
只好自己再写一份代码。 - -!

实现思路

因为要实现加速、减速的这两个功能,所以首先想到的就是利用加速度公式。(把转动的角度,比作运行的距离)
公式如下:

1
2
s = v0 * t + (a * t^2) / 2
a = (vt - v0) / t

在确定好思路之后,转盘的实现,一下子就变成了初中的物理题啦。


转盘需要提供的接口

因为转盘这个功能很多游戏里面都会用到,所以要确保所写的转盘代码,能比较方便的复用,不要和游戏本身扯上太多的关系,同时也不要太依赖引擎本身的功能。
比如:如果是用cocos2dx开发,就不要用action之类的代码来控制转盘的转动速率

代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Class LotteryCtrl
{
//转盘的最大转速
maxSpeed
// 转盘加速、减速时间
speedUpTime
speedCutTime
/*
所控制的转盘指针(就是一个ui对象,可以设置它的rotation)
需要在创建LotteryCtrl的时候,设置这个参数
*
lotteryNode
/**************************/
// 开始转动
start : function()
// 在转动过程中设置目标角度
setData : function(_targetAngle)
// 根据时间刷新角度
_update : function(_dt)
}

这里特别要说一下为什么不把start,setData合并为一个函数.
因为一般联网的游戏,在客户端点击转盘之后,最终转到什么东西,是由服务端开始控制。所以这里有发包收包的过程。
如果是手游,那么在网速不好的情况下,这一过程会比较耗时,为了让玩家的操作能够立马得到反馈,我们需要在玩家执行转盘操作的时候,里面开始转动。等到收到服务器的回报之后,在执行setData。

关于_update函数

在_update中,根据start函数已经执行的时间,设置lotteryNode的角度。
这里主要计算加速阶段,匀速阶段,结算阶段所运行的角度值。这三个阶段的运算公式会稍微不同。
但都是用上面的那个公式。


最终效果演示

点击转盘按钮,即可进入转盘界面。
全屏地址

项目地址

https://github.com/xtutu/egret-demo

转载本站文章请注明作者(xtutu)和出处 xtutu.me