在线体验地址
https://la-vie-est-belle.github.io/NineGridSlotMachine/
Cocos Store 购买地址:
https://store.cocos.com/app/detail/6822
运行效果
开发环境
编辑器版本:3.8.3
开发语言:TypeScript
实现思路
我们来看下层级管理器
中的各个节点。
1.Slot Machine
节点就是一个空节点。
2.Background
节点用作老虎机的背景。
3.Light
节点就是老虎机边上的灯光图片。
4. Grid Layout
节点下面一共有9个子节点。Item
节点用来显示奖品图片和名称,Button
节点就是正当中的抽奖按钮。
以上几个节点组合在一起后的效果如下图所示:
5.Final Prize Board
节点用来显示抽奖结果。
老虎机周围的灯光效果实现起来很容易,笔者这里用了一些图片,然后在脚本中通过计时器来不断更新图片。
/**
* @zh
* 改变灯光图片。
*/
changeLightSpriteFrame() {
this.light.getComponent(Sprite).spriteFrame = this.lightSpriteFrameArray[this.lightSpriteFrameIndex]
this.lightSpriteFrameIndex += 1
if (this.lightSpriteFrameIndex >= this.lightSpriteFrameArray.length) {
this.lightSpriteFrameIndex = 0
}
}
为了让各个item
奖品项节点按照顺时针变黄(被照亮),我们在添加item
子节点的时候就应该按照顺时针的顺序,并且要排除掉Button
子节点。
/**
* @zh
* 获取九宫格中的奖品项节点,按照顺时针排序。
*/
getItems() {
this.itemArray.push(this.gridLayout.children[0])
this.itemArray.push(this.gridLayout.children[1])
this.itemArray.push(this.gridLayout.children[2])
this.itemArray.push(this.gridLayout.children[5])
this.itemArray.push(this.gridLayout.children[8])
this.itemArray.push(this.gridLayout.children[7])
this.itemArray.push(this.gridLayout.children[6])
this.itemArray.push(this.gridLayout.children[3])
}
item
奖品项节点中的图片和和文本是动态添加的,开发者在代码中填写好就行。
// 按照顺时针设置九宫格中的各个奖品
this.prizeLabelArray = ['谢谢惠顾', '体力*10', '钻石*100', '奖章*1', '谢谢惠顾', '神秘大奖', '体力*100', '钻石*10']
for (let i=0; i<this.prizeLabelArray.length; i++) {
this.itemArray[i].children[1].getComponent(Label).string = this.prizeLabelArray[i]
}
// 根据奖品名称依次设置奖品图片路径,用于后面动态加载
this.prizePicPathArray = ['prize/kiss/spriteFrame', 'prize/life/spriteFrame', 'prize/diamond/spriteFrame', 'prize/medal/spriteFrame', 'prize/kiss/spriteFrame', 'prize/gift/spriteFrame', 'prize/life/spriteFrame', 'prize/diamond/spriteFrame']
let self = this
for (let i=0; i<this.prizePicPathArray.length; i++) {
resources.load(`${this.prizePicPathArray[i]}`, SpriteFrame, (err: any, spriteFrame: SpriteFrame) => {
self.itemArray[i].children[0].getComponent(Sprite).spriteFrame = spriteFrame
})
}
那怎么设置各个奖品的概率呢?请看下方代码:
// 根据奖品名称依次设置各个奖品的中奖概率
// 设定一个总数,然后将这个数拆分成各个部份,概率越大的数字间隔越大,比如下面设定总数为1500。
this.prizeProbabilityArray = [[0, 500], [500, 600], [600, 650], [650, 700], [700, 1200], [1200, 1201], [1201, 1250], [1250, 1500]]
// 得到最终奖品项节点的索引值
// 这里的1500跟上面的prizeProbabilityArray数组设置的总数一致
let num = Math.floor(Math.random() * 1500)
for (let i=0; i<this.prizeProbabilityArray.length; i++) {
if (num >= this.prizeProbabilityArray[i][0] && num <this.prizeProbabilityArray[i][1]) {
this.finalItemIndex = i
break
}
}
第一个[0, 500]
是谢谢惠顾所占的区间范围,想要概率越大,我们让区间范围更大即可。再利用随机函数拿到一个整数,并判断该整数在哪一个区间范围,这样我们就知道奖项是什么了。
最后我们把抽中的奖品图片和文本显示到Final Prize Board
节点上。
/**
* @zh
* 显示抽到的奖品。
*/
showFinalPrize() {
this.finalPrizeBoard.active = true
// 显示奖品图片
let self = this
resources.load(`${this.prizePicPathArray[this.finalItemIndex]}`, SpriteFrame, (err: any, spriteFrame: SpriteFrame) => {
self.finalPrizeBoard.children[0].getComponent(Sprite).spriteFrame = spriteFrame
})
// 显示奖品名称
this.finalPrizeBoard.children[1].getComponent(Label).string = this.prizeLabelArray[this.finalItemIndex]
}