“打工搬砖记”中吃什么的轮盘功能实现(二)

发布于:2024-05-15 ⋅ 阅读:(212) ⋅ 点赞:(0)

打工搬砖记

先来一个吃什么轮盘的预览图,这轮盘文案加字呈圆形铺出来,开始后旋转到指定的选项处停下来。
已上线小程序“打工人搬砖记”,可以扫码进行预览观看。
请添加图片描述
请添加图片描述

转盘主要的逻辑实现

1、通过绑定style绑定值为“prizeBoxStyle”,设置每个选项的颜色以及后续转盘转动需要操作这个值。
2、通过绑定style绑定值为“prizeStyle”,然后通过“rotateAngle()”方法计算出总共有几个选项,然后算出每个选项需要旋转的角度。
3、通过“totalRunAngle()”计算出转盘最后需要转动角度,所以说游戏在开始的一瞬间就程序就已经知道,抽中的是那一个。
4、为了使转盘有声音就使用“uni.createInnerAudioContext()”来创建音乐,这个地方需要注意的是,如果想要后续“.stop()”停下音乐,在创建的时候一定不要设置为自动播放,就是说“autoplay = false”。

具体代码如下:

<template>
	<view>
		<image src="../../static/lunch/lunchBcg.jpg" class="bcgImg" mode=""></image>
		<view class="container">
			<view class="container-title"></view>

			<view class="prize-box-relative">
				<view class="prize-box">
					<view class="prize-list" ref="prizeWrap" :style="prizeBoxStyle">
						<div class="prize-item" v-for="(item, index) in prizeList" :style="[prizeStyle(index)]">
							<text>{{ item }}</text>
						</div>
					</view>
				</view>
			</view>
			<image @click="openGame()" src="../../static/lunch/turntable.png" class="turntableImg" mode=""></image>
		</view>

		<!-- 弹框 :抽中要吃的-->
		<view v-show="tipShow" class="tip_box">
			<view class="tip_content">
				<image src="../../static/lunch/tip.png" class="tip_img" mode=""></image>
				<view class="tip_txt">
					{{prizeList[prizeId] }}
				</view>
				<view class="tip_btn" @click="tipShow = false"></view>
			</view>
		</view>
	</view>
</template>

<script>
	import {
		turnList
	} from 'config/api.js';
	export default {
		data() {
			return {
				// colorList: ['#f69602', '#f8ca41', '#ffe7c9','#afe2ec'],
				colorList: ['#fe9539', '#fadf94', '#5fcbd1', '#ffffff'],
				prizeList: ["豆浆", "胡辣汤", "韭菜鸡蛋韭菜鸡蛋", "奖品4", "奖品5", "奖品6", "奖品4", "奖品5", "奖品6"],
				isRunning: false, // 是否正在抽奖
				baseRunAngle: 360 * 5, // 总共转动角度 至少5圈
				prizeId: 0, // 中奖id
				rotatePrize: 40,
				tipShow: false,
				prizeBoxStyle: '',
				audioMusic: '',
			}
		},
		onLoad() {
			this.getPrizeList()
			uni.$on('updateTurn', (data) => {
				this.getPrizeList()
			})
		},
		methods: {
			getPrizeList() {
				turnList({
					data: {
						eatType: this.activeMenu
					},
					custom: {
						auth: true,
						toast: false,
						catch: true
					}
				}).then((res) => {
					let arr = []
					res.map(value => {
						arr.push(value.name)
					})
					this.prizeList = arr
					this.rotatePrize = 360 / arr.length
					this.prizeBoxStyle = this.bgColor()
					this.initGame()
				})
			},
			// 初始化转盘游戏
			initGame() {
				this.rotateAngle()
			},
			// 开始游戏
			openGame() {
				this.startGame()
			},
			// 开始游戏
			startGame() {
				if (!this.isRunning) {
					this.isRunning = true
					this.prizeId = this.getRandomNum()
					this.startRun()
				}
			},
			// 游戏运行
			startRun() {
				this.prizeBoxStyle = `${this.bgColor()} transform: rotate(${this.totalRunAngle()}deg);transition: all 4s ease;`

				this.audioMusic = uni.createInnerAudioContext();
				this.audioMusic.autoplay = false;
				this.audioMusic.startTime = 2;
				this.audioMusic.sessionCategory = 'ambient';
				this.audioMusic.src = '/static/lunch/music01.mp3';
				this.audioMusic.play();
				setTimeout(() => {
					this.audioMusic.stop()
					this.audioMusic.destroy()
					this.audioMusic = null
				}, 3700)


				this.playAudio()
				setTimeout(() => {
					this.tipShow = true
					this.isRunning = false
					this.prizeBoxStyle = `${this.bgColor()} transform: rotate(${this.totalRunAngle() - this.baseRunAngle}deg);`
				}, 4000)
			},
			getRandomNum() {
				const num = Math.floor(Math.random() * this.prizeList.length)
				return num
			},
			// 平均每个奖品角度
			rotateAngle() {
				this.rotatePrize = 360 / this.prizeList.length
			},
			// 奖品布局
			prizeStyle(i) {
				let _degree = this.rotatePrize
				let style = {}

				style.width = 2 * 130 * Math.sin(_degree / 2 * Math.PI / 180) + 'px'
				style.height = '130px'
				style.transform = `rotate(${_degree * i + _degree / 2}deg)`
				style.transformOrigin = '50% 100%'

				return style
			},
			// 计算绘制转盘背景
			bgColor() {
				let colorVal = ''
				for (let i = 0; i < this.prizeList.length; i++) {
					colorVal += `${this.colorList[i % 4]} ${this.rotatePrize * i}deg ${this.rotatePrize * (i + 1)}deg,`
				}
				return ` background: conic-gradient(${colorVal.slice(0, -1)});transform: rotate(-${this.rotatePrize/2}deg); `
			},

			// 要执行总转角度数
			totalRunAngle() {
				return this.baseRunAngle + 360 - this.prizeId * this.rotatePrize - this.rotatePrize / 2
			},
			// 转盘停下来时的声音
			playAudio() {
				setTimeout(() => {
					const innerAudioContext = uni.createInnerAudioContext();
					innerAudioContext.autoplay = true;
					innerAudioContext.sessionCategory = 'ambient';
					innerAudioContext.src = '/static/lunch/music.mp3';
					innerAudioContext.onPlay();
				}, 3800)
			}

		}
	}
