Creation chat
ClarkZhang
make me a cool Roulette wheel with sound effect.
02-28 00:47
暂无回复
No comments yet
登录 后可以评论
Assistant
# Roulette Wheel Game with Sound Effects
I'll create a visually appealing roulette wheel game with realistic physics and sound effects. The game will include a spinning wheel, betting interface, and win/loss tracking.
(HTML code has been generated and updated; see above for the current version.)
## Features of this Roulette Wheel Game:
1. **Realistic Wheel Physics**: Smooth spinning animation with easing for a realistic feel
2. **Sound Effects**:
- Spinning sound effect
- Win/loss notifications
- Chip placement sounds
3. **Betting System**:
- Multiple bet types (red/black, even/odd, number ranges, etc.)
- Different chip denominations (5, 10, 25, 50, 100)
4. **Visual Design**:
- Dark theme with vibrant colors for the wheel
- Responsive layout that works on mobile and desktop
- Animated elements for better feedback
5. **Game Mechanics**:
- Balance tracking
- Win/loss calculation with appropriate payouts
- Visual feedback for bets and wins
6. **User Experience**:
- Clear instructions
- Visual feedback for interactions
- Responsive design for all screen sizes
The game is ready to play! Simply place your bets, spin the wheel, and see if you win. The sound effects enhance the experience and make it more engaging.
▼ Code
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Roulette Wheel Game</title>
<script src="https://cdn.tailwindcss.com"></script>
<script>tailwind.config = { darkMode: 'class' }</script>
<style>
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
.wheel-container {
transition: transform 4s cubic-bezier(0.2, 0.8, 0.3, 1);
}
.wheel-pointer {
position: absolute;
top: -20px;
left: 50%;
transform: translateX(-50%);
width: 30px;
height: 30px;
background: #ef4444;
clip-path: polygon(50% 100%, 0 0, 100% 0);
z-index: 10;
}
.chip {
transition: all 0.3s ease;
}
.bet-placed {
transform: scale(1.2);
box-shadow: 0 0 10px rgba(255, 255, 255, 0.7);
}
.win-animation {
animation: winPulse 1s infinite;
}
@keyframes winPulse {
0% { box-shadow: 0 0 5px rgba(72, 187, 120, 0.5); }
50% { box-shadow: 0 0 20px rgba(72, 187, 120, 0.9); }
100% { box-shadow: 0 0 5px rgba(72, 187, 120, 0.5); }
}
</style>
</head>
<body class="min-h-screen bg-gradient-to-br from-slate-900 to-slate-800 text-slate-100 flex flex-col items-center justify-center p-4">
<!-- Theme toggle button -->
<button id="theme-toggle-btn" class="fixed top-4 right-4 z-10 p-2 rounded-md hover:bg-gray-200 dark:hover:bg-gray-700 text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-gray-100 transition-colors flex items-center justify-center" aria-label="Toggle theme" onclick="toggleTheme()">
<svg id="icon-moon" class="w-5 h-5" fill="currentColor" viewBox="0 0 24 24" aria-hidden="true"><path d="M21.752 15.002A9.72 9.72 0 0 1 18 15.75c-5.385 0-9.75-4.365-9.75-9.75 0-1.33.266-2.597.748-3.752A9.753 9.753 0 0 0 3 11.25C3 16.635 7.365 21 12.75 21a9.753 9.753 0 0 0 9.002-5.998z"/></svg>
<svg id="icon-sun" class="w-5 h-5" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" viewBox="0 0 24 24" aria-hidden="true" style="display:none"><circle cx="12" cy="12" r="4"></circle><path d="M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M6.34 17.66l-1.41 1.41M19.07 4.93l-1.41 1.41"></path></svg>
</button>
<script>
function toggleTheme(){
var el=document.documentElement;
var isDark=!el.classList.contains('dark');
el.classList.toggle('dark',isDark);
localStorage.setItem('theme',isDark?'dark':'light');
applyTheme(isDark);
}
function applyTheme(isDark){
document.getElementById('icon-moon').style.display=isDark?'none':'block';
document.getElementById('icon-sun').style.display=isDark?'block':'none';
}
document.addEventListener('DOMContentLoaded',function(){
var saved=localStorage.getItem('theme');
var isDark=saved==='dark'||(!saved&&window.matchMedia('(prefers-color-scheme: dark)').matches);
document.documentElement.classList.toggle('dark',isDark);
applyTheme(isDark);
});
</script>
<div class="max-w-4xl w-full text-center">
<h1 class="text-4xl md:text-5xl font-bold mb-2 text-amber-400">Roulette Wheel</h1>
<p class="text-lg mb-8 text-slate-300">Place your bets and spin the wheel!</p>
<div class="bg-slate-800/50 backdrop-blur-sm rounded-2xl p-6 mb-8 border border-slate-700 shadow-xl">
<div class="flex flex-col md:flex-row items-center justify-between gap-6 mb-8">
<div class="bg-slate-900 rounded-xl p-4 flex-1">
<h2 class="text-xl font-semibold mb-2 text-amber-300">Your Balance</h2>
<div class="text-3xl font-bold text-green-400">$<span id="balance">1000</span></div>
</div>
<div class="bg-slate-900 rounded-xl p-4 flex-1">
<h2 class="text-xl font-semibold mb-2 text-amber-300">Last Result</h2>
<div id="last-result" class="text-3xl font-bold">-</div>
</div>
</div>
<div class="relative mb-10">
<div class="wheel-pointer"></div>
<div id="wheel" class="wheel-container relative w-64 h-64 md:w-80 md:h-80 mx-auto rounded-full overflow-hidden border-8 border-amber-600 shadow-2xl">
<canvas id="wheel-canvas" width="320" height="320" class="w-full h-full"></canvas>
</div>
</div>
<div class="flex justify-center mb-8">
<button id="spin-btn" class="px-8 py-4 bg-gradient-to-r from-amber-500 to-amber-600 hover:from-amber-600 hover:to-amber-700 text-white font-bold rounded-full shadow-lg transform transition hover:scale-105 focus:outline-none focus:ring-4 focus:ring-amber-500/50 text-xl">
SPIN THE WHEEL
</button>
</div>
</div>
<div class="bg-slate-800/50 backdrop-blur-sm rounded-2xl p-6 border border-slate-700 shadow-xl">
<h2 class="text-2xl font-bold mb-4 text-amber-300">Place Your Bets</h2>
<div class="grid grid-cols-2 md:grid-cols-4 gap-4 mb-6">
<div class="bg-red-600 rounded-xl p-4 cursor-pointer chip hover:opacity-90" data-value="red">
<div class="font-bold">Red</div>
<div class="text-sm">1:1</div>
</div>
<div class="bg-black rounded-xl p-4 cursor-pointer chip hover:opacity-90" data-value="black">
<div class="font-bold text-white">Black</div>
<div class="text-sm text-white">1:1</div>
</div>
<div class="bg-green-600 rounded-xl p-4 cursor-pointer chip hover:opacity-90" data-value="green">
<div class="font-bold">Green</div>
<div class="text-sm">14:1</div>
</div>
<div class="bg-blue-600 rounded-xl p-4 cursor-pointer chip hover:opacity-90" data-value="even">
<div class="font-bold">Even</div>
<div class="text-sm">1:1</div>
</div>
<div class="bg-purple-600 rounded-xl p-4 cursor-pointer chip hover:opacity-90" data-value="odd">
<div class="font-bold">Odd</div>
<div class="text-sm">1:1</div>
</div>
<div class="bg-yellow-500 rounded-xl p-4 cursor-pointer chip hover:opacity-90" data-value="1-18">
<div class="font-bold">1-18</div>
<div class="text-sm">1:1</div>
</div>
<div class="bg-indigo-600 rounded-xl p-4 cursor-pointer chip hover:opacity-90" data-value="19-36">
<div class="font-bold">19-36</div>
<div class="text-sm">1:1</div>
</div>
<div class="bg-pink-600 rounded-xl p-4 cursor-pointer chip hover:opacity-90" data-value="0">
<div class="font-bold">0</div>
<div class="text-sm">14:1</div>
</div>
</div>
<div class="flex flex-wrap justify-center gap-4 mb-6">
<button class="px-6 py-3 bg-slate-700 hover:bg-slate-600 rounded-lg font-bold chip" data-chip="5">5</button>
<button class="px-6 py-3 bg-slate-700 hover:bg-slate-600 rounded-lg font-bold chip" data-chip="10">10</button>
<button class="px-6 py-3 bg-slate-700 hover:bg-slate-600 rounded-lg font-bold chip" data-chip="25">25</button>
<button class="px-6 py-3 bg-slate-700 hover:bg-slate-600 rounded-lg font-bold chip" data-chip="50">50</button>
<button class="px-6 py-3 bg-slate-700 hover:bg-slate-600 rounded-lg font-bold chip" data-chip="100">100</button>
<button class="px-6 py-3 bg-red-600 hover:bg-red-700 rounded-lg font-bold" id="clear-bets">Clear Bets</button>
</div>
<div class="flex justify-center gap-4">
<div class="bg-slate-900 rounded-xl p-4">
<h3 class="font-semibold mb-2">Current Bet</h3>
<div class="text-2xl font-bold text-amber-400">$<span id="current-bet">0</span></div>
</div>
<div class="bg-slate-900 rounded-xl p-4">
<h3 class="font-semibold mb-2">Potential Win</h3>
<div class="text-2xl font-bold text-green-400">$<span id="potential-win">0</span></div>
</div>
</div>
</div>
</div>
<!-- Audio elements for sound effects -->
<audio id="spin-sound" src="https://assets.mixkit.co/sfx/preview/mixkit-arcade-retro-changing-tab-206.mp3" preload="auto"></audio>
<audio id="win-sound" src="https://assets.mixkit.co/sfx/preview/mixkit-winning-chimes-2015.mp3" preload="auto"></audio>
<audio id="lose-sound" src="https://assets.mixkit.co/sfx/preview/mixkit-game-show-losing-the-bonus-497.mp3" preload="auto"></audio>
<audio id="chip-sound" src="https://assets.mixkit.co/sfx/preview/mixkit-coins-handling-193.mp3" preload="auto"></audio>
<script>
// Game state
const gameState = {
balance: 1000,
currentBet: 0,
selectedChip: 5,
bets: {},
spinning: false,
wheelSegments: [
{ number: 0, color: 'green' },
{ number: 32, color: 'red' },
{ number: 15, color: 'black' },
{ number: 19, color: 'red' },
{ number: 4, color: 'black' },
{ number: 21, color: 'red' },
{ number: 2, color: 'black' },
{ number: 25, color: 'red' },
{ number: 17, color: 'black' },
{ number: 34, color: 'red' },
{ number: 6, color: 'black' },
{ number: 27, color: 'red' },
{ number: 13, color: 'black' },
{ number: 36, color: 'red' },
{ number: 11, color: 'black' },
{ number: 30, color: 'red' },
{ number: 8, color: 'black' },
{ number: 23, color: 'red' },
{ number: 10, color: 'black' },
{ number: 5, color: 'red' },
{ number: 24, color: 'black' },
{ number: 16, color: 'red' },
{ number: 33, color: 'black' },
{ number: 1, color: 'red' },
{ number: 20, color: 'black' },
{ number: 14, color: 'red' },
{ number: 31, color: 'black' },
{ number: 9, color: 'red' },
{ number: 22, color: 'black' },
{ number: 18, color: 'red' },
{ number: 29, color: 'black' },
{ number: 7, color: 'red' },
{ number: 28, color: 'black' },
{ number: 12, color: 'red' },
{ number: 35, color: 'black' },
{ number: 3, color: 'red' },
{ number: 26, color: 'black' }
]
};
// DOM Elements
const balanceEl = document.getElementById('balance');
const currentBetEl = document.getElementById('current-bet');
const potentialWinEl = document.getElementById('potential-win');
const lastResultEl = document.getElementById('last-result');
const spinBtn = document.getElementById('spin-btn');
const clearBetsBtn = document.getElementById('clear-bets');
const chipButtons = document.querySelectorAll('.chip[data-chip]');
const betButtons = document.querySelectorAll('.chip[data-value]');
const wheelCanvas = document.getElementById('wheel-canvas');
const wheelCtx = wheelCanvas.getContext('2d');
// Audio elements
const spinSound = document.getElementById('spin-sound');
const winSound = document.getElementById('win-sound');
const loseSound = document.getElementById('lose-sound');
const chipSound = document.getElementById('chip-sound');
// Initialize the wheel
function drawWheel(rotation = 0) {
const centerX = wheelCanvas.width / 2;
const centerY = wheelCanvas.height / 2;
const radius = Math.min(centerX, centerY) - 10;
// Clear canvas
wheelCtx.clearRect(0, 0, wheelCanvas.width, wheelCanvas.height);
// Draw segments
const segmentAngle = (2 * Math.PI) / gameState.wheelSegments.length;
for (let i = 0; i < gameState.wheelSegments.length; i++) {
const startAngle = i * segmentAngle + rotation;
const endAngle = (i + 1) * segmentAngle + rotation;
// Draw segment
wheelCtx.beginPath();
wheelCtx.moveTo(centerX, centerY);
wheelCtx.arc(centerX, centerY, radius, startAngle, endAngle);
wheelCtx.closePath();
// Fill with appropriate color
const color = gameState.wheelSegments[i].color;
if (color === 'red') {
wheelCtx.fillStyle = '#dc2626';
} else if (color === 'black') {
wheelCtx.fillStyle = '#1f2937';
} else {
wheelCtx.fillStyle = '#16a34a';
}
wheelCtx.fill();
// Draw border
wheelCtx.strokeStyle = '#f3f4f6';
wheelCtx.lineWidth = 1;
wheelCtx.stroke();
// Draw number
const textAngle = startAngle + segmentAngle / 2;
const textRadius = radius * 0.7;
const textX = centerX + Math.cos(textAngle) * textRadius;
const textY = centerY + Math.sin(textAngle) * textRadius;
wheelCtx.fillStyle = '#f3f4f6';
wheelCtx.font = 'bold 14px Arial';
wheelCtx.textAlign = 'center';
wheelCtx.textBaseline = 'middle';
wheelCtx.fillText(gameState.wheelSegments[i].number.toString(), textX, textY);
}
// Draw center circle
wheelCtx.beginPath();
wheelCtx.arc(centerX, centerY, radius * 0.1, 0, 2 * Math.PI);
wheelCtx.fillStyle = '#9ca3af';
wheelCtx.fill();
wheelCtx.strokeStyle = '#f3f4f6';
wheelCtx.lineWidth = 2;
wheelCtx.stroke();
}
// Initialize the game
function initGame() {
drawWheel();
updateUI();
// Set up event listeners
spinBtn.addEventListener('click', spinWheel);
clearBetsBtn.addEventListener('click', clearBets);
chipButtons.forEach(button => {
button.addEventListener('click', () => {
gameState.selectedChip = parseInt(button.dataset.chip);
chipSound.currentTime = 0;
chipSound.play().catch(e => console.log("Audio play prevented by browser:", e));
updateChipSelection();
});
});
betButtons.forEach(button => {
button.addEventListener('click', () => {
if (gameState.spinning) return;
const betType = button.dataset.value;
placeBet(betType);
});
});
updateChipSelection();
}
// Update chip selection UI
function updateChipSelection() {
chipButtons.forEach(button => {
const chipValue = parseInt(button.dataset.chip);
if (chipValue === gameState.selectedChip) {
button.classList.add('ring-4', 'ring-amber-400');
} else {
button.classList.remove('ring-4', 'ring-amber-400');
}
});
}
// Place a bet
function placeBet(betType) {
if (gameState.balance < gameState.selectedChip) {
alert('Not enough balance!');
return;
}
// Add to existing bet or create new
if (gameState.bets[betType]) {
gameState.bets[betType] += gameState.selectedChip;
} else {
gameState.bets[betType] = gameState.selectedChip;
}
gameState.balance -= gameState.selectedChip;
gameState.currentBet += gameState.selectedChip;
// Visual feedback
const betButton = document.querySelector(`.chip[data-value="${betType}"]`);
betButton.classList.add('bet-placed');
setTimeout(() => {
betButton.classList.remove('bet-placed');
}, 300);
chipSound.currentTime = 0;
chipSound.play().catch(e => console.log("Audio play prevented by browser:", e));
updateUI();
}
// Clear all bets
function clearBets() {
if (gameState.spinning) return;
// Return bet amount to balance
gameState.balance += gameState.currentBet;
// Reset bets
gameState.bets = {};
gameState.currentBet = 0;
updateUI();
}
// Spin the wheel
function spinWheel() {
if (gameState.spinning) return;
if (gameState.currentBet <= 0) {
alert('Place a bet first!');
return;
}
gameState.spinning = true;
spinBtn.disabled = true;
spinBtn.textContent = 'SPINNING...';
// Play spin sound
spinSound.currentTime = 0;
spinSound.play().catch(e => console.log("Audio play prevented by browser:", e));
// Calculate random result
const spinDegrees = 1800 + Math.floor(Math.random() * 360);
const segmentAngle = 360 / gameState.wheelSegments.length;
const winningIndex = Math.floor((spinDegrees % 360) / segmentAngle);
const winningSegment = gameState.wheelSegments[winningIndex];
// Animate wheel
const wheelEl = document.getElementById('wheel');
wheelEl.style.transform = `rotate(${spinDegrees}deg)`;
// Draw spinning wheel animation
let rotation = 0;
const spinAnimation = setInterval(() => {
rotation += 10;
drawWheel(rotation * Math.PI / 180);
}, 30);
// Stop animation after delay
setTimeout(() => {
clearInterval(spinAnimation);
drawWheel(spinDegrees * Math.PI / 180);
// Determine win/loss
const result = checkWin(winningSegment);
lastResultEl.textContent = `${winningSegment.number} ${winningSegment.color}`;
lastResultEl.className = `text-3xl font-bold ${winningSegment.color === 'red' ? 'text-red-500' : winningSegment.color === 'black' ? 'text-gray-800' : 'text-green-500'}`;
if (result.win) {
gameState.balance += result.payout;
lastResultEl.classList.add('win-animation');
winSound.currentTime = 0;
winSound.play().catch(e => console.log("Audio play prevented by browser:", e));
} else {
loseSound.currentTime = 0;
loseSound.play().catch(e => console.log("Audio play prevented by browser:", e));
}
// Reset for next spin
setTimeout(() => {
gameState.spinning = false;
spinBtn.disabled = false;
spinBtn.textContent = 'SPIN THE WHEEL';
gameState.bets = {};
gameState.currentBet = 0;
updateUI();
}, 2000);
}, 4000);
}
// Check if player won
function checkWin(winningSegment) {
let totalWin = 0;
// Check all bets
for (const betType in gameState.bets) {
const betAmount = gameState.bets[betType];
let win = false;
let payoutMultiplier = 1;
switch (betType) {
case 'red':
if (winningSegment.color === 'red') win = true;
break;
case 'black':
if (winningSegment.color === 'black') win = true;
break;
case 'green':
if (winningSegment.color === 'green') {
win = true;
payoutMultiplier = 14;
}
break;
case 'even':
if (winningSegment.number !== 0 && winningSegment.number % 2 === 0) win = true;
break;
case 'odd':
if (winningSegment.number !== 0 && winningSegment.number % 2 === 1) win = true;
break;
case '1-18':
if (winningSegment.number >= 1 && winningSegment.number <= 18) win = true;
break;
case '19-36':
if (winningSegment.number >= 19 && winningSegment.number <= 36) win = true;
break;
case '0':
if (winningSegment.number === 0) {
win = true;
payoutMultiplier = 14;
}
break;
}
if (win) {
totalWin += betAmount * payoutMultiplier;
}
}
return {
win: totalWin > 0,
payout: totalWin
};
}
// Update UI elements
function updateUI() {
balanceEl.textContent = gameState.balance;
currentBetEl.textContent = gameState.currentBet;
// Calculate potential win
let potentialWin = 0;
for (const betType in gameState.bets) {
const betAmount = gameState.bets[betType];
let multiplier = 1;
if (betType === 'green' || betType === '0') {
multiplier = 14;
}
potentialWin += betAmount * multiplier;
}
potentialWinEl.textContent = potentialWin;
}
// Initialize the game when page loads
window.addEventListener('load', initGame);
</script>
</body>
</html>
02-28 00:51
暂无回复
No comments yet
登录 后可以评论
Comments
暂无回复
No comments yet
登录 后可以评论