【100个Cocos实例】看完这个,我再也不要当赌狗了...

引言

探索游戏开发中抽奖转盘的奥秘。

抽奖转盘 是一种常见的互动元素 ,通常用于游戏、营销活动等场景。

本文将介绍一下抽奖转盘原理实现

本文源工程可在文末阅读原文获取,小伙伴们自行前往。

1.抽奖转盘的组成

抽奖转盘的实现 涉及多个组成部分,以下是一般抽奖转盘的主要组成:

  1. 转盘界面: 转盘通常是一个圆形或扇形的图形,分为多个奖项区域。
  2. 奖项定义: 定义转盘上的各个奖项,每个奖项包含奖品名称、图标等信息。
  3. 随机数生成器: 抽奖的核心是生成一个随机数,该随机数用于确定用户最终停留在转盘上的位置。
  4. 角度计算: 根据生成的随机数,计算用户最终停留的角度。这涉及将随机数映射到转盘上的角度范围。
  5. 旋转动画: 实现转盘旋转的动画效果,使其在一段时间内以一定的速度旋转。

下面一起来看看抽奖转盘的原理。

2.抽奖转盘的原理

首先 我们来看一下抽奖的流程图:

其中核心一 是后端的抽奖核心算法

概率并不是 我们直观看到的均等的1/8 (相信大家都是知道的,但是明知山有虎,偏向虎山行)。

事实上会根据不同的奖品 设定不同的权重 ,便宜的物品权重极高(接近90% ),贵重的物品权重极低(少于1%,甚至为0)。

从下图可以看到,288 金币的权重为33005000 金币的权重为200 ,总权重为10000 。所以288 金币的概率为33%5000 金币的概率为2%

核心二 则是角度的计算

旋转的角度=当前转盘的角度-当前转盘的角度%360 - 360 / 8 * i - 1080

其中

  • -当前转盘的角度%360是为了让转盘复位,可以从当前旋转继续旋转。
  • -360 / 8 * i则是转盘应该旋转到的角度。
  • -1080 则是为了转盘效果让转盘多转3圈。

下面一起来实现一个抽奖转盘。

3.抽奖转盘的实现

1.环境

引擎版本:Cocos Creator 3.8.1

编程语言:TypeScript

2.资源准备

首先 根据抽奖转盘的组成,准备一些图片,其中包括:

  • 一个8等分的转盘。
  • 一个指针。
  • 一些奖励的图片(金币和钻石)。

然后简单编辑一下UI界面。

其中要注意 的是如果图片的中心不是 转盘的中心 ,需要稍微调整一下锚点 ,否者转起来奇奇怪怪

其次是奖励的子项 ,可以只拼一个 ,但是中心也要移动到 转盘中心,然后通过克隆和旋转生成其他的。

3.编写代码

首先创建一个Turntable组件。

typescript 复制代码
import { _decorator, Component, find, Input, input, instantiate, KeyCode, Label, Node, Sprite, SpriteFrame, tween } from 'cc';
const { ccclass, property } = _decorator;

type ItemNode = { icon: Sprite, count: Label };

@ccclass('Turntable')
export class Turntable extends Component {
}

然后 定义一下奖品的配置 ,包括奖品类型type、奖品数量count和奖品权重weight。小伙伴们可以写到配置 里面去,通过配置驱动

typescript 复制代码
private DropLibs = [
{ type: 1, count: 288, weight: 3300 },
{ type: 2, count: 3, weight: 2200 },
{ type: 1, count: 1000, weight: 1000 },
{ type: 1, count: 2000, weight: 500 },
{ type: 2, count: 10, weight: 600 },
{ type: 1, count: 5000, weight: 200 },
{ type: 2, count: 30, weight: 200 },
{ type: 1, count: 500, weight: 2000 }
];

根据配置初始化转盘,核心方法为:

  • 通过instantiate克隆奖励项。
  • 通过angle属性修改奖励项旋转。