</script>

<style lang="scss">
	.bcgImg {
		position: fixed;
		width: 750rpx;
		height: 100vh;
	}

	.container {
		position: relative;
		width: 660rpx;
		height: 660rpx;
		margin: 0 auto;
	}

	.container-title {
		font-size: 56rpx;
		font-weight: bold;
		color: #FFFFFF;
		text-align: center;
		line-height: 160rpx;
		height: 160rpx;
		letter-spacing: 20px;
	}

	.turntableImg {
		width: 100%;
		height: 100%;
		position: absolute;
		top: 160rpx;
	}



	.prize-box-relative {
		width: 100%;
		height: 100%;
		display: flex;
		align-items: center;
		justify-content: center;
	}

	.prize-box {
		width: 300px;
		height: 300px;
		position: relative;
	}

	.prize-list {
		width: 100%;
		height: 100%;
		border-radius: 50%;
		overflow: hidden;
	}

	.prize-item {
		/*border: 2px solid red;*/
		position: absolute;
		left: 0;
		right: 0;
		top: 20px;
		margin: auto;
		text-align: center;
	}

	.prize-item text {
		display: flex;
		align-items: center;
		writing-mode: vertical-rl;
		color: #333333;
		font-size: 26rpx;
		font-weight: bold;
		text-align: center;
		line-height: 20px;
		width: 100%;
	}

	.tip_box {
		z-index: 10;
		position: fixed;
		top: 0;
		width: 100%;
		height: 100vh;
		background: rgba(0, 0, 0, 0.5);
		display: flex;
		align-items: center;
		justify-content: center;
	}

	.tip_content {
		position: relative;
	}

	.tip_img {
		width: 640rpx;
		height: 480rpx;
	}

	.tip_txt {
		position: absolute;
		top: 160rpx;
		width: 600rpx;
		text-align: center;
		font-weight: bold;
		font-size: 38rpx;
	}

	.tip_btn {
		position: absolute;
		bottom: 60rpx;
		left: 210rpx;
		width: 200rpx;
		height: 100rpx;
	}


	.food_menu_list {
		position: fixed;
		bottom: 100rpx;
		width: 710rpx;
		padding: 50rpx 20rpx;
		display: flex;
		flex-wrap: wrap;
		font-size: 26rpx;
		color: #999999;
		font-weight: bold;

		.menu_box {
			margin: 0 10rpx;
			width: 174rpx;
			background: rgba(244, 244, 244, 0.6);
			box-shadow: 0 0 10rpx #FFFFFF;
			display: flex;
			align-items: center;
			padding: 20rpx;
			border-radius: 10rpx;
			margin-bottom: 30rpx;

			.menu_img {
				width: 40rpx;
				height: 40rpx;
				margin-right: 10rpx;
			}
		}

		.menu_active {
			color: #53851b;
			background: #f4f4f4;
			box-shadow: 0 0 10rpx #f4f4f4;
		}


		.menu_btn {
			font-size: 36rpx;
			color: #ffffff;
			line-height: 80rpx;
			text-align: center;
			width: 100%;
			border-radius: 10rpx;
			border: 2rpx #FFFFFF solid;
		}
	}
</style>

转盘的素材

我发现穿上后好像就成为了jpg格式了,注意转盘哪个一定要是png格式的,不然会把转盘的内容给覆盖住,音乐和背景图的话就自己找找吧!
请添加图片描述
请添加图片描述

小结

总的来说实现过程不难,难的是思路以及行动力。加油打工人!!!