效果简述:点击设置“骰子个数”,喝一杯前,先摇一摇。
骰子图片命名示例: 1.png、2.png
一、dice.js
Page({
data: {
numDice: 1, // 初始化骰子数
diceImages: [],
dicePositions: [],
rolling: false,
intervalId: null
},
onInputNumDice(e) {
this.setData({
numDice: parseInt(e.detail.value) + 1,
diceImages: [],
dicePositions: []
});
},
rollDice() {
if (this.data.rolling) return;
const { numDice } = this.data;
this.setData({ rolling: true });
const intervalId = setInterval(() => {
const rollingImages = [];
for (let i = 0; i < numDice; i++) {
rollingImages.push('http://xxx/dice/' + Math.floor(Math.random() * 6 + 1) + '.png');
}
this.setData({
diceImages: rollingImages,
dicePositions: this.generateRandomPositions(numDice)
});
}, 100);
this.setData({
intervalId: intervalId
});
},
revealDice() {
if (!this.data.rolling) return;
clearInterval(this.data.intervalId);
const { numDice } = this.data;
const finalDiceImages = [];
for (let i = 0; i < numDice; i++) {
finalDiceImages.push('http://xxx/dice/' + Math.floor(Math.random() * 6 + 1) + '.png');
}
this.setData({
diceImages: finalDiceImages,
rolling: false,
intervalId: null,
dicePositions: this.generateRandomPositions(numDice)
});
},
generateRandomPositions(numDice) {
const positions = [];
const size = 50;
const containerWidth = 300;
const containerHeight = 200;
const margin = 1; // 骰子间距
for (let i = 0; i < numDice; i++) {
let position;
let overlaps;
do {
overlaps = false;
position = {
left: Math.floor(Math.random() * (containerWidth - size)),
top: Math.floor(Math.random() * (containerHeight - size))
};
for (const other of positions) {
if (Math.abs(position.left - other.left) < size + margin && Math.abs(position.top - other.top) < size + margin) {
overlaps = true;
break;
}
}
} while (overlaps);
positions.push(position);
}
return positions;
},
goBack() {
wx.navigateBack();
}
});
二、dice.json
这里不需要填,用默认的
{
"usingComponents": {}
}
三、dice.wxml
<view class="container">
<image class="background" src="http://xxx/bg/login_bg2.png" mode="aspectFill" />
<view class="header">
<image src="http://xxx/dice/return.png" class="back-button" bindtap="goBack" />
</view>
<view class="content">
<view class="dice-container">
<block wx:for="{{diceImages}}" wx:key="index">
<image src="{{item}}" class="dice" style="left:{{dicePositions[index].left}}px; top:{{dicePositions[index].top}}px;" />
</block>
</view>
<view class="settings">
<label for="numDice">骰子个数:</label>
<picker mode="selector" range="{{[1, 2, 3, 4, 5, 6, 7]}}" value="{{numDice-1}}" bindchange="onInputNumDice">
<view>{{numDice}} 个</view>
</picker>
</view>
<view class="buttons">
<view class="button-container">
<image src="http://xxx/dice/roll.png" class="button" bindtap="rollDice" />
<text>投掷</text>
</view>
<view class="button-container">
<image src="http://xxx/dice/open.png" class="button" bindtap="revealDice" />
<text>揭开</text>
</view>
</view>
</view>
</view>
四、dice.wxss
.container {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
width: 100%;
height: 100vh;
position: relative;
overflow: hidden;
}
.background {
position: absolute;
width: 100%;
height: 100%;
z-index: -1;
}
.header {
position: absolute;
top: 10px;
left: 10px;
}
.back-button {
width: 30px;
height: 30px;
margin-top: 20px;
margin-left: 10px;
}
.content {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100%;
}
.dice-container {
position: relative;
width: 300px;
height: 300px;
margin-bottom: 20px;
}
.dice {
width: 50px;
height: 50px;
position: absolute;
}
.settings {
display: flex;
align-items: center;
margin-bottom: 20px;
}
.settings label {
margin-right: 10px;
}
.buttons {
display: flex;
justify-content: center;
}
.button-container {
display: flex;
flex-direction: column;
align-items: center;
margin: 0 40px;
}
.button {
width: 50px;
height: 50px;
margin-bottom: 5px;
}