typescript 复制代码
this.TurntableNode = find("Canvas/Turntable/TurntableNode");
let length = this.DropLibs.length;
for (let i = 0; i < length; i++) {
    let dropLib = this.DropLibs[i];
    let node: Node;
    if (i == 0) {
        node = this.TurntableNode.children[0];
    }
    else {
        node = instantiate(this.TurntableNode.children[0]);
        this.TurntableNode.addChild(node);
    }
    this.ItemNodes.push({ icon: node.getComponentInChildren(Sprite), count: node.getComponentInChildren(Label) });
    this.ItemNodes[i].icon.spriteFrame = dropLib.type == 1 ? this.iconSpriteFrame1 : this.iconSpriteFrame2;
    this.ItemNodes[i].count.string = "X" + dropLib.count;
    this.totalWeight += dropLib.weight;
    node.angle = 360 / length * i;
}

添加键盘事件 ,按下空格键 开始抽奖并开始播放动画,核心方法为:

  • 通过input.onInput.EventType.KEY_DOWN监听键盘事件。
  • 通过Math.random()产生随机数。
  • 通过tween实现动画。
typescript 复制代码
input.on(Input.EventType.KEY_DOWN, event => {
    if (event.keyCode == KeyCode.SPACE) {
        if (this.droping) return;
        this.droping = true;

        let length = this.DropLibs.length;
        let weight = Math.floor(Math.random() * this.totalWeight);
        let totalWeight = 0;
        for (let i = 0; i < length; i++) {
            let dropLib = this.DropLibs[i];
            totalWeight += dropLib.weight;
            if (weight < totalWeight) {
                var rotation = this.TurntableNode.eulerAngles.z;
                var to = rotation - 1080 - 360 / 8 * i - rotation % 360;
                var rand = Math.floor(Math.random() * 90) + 90;
                console.log(dropLib);
                tween(this.TurntableNode).to(1, { angle: to + rand })
                    .to(3, { angle: to - 360 }, { easing: 'quintOut' })
                    .call(() => {
                        this.droping = false;
                    })
                    .start();
                break;
            }
        }
    }
})

4.效果演示

结语

看完这个,概率都是假的,我再也不要当赌狗了...

在哪里 可以看到如此清晰的思路,快跟上我的节奏!关注我 ,和我一起了解 游戏行业最新动态,学习游戏开发技巧。

我是"亿元程序员",一位有着8年游戏行业经验的主程。在游戏开发中,希望能给到您帮助, 也希望通过您能帮助到大家。

AD:笔者线上的小游戏《贪吃蛇掌机经典》《重力迷宫球》《填色之旅》大家可以自行点击搜索体验。

实不相瞒,想要个在看 !请把该文章分享给你觉得有需要的其他小伙伴。谢谢!

推荐专栏:

你知道王者荣耀是怎么实现技能范围指示器的吗?

8年主程手把手打造Cocos独立游戏开发框架

和8年游戏主程一起学习设计模式

从零开始开发贪吃蛇小游戏到上线系列

本文源工程 可通过阅读原文获取。

相关推荐
G_G#8 分钟前
纯前端js插件实现同一浏览器控制只允许打开一个标签,处理session变更问题
前端·javascript·浏览器标签页通信·只允许一个标签页
@大迁世界23 分钟前
TypeScript 的本质并非类型,而是信任
开发语言·前端·javascript·typescript·ecmascript
GIS之路32 分钟前
GDAL 实现矢量裁剪
前端·python·信息可视化
是一个Bug35 分钟前
后端开发者视角的前端开发面试题清单(50道)
前端
Amumu1213837 分钟前
React面向组件编程
开发语言·前端·javascript
持续升级打怪中1 小时前
Vue3 中虚拟滚动与分页加载的实现原理与实践
前端·性能优化
GIS之路1 小时前
GDAL 实现矢量合并
前端
hxjhnct1 小时前
React useContext的缺陷
前端·react.js·前端框架
前端 贾公子1 小时前
从入门到实践:前端 Monorepo 工程化实战(4)
前端
菩提小狗2 小时前
Sqlmap双击运行脚本,双击直接打开。
前端·笔记·安全·web安全