Spaces:
Running
Running
| <html lang="zh-CN"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>轮盘赌游戏</title> | |
| <meta name="description" content="在线轮盘赌游戏,体验真实的赌场乐趣"> | |
| <link rel="stylesheet" href="assets/css/styles.css"> | |
| </head> | |
| <body> | |
| <div class="container"> | |
| <header class="header"> | |
| <h1>🎰 轮盘赌游戏</h1> | |
| <p class="subtitle">体验真实的赌场乐趣</p> | |
| </header> | |
| <main class="game-area"> | |
| <div class="wheel-container"> | |
| <div class="wheel-wrapper"> | |
| <div class="wheel" id="wheel"> | |
| <!-- 轮盘数字将通过JavaScript生成 --> | |
| </div> | |
| <div class="ball" id="ball"></div> | |
| <div class="wheel-pointer">▼</div> | |
| </div> | |
| </div> | |
| <div class="game-controls"> | |
| <div class="balance-info"> | |
| <div class="balance"> | |
| <span>余额:¥</span> | |
| <span id="balance">1000</span> | |
| </div> | |
| <div class="last-result" id="lastResult"> | |
| 点击开始按钮开始游戏 | |
| </div> | |
| </div> | |
| <div class="betting-section"> | |
| <div class="bet-input"> | |
| <label for="betAmount">投注金额:</label> | |
| <input type="number" id="betAmount" min="1" max="1000" value="10"> | |
| <button id="clearBet" class="btn-secondary">清空</button> | |
| </div> | |
| <div class="number-selection"> | |
| <label>选择号码 (0-36):</label> | |
| <div class="number-grid" id="numberGrid"> | |
| <!-- 数字按钮将通过JavaScript生成 --> | |
| </div> | |
| </div> | |
| <div class="current-bet"> | |
| <span>当前投注:</span> | |
| <span id="currentBetDisplay">无</span> | |
| </div> | |
| <div class="action-buttons"> | |
| <button id="spinButton" class="btn-primary">开始旋转</button> | |
| <button id="resetButton" class="btn-secondary">重置游戏</button> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="game-stats"> | |
| <div class="stat-item"> | |
| <span>总游戏次数:</span> | |
| <span id="totalGames">0</span> | |
| </div> | |
| <div class="stat-item"> | |
| <span>获胜次数:</span> | |
| <span id="winGames">0</span> | |
| </div> | |
| <div class="stat-item"> | |
| <span>胜率:</span> | |
| <span id="winRate">0%</span> | |
| </div> | |
| </div> | |
| </main> | |
| <footer class="footer"> | |
| <p>Built with <a href="https://huggingface.co/spaces/akhaliq/anycoder" target="_blank">anycoder</a></p> | |
| </footer> | |
| </div> | |
| <script src="assets/js/roulette.js"></script> | |
| </body> | |
| </html> | |
| === assets/css/styles.css === | |
| * { | |
| margin: 0; | |
| padding: 0; | |
| box-sizing: border-box; | |
| } | |
| body { | |
| font-family: 'Arial', sans-serif; | |
| background: linear-gradient(135deg, #1e3c72 0%, #2a5298 100%); | |
| min-height: 100vh; | |
| color: #fff; | |
| } | |
| .container { | |
| max-width: 1200px; | |
| margin: 0 auto; | |
| padding: 20px; | |
| } | |
| .header { | |
| text-align: center; | |
| margin-bottom: 30px; | |
| } | |
| .header h1 { | |
| font-size: 2.5rem; | |
| margin-bottom: 10px; | |
| text-shadow: 2px 2px 4px rgba(0,0,0,0.5); | |
| } | |
| .subtitle { | |
| font-size: 1.2rem; | |
| opacity: 0.9; | |
| } | |
| .game-area { | |
| display: grid; | |
| grid-template-columns: 1fr 1fr; | |
| gap: 40px; | |
| align-items: start; | |
| } | |
| .wheel-container { | |
| display: flex; | |
| justify-content: center; | |
| align-items: center; | |
| } | |
| .wheel-wrapper { | |
| position: relative; | |
| width: 400px; | |
| height: 400px; | |
| } | |
| .wheel { | |
| width: 100%; | |
| height: 100%; | |
| border-radius: 50%; | |
| border: 8px solid #8B4513; | |
| position: relative; | |
| overflow: hidden; | |
| transition: transform 4s cubic-bezier(0.23, 1, 0.32, 1); | |
| background: conic-gradient( | |
| #ff0000 0deg 19.35deg, | |
| #000 19.35deg 38.7deg, | |
| #ff0000 38.7deg 58.05deg, | |
| #000 58.05deg 77.4deg, | |
| #ff0000 77.4deg 96.75deg, | |
| #000 96.75deg 116.1deg, | |
| #ff0000 116.1deg 135.45deg, | |
| #000 135.45deg 154.8deg, | |
| #ff0000 154.8deg 174.15deg, | |
| #000 174.15deg 193.5deg, | |
| #ff0000 193.5deg 212.85deg, | |
| #000 212.85deg 232.2deg, | |
| #ff0000 232.2deg 251.55deg, | |
| #000 251.55deg 270.9deg, | |
| #ff0000 270.9deg 290.25deg, | |
| #000 290.25deg 309.6deg, | |
| #ff0000 309.6deg 328.95deg, | |
| #000 328.95deg 348.3deg, | |
| #ff0000 348.3deg 367.65deg, | |
| #008000 367.65deg 378.95deg, | |
| #008000 378.95deg 390.25deg | |
| ); | |
| box-shadow: | |
| 0 0 20px rgba(0,0,0,0.5), | |
| inset 0 0 20px rgba(255,255,255,0.1); | |
| } | |
| .wheel-number { | |
| position: absolute; | |
| width: 40px; | |
| height: 40px; | |
| border-radius: 50%; | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| font-weight: bold; | |
| font-size: 14px; | |
| color: white; | |
| text-shadow: 1px 1px 2px rgba(0,0,0,0.8); | |
| transform-origin: 50% 200px; | |
| } | |
| .number-red { background-color: #c41e3a; } | |
| .number-black { background-color: #000; } | |
| .number-green { background-color: #228b22; } | |
| .ball { | |
| position: absolute; | |
| width: 20px; | |
| height: 20px; | |
| border-radius: 50%; | |
| background: radial-gradient(circle at 30% 30%, #fff, #ccc); | |
| top: 50%; | |
| left: 50%; | |
| transform: translate(-50%, -50%); | |
| z-index: 10; | |
| box-shadow: 0 2px 10px rgba(0,0,0,0.5); | |
| transition: all 0.1s ease; | |
| } | |
| .ball.spinning { | |
| animation: ballSpin 4s cubic-bezier(0.23, 1, 0.32, 1) forwards; | |
| } | |
| @keyframes ballSpin { | |
| 0% { | |
| transform: translate(-50%, -50%) rotate(0deg); | |
| } | |
| 100% { | |
| transform: translate(-50%, -50%) rotate(1440deg); | |
| } | |
| } | |
| .wheel-pointer { | |
| position: absolute; | |
| top: -20px; | |
| left: 50%; | |
| transform: translateX(-50%); | |
| font-size: 30px; | |
| color: #fff; | |
| text-shadow: 2px 2px 4px rgba(0,0,0,0.8); | |
| z-index: 15; | |
| } | |
| .game-controls { | |
| background: rgba(255,255,255,0.1); | |
| border-radius: 15px; | |
| padding: 30px; | |
| backdrop-filter: blur(10px); | |
| } | |
| .balance-info { | |
| margin-bottom: 30px; | |
| } | |
| .balance { | |
| font-size: 1.5rem; | |
| font-weight: bold; | |
| margin-bottom: 15px; | |
| color: #ffd700; | |
| } | |
| .last-result { | |
| background: rgba(0,0,0,0.3); | |
| padding: 10px; | |
| border-radius: 8px; | |
| text-align: center; | |
| font-size: 1.1rem; | |
| } | |
| .betting-section { | |
| margin-bottom: 30px; | |
| } | |
| .bet-input { | |
| display: flex; | |
| align-items: center; | |
| gap: 10px; | |
| margin-bottom: 20px; | |
| } | |
| .bet-input label { | |
| font-weight: bold; | |
| min-width: 80px; | |
| } | |
| .bet-input input { | |
| flex: 1; | |
| padding: 8px; | |
| border: none; | |
| border-radius: 5px; | |
| font-size: 1rem; | |
| } | |
| .number-selection label { | |
| display: block; | |
| font-weight: bold; | |
| margin-bottom: 15px; | |
| } | |
| .number-grid { | |
| display: grid; | |
| grid-template-columns: repeat(6, 1fr); | |
| gap: 8px; | |
| margin-bottom: 20px; | |
| } | |
| .number-btn { | |
| padding: 10px 5px; | |
| border: none; | |
| border-radius: 5px; | |
| font-weight: bold; | |
| cursor: pointer; | |
| transition: all 0.3s ease; | |
| text-align: center; | |
| } | |
| .number-btn.red { | |
| background-color: #c41e3a; | |
| color: white; | |
| } | |
| .number-btn.black { | |
| background-color: #333; | |
| color: white; | |
| } | |
| .number-btn.green { | |
| background-color: #228b22; | |
| color: white; | |
| } | |
| .number-btn:hover { | |
| transform: scale(1.1); | |
| } | |
| .number-btn.selected { | |
| transform: scale(1.2); | |
| box-shadow: 0 0 15px rgba(255,255,255,0.5); | |
| } | |
| .current-bet { | |
| font-weight: bold; | |
| margin-bottom: 20px; | |
| color: #ffd700; | |
| } | |
| .action-buttons { | |
| display: flex; | |
| gap: 15px; | |
| } | |
| .btn-primary, .btn-secondary { | |
| flex: 1; | |
| padding: 12px 20px; | |
| border: none; | |
| border-radius: 8px; | |
| font-size: 1rem; | |
| font-weight: bold; | |
| cursor: pointer; | |
| transition: all 0.3s ease; | |
| } | |
| .btn-primary { | |
| background: linear-gradient(45deg, #ff6b6b, #ff8e8e); | |
| color: white; | |
| } | |
| .btn-primary:hover:not(:disabled) { | |
| background: linear-gradient(45deg, #ff5252, #ff7979); | |
| transform: translateY(-2px); | |
| } | |
| .btn-primary:disabled { | |
| background: #666; | |
| cursor: not-allowed; | |
| transform: none; | |
| } | |
| .btn-secondary { | |
| background: linear-gradient(45deg, #667eea, #764ba2); | |
| color: white; | |
| } | |
| .btn-secondary:hover { | |
| background: linear-gradient(45deg, #5a67d8, #6b46c1); | |
| transform: translateY(-2px); | |
| } | |
| .game-stats { | |
| display: flex; | |
| justify-content: space-around; | |
| background: rgba(255,255,255,0.1); | |
| padding: 20px; | |
| border-radius: 15px; | |
| backdrop-filter: blur(10px); | |
| } | |
| .stat-item { | |
| text-align: center; | |
| } | |
| .stat-item span:first-child { | |
| display: block; | |
| font-size: 0.9rem; | |
| opacity: 0.8; | |
| margin-bottom: 5px; | |
| } | |
| .stat-item span:last-child { | |
| font-size: 1.2rem; | |
| font-weight: bold; | |
| color: #ffd700; | |
| } | |
| .footer { | |
| text-align: center; | |
| margin-top: 40px; | |
| padding-top: 20px; | |
| border-top: 1px solid rgba(255,255,255,0.2); | |
| } | |
| .footer a { | |
| color: #ffd700; | |
| text-decoration: none; | |
| } | |
| .footer a:hover { | |
| text-decoration: underline; | |
| } | |
| /* 响应式设计 */ | |
| @media (max-width: 768px) { | |
| .game-area { | |
| grid-template-columns: 1fr; | |
| gap: 30px; | |
| } | |
| .wheel-wrapper { | |
| width: 300px; | |
| height: 300px; | |
| } | |
| .header h1 { | |
| font-size: 2rem; | |
| } | |
| .number-grid { | |
| grid-template-columns: repeat(5, 1fr); | |
| } | |
| .action-buttons { | |
| flex-direction: column; | |
| } | |
| } | |
| @media (max-width: 480px) { | |
| .container { | |
| padding: 15px; | |
| } | |
| .wheel-wrapper { | |
| width: 250px; | |
| height: 250px; | |
| } | |
| .number-grid { | |
| grid-template-columns: repeat(4, 1fr); | |
| } | |
| .game-stats { | |
| flex-direction: column; | |
| gap: 15px; | |
| } | |
| } | |
| === assets/js/roulette.js === | |
| class RouletteGame { | |
| constructor() { | |
| this.balance = 1000; | |
| this.currentBet = null; | |
| this.betAmount = 10; | |
| this.totalGames = 0; | |
| this.winGames = 0; | |
| this.isSpinning = false; | |
| this.wheelNumbers = [ | |
| 0, 32, 15, 19, 4, 21, 2, 25, 17, 34, 6, 27, 13, 36, 11, 30, 8, 23, | |
| 10, 5, 24, 16, 33, 1, 20, 14, 31, 9, 22, 18, 29, 7, 28, 12, 35, 3, 26 | |
| ]; | |
| this.redNumbers = [1, 3, 5, 7, 9, 12, 14, 16, 18, 19, 21, 23, 25, 27, 30, 32, 34, 36]; | |
| this.blackNumbers = [2, 4, 6, 8, 10, 11, 13, 15, 17, 20, 22, 24, 26, 28, 29, 31, 33, 35]; | |
| this.init(); | |
| } | |
| init() { | |
| this.createWheelNumbers(); | |
| this.createNumberGrid(); | |
| this.bindEvents(); | |
| this.updateDisplay(); | |
| } | |
| createWheelNumbers() { | |
| const wheel = document.getElementById('wheel'); | |
| const angleStep = 360 / 37; | |
| this.wheelNumbers.forEach((number, index) => { | |
| const numberElement = document.createElement('div'); | |
| numberElement.className = 'wheel-number'; | |
| numberElement.textContent = number; | |
| // 确定颜色 | |
| if (number === 0) { | |
| numberElement.classList.add('number-green'); | |
| } else if (this.redNumbers.includes(number)) { | |
| numberElement.classList.add('number-red'); | |
| } else { | |
| numberElement.classList.add('number-black'); | |
| } | |
| // 设置位置 | |
| const angle = index * angleStep; | |
| numberElement.style.transform = `rotate(${angle}deg) translateY(-180px)`; | |
| wheel.appendChild(numberElement); | |
| }); | |
| } | |
| createNumberGrid() { | |
| const grid = document.getElementById('numberGrid'); | |
| for (let i = 0; i <= 36; i++) { | |
| const button = document.createElement('button'); | |
| button.className = 'number-btn'; | |
| button.textContent = i; | |
| button.dataset.number = i; | |
| if (i === 0) { | |
| button.classList.add('green'); | |
| } else if (this.redNumbers.includes(i)) { | |
| button.classList.add('red'); | |
| } else { | |
| button.classList.add('black'); | |
| } | |
| button.addEventListener('click', () => this.selectNumber(i, button)); | |
| grid.appendChild(button); | |
| } | |
| } | |
| selectNumber(number, button) { | |
| // 清除之前的选择 | |
| document.querySelectorAll('.number-btn').forEach(btn => { | |
| btn.classList.remove('selected'); | |
| }); | |
| // 选择新号码 | |
| button.classList.add('selected'); | |
| this.currentBet = number; | |
| this.updateDisplay(); | |
| } | |
| bindEvents() { | |
| document.getElementById('spinButton').addEventListener('click', () => this.spin()); | |
| document.getElementById('resetButton').addEventListener('click', () => this.reset()); | |
| document.getElementById('clearBet').addEventListener('click', () => this.clearBet()); | |
| const betAmountInput = document.getElementById('betAmount'); | |
| betAmountInput.addEventListener('change', (e) => { | |
| this.betAmount = Math.max(1, Math.min(1000, parseInt(e.target.value) || 10)); | |
| e.target.value = this.betAmount; | |
| }); | |
| } | |
| async spin() { | |
| if (this.isSpinning || this.currentBet === null) { | |
| this.showMessage('请先选择一个号码!'); | |
| return; | |
| } | |
| if (this.betAmount > this.balance) { | |
| this.showMessage('余额不足!'); | |
| return; | |
| } | |
| this.isSpinning = true; | |
| this.balance -= this.betAmount; | |
| this.updateDisplay(); | |
| // 重置轮盘和球的动画 | |
| const wheel = document.getElementById('wheel'); | |
| const ball = document.getElementById('ball'); | |
| const spinButton = document.getElementById('spinButton'); | |
| wheel.style.transition = 'none'; | |
| ball.classList.remove('spinning'); | |
| // 强制重绘 | |
| wheel.offsetHeight; | |
| // 随机结果 | |
| const winningNumber = Math.floor(Math.random() * 37); | |
| const targetAngle = this.getTargetAngle(winningNumber); | |
| // 设置最终旋转角度 | |
| wheel.style.transition = 'transform 4s cubic-bezier(0.23, 1, 0.32, 1)'; | |
| wheel.style.transform = `rotate(${targetAngle}deg)`; | |
| // 开始球的旋转动画 | |
| setTimeout(() => { | |
| ball.classList.add('spinning'); | |
| }, 100); | |
| // 等待动画完成 | |
| await new Promise(resolve => setTimeout(resolve, 4000)); | |
| // 检查结果 | |
| this.checkResult(winningNumber); | |
| this.totalGames++; | |
| if (this.currentBet === winningNumber) { | |
| this.winGames++; | |
| const winnings = this.betAmount * 35; // 35倍赔率 | |
| this.balance += winnings; | |
| this.showMessage(`🎉 恭喜!您赢了 ¥${winnings}!`); | |
| } else { | |
| this.showMessage(`💔 很遗憾,号码 ${winningNumber} 获胜。您输了 ¥${this.betAmount}。`); | |
| } | |
| this.updateDisplay(); | |
| this.isSpinning = false; | |
| spinButton.disabled = false; | |
| // 重置选择 | |
| this.clearBet(); | |
| } | |
| getTargetAngle(winningNumber) { | |
| const index = this.wheelNumbers.indexOf(winningNumber); | |
| const angleStep = 360 / 37; | |
| const baseAngle = index * angleStep; | |
| // 轮盘逆时针旋转,我们需要让获胜号码转到指针位置 | |
| // 指针在12点钟位置,所以轮盘需要旋转到获胜号码在顶部 | |
| return 360 - baseAngle + (Math.random() * angleStep - angleStep/2); | |
| } | |
| checkResult(winningNumber) { | |
| // 这里可以添加更复杂的游戏逻辑 | |
| // 比如红黑、大小、奇偶等投注 | |
| } | |
| clearBet() { | |
| this.currentBet = null; | |
| document.querySelectorAll('.number-btn').forEach(btn => { | |
| btn.classList.remove('selected'); | |
| }); | |
| this.updateDisplay(); | |
| } | |
| reset() { | |
| if (this.isSpinning) return; | |
| this.balance = 1000; | |
| this.totalGames = 0; | |
| this.winGames = 0; | |
| this.clearBet(); | |
| this.showMessage('游戏已重置!'); | |
| this.updateDisplay(); | |
| } | |
| updateDisplay() { | |
| document.getElementById('balance').textContent = this.balance; | |
| document.getElementById('currentBetDisplay').textContent = | |
| this.currentBet !== null ? `${this.currentBet}号 (¥${this.betAmount})` : '无'; | |
| document.getElementById('totalGames').textContent = this.totalGames; | |
| document.getElementById('winGames').textContent = this.winGames; | |
| const winRate = this.totalGames > 0 ? ((this.winGames / this.totalGames) * 100).toFixed(1) : '0.0'; | |
| document.getElementById('winRate').textContent = `${winRate}%`; | |
| const spinButton = document.getElementById('spinButton'); | |
| spinButton.disabled = this.isSpinning || this.currentBet === null || this.betAmount > this.balance; | |
| spinButton.textContent = this.isSpinning ? '旋转中...' : '开始旋转'; | |
| } | |
| showMessage(message) { | |
| const lastResult = document.getElementById('lastResult'); | |
| lastResult.textContent = message; | |
| } | |
| } | |
| // 游戏初始化 | |
| document.addEventListener('DOMContentLoaded', () => { | |
| new RouletteGame(); | |
| }); | |
| // 添加一些额外的功能 | |
| document.addEventListener('keydown', (e) => { | |
| if (e.code === 'Space') { | |
| e.preventDefault(); | |
| const spinButton = document.getElementById('spinButton'); | |
| if (!spinButton.disabled) { | |
| spinButton.click(); | |
| } | |
| } | |
| }); | |
| // 添加音效(如果需要的话) | |
| function playSound(type) { | |
| // 这里可以添加音效 | |
| // const audio = new Audio(`assets/sounds/${type}.mp3`); | |
| // audio.play().catch(() => {}); // 忽略播放错误 | |
| } |