slot-machine / index.html
namelessai's picture
Update index.html
d6c367d verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Lucky Spin Slot Machine</title>
<script src="https://cdn.tailwindcss.com"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<style>
@keyframes spin {
0% { transform: translateY(0); }
100% { transform: translateY(-1000px); }
}
@keyframes bounce {
0%, 100% { transform: translateY(0); }
50% { transform: translateY(-20px); }
}
@keyframes winPulse {
0% { transform: scale(1); }
50% { transform: scale(1.1); }
100% { transform: scale(1); }
}
.slot-reel {
height: 100px;
overflow: hidden;
position: relative;
}
.slot-item {
height: 100px;
display: flex;
align-items: center;
justify-content: center;
font-size: 3rem;
}
.spinning {
animation: spin 0.1s linear infinite;
}
.win-animation {
animation: winPulse 0.5s ease infinite;
}
.jackpot {
animation: bounce 0.5s ease infinite, winPulse 0.5s ease infinite;
}
.machine-body {
background: linear-gradient(145deg, #d10000, #8a0000);
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.5);
}
.lever {
transition: all 0.3s ease;
}
.lever.pulled {
transform: rotate(-30deg);
}
.coin {
transition: all 0.3s ease;
}
.coin.inserted {
transform: translateY(50px) scale(0);
}
.auto-spin-active {
background-color: #10b981 !important;
box-shadow: 0 0 10px #10b981;
}
</style>
</head>
<body class="bg-gray-900 min-h-screen flex items-center justify-center p-4">
<div class="relative">
<!-- Slot Machine -->
<div class="machine-body rounded-2xl p-8 relative overflow-hidden">
<!-- Decorative elements -->
<div class="absolute top-0 left-0 w-full h-4 bg-yellow-400"></div>
<div class="absolute bottom-0 left-0 w-full h-4 bg-yellow-400"></div>
<div class="absolute top-4 left-4 right-4 bottom-4 border-4 border-yellow-400 rounded-xl opacity-20"></div>
<!-- Machine header -->
<div class="text-center mb-6">
<h1 class="text-yellow-400 text-4xl font-bold mb-2">LUCKY SPIN</h1>
<div class="bg-black bg-opacity-50 rounded-full py-2 px-6 inline-block">
<span class="text-white font-mono text-xl">SLOT MACHINE</span>
</div>
</div>
<!-- Reels container -->
<div class="flex justify-center items-center mb-8">
<!-- Lever -->
<div class="h-48 w-16 bg-gray-700 rounded-lg mr-4 flex flex-col items-center justify-end relative">
<div class="w-16 h-8 bg-gray-800 rounded-t-lg"></div>
<div id="lever" class="lever w-12 h-32 bg-red-700 rounded-t-lg absolute top-0 cursor-pointer z-10"></div>
</div>
<!-- Reels -->
<div class="flex bg-black bg-opacity-70 rounded-xl p-4">
<div class="slot-reel w-24 bg-white rounded-lg mx-2 relative overflow-hidden" id="reel1">
<div class="slot-items" id="items1">
<div class="slot-item text-red-500">πŸ’</div>
<div class="slot-item text-blue-500">πŸ‹</div>
<div class="slot-item text-purple-500">πŸ‡</div>
<div class="slot-item text-yellow-500">🍊</div>
<div class="slot-item text-green-500">🍏</div>
<div class="slot-item text-red-500">πŸ“</div>
<div class="slot-item text-blue-500">πŸ””</div>
<div class="slot-item text-yellow-500">πŸ’°</div>
<div class="slot-item text-red-500">πŸ’</div>
<div class="slot-item text-blue-500">πŸ‹</div>
</div>
</div>
<div class="slot-reel w-24 bg-white rounded-lg mx-2 relative overflow-hidden" id="reel2">
<div class="slot-items" id="items2">
<div class="slot-item text-blue-500">πŸ‹</div>
<div class="slot-item text-purple-500">πŸ‡</div>
<div class="slot-item text-yellow-500">🍊</div>
<div class="slot-item text-green-500">🍏</div>
<div class="slot-item text-red-500">πŸ“</div>
<div class="slot-item text-blue-500">πŸ””</div>
<div class="slot-item text-yellow-500">πŸ’°</div>
<div class="slot-item text-red-500">πŸ’</div>
<div class="slot-item text-blue-500">πŸ‹</div>
<div class="slot-item text-purple-500">πŸ‡</div>
</div>
</div>
<div class="slot-reel w-24 bg-white rounded-lg mx-2 relative overflow-hidden" id="reel3">
<div class="slot-items" id="items3">
<div class="slot-item text-purple-500">πŸ‡</div>
<div class="slot-item text-yellow-500">🍊</div>
<div class="slot-item text-green-500">🍏</div>
<div class="slot-item text-red-500">πŸ“</div>
<div class="slot-item text-blue-500">πŸ””</div>
<div class="slot-item text-yellow-500">πŸ’°</div>
<div class="slot-item text-red-500">πŸ’</div>
<div class="slot-item text-blue-500">πŸ‹</div>
<div class="slot-item text-purple-500">πŸ‡</div>
<div class="slot-item text-yellow-500">🍊</div>
</div>
</div>
</div>
</div>
<!-- Coin slot and controls -->
<div class="flex justify-between items-center">
<div class="relative">
<div class="w-24 h-12 bg-gray-700 rounded-lg flex items-center justify-center">
<div class="w-16 h-2 bg-gray-800 rounded-full"></div>
</div>
<div id="coin" class="coin absolute top-0 left-1/2 transform -translate-x-1/2 w-8 h-8 bg-yellow-400 rounded-full shadow-lg">
<div class="absolute inset-0 rounded-full bg-yellow-300 opacity-50"></div>
</div>
</div>
<div class="text-center">
<div class="bg-black bg-opacity-70 rounded-lg p-3 inline-block">
<div class="text-white mb-2">CREDIT: <span id="credit" class="text-yellow-400 font-bold">100</span></div>
<div class="text-white">WIN: <span id="win" class="text-green-400 font-bold">0</span></div>
</div>
</div>
<div class="flex space-x-2">
<button id="auto-spin-btn" class="bg-gray-700 hover:bg-gray-600 text-white font-bold py-3 px-4 rounded-lg shadow-lg transition-all transform hover:scale-105 disabled:opacity-50 disabled:cursor-not-allowed">
<i class="fas fa-sync-alt mr-2"></i>AUTO
</button>
<button id="spin-btn" class="bg-yellow-500 hover:bg-yellow-600 text-black font-bold py-3 px-6 rounded-lg shadow-lg transition-all transform hover:scale-105 disabled:opacity-50 disabled:cursor-not-allowed">
SPIN
</button>
</div>
</div>
<!-- Auto-spin options -->
<div id="auto-spin-options" class="hidden mt-4 bg-black bg-opacity-50 rounded-lg p-3">
<div class="flex justify-between items-center mb-2">
<span class="text-white">Auto-spin count:</span>
<select id="auto-spin-count" class="bg-gray-700 text-white rounded px-2 py-1">
<option value="10">10</option>
<option value="25">25</option>
<option value="50">50</option>
<option value="100">100</option>
<option value="0">Until stop</option>
</select>
</div>
<div class="flex justify-between items-center">
<span class="text-white">Stop if credit below:</span>
<select id="auto-spin-limit" class="bg-gray-700 text-white rounded px-2 py-1">
<option value="10">10</option>
<option value="25">25</option>
<option value="50">50</option>
<option value="100">100</option>
<option value="0">Never stop</option>
</select>
</div>
<div class="flex justify-center mt-3 space-x-2">
<button id="start-auto-spin" class="bg-green-500 hover:bg-green-600 text-white font-bold py-2 px-4 rounded">
Start
</button>
<button id="stop-auto-spin" class="bg-red-500 hover:bg-red-600 text-white font-bold py-2 px-4 rounded">
Stop
</button>
</div>
</div>
</div>
<!-- Paytable -->
<div class="mt-8 bg-gray-800 bg-opacity-70 rounded-xl p-6 text-white max-w-md mx-auto">
<h2 class="text-2xl font-bold text-yellow-400 mb-4 text-center">PAYTABLE</h2>
<div class="grid grid-cols-2 gap-4">
<div class="flex items-center">
<span class="text-3xl mr-2">πŸ’πŸ’πŸ’</span>
<span class="font-bold">x50</span>
</div>
<div class="flex items-center">
<span class="text-3xl mr-2">πŸ’°πŸ’°πŸ’°</span>
<span class="font-bold">x100</span>
</div>
<div class="flex items-center">
<span class="text-3xl mr-2">πŸ‡πŸ‡πŸ‡</span>
<span class="font-bold">x20</span>
</div>
<div class="flex items-center">
<span class="text-3xl mr-2">πŸ””πŸ””πŸ””</span>
<span class="font-bold">x30</span>
</div>
<div class="flex items-center">
<span class="text-3xl mr-2">🍊🍊🍊</span>
<span class="font-bold">x15</span>
</div>
<div class="flex items-center">
<span class="text-3xl mr-2">🍏🍏🍏</span>
<span class="font-bold">x10</span>
</div>
</div>
</div>
<!-- Win message -->
<div id="win-message" class="fixed inset-0 flex items-center justify-center bg-black bg-opacity-70 z-50 hidden">
<div class="bg-gradient-to-br from-yellow-400 to-yellow-600 p-8 rounded-xl text-center max-w-md">
<h2 class="text-4xl font-bold mb-4">YOU WIN!</h2>
<p id="win-amount" class="text-5xl font-bold mb-6">0</p>
<button id="close-win" class="bg-black text-white px-6 py-3 rounded-lg font-bold hover:bg-gray-800 transition">COLLECT</button>
</div>
</div>
<!-- Auto-spin status -->
<div id="auto-spin-status" class="fixed bottom-4 left-1/2 transform -translate-x-1/2 bg-black bg-opacity-70 text-white px-4 py-2 rounded-lg hidden">
<span id="auto-spin-countdown">Auto-spin: 10 remaining</span>
</div>
</div>
<!-- Audio elements -->
<audio id="spinSound" src="https://assets.mixkit.co/sfx/preview/mixkit-slot-machine-spin-1930.mp3" preload="auto"></audio>
<audio id="winSound" src="https://assets.mixkit.co/sfx/preview/mixkit-winning-chimes-2015.mp3" preload="auto"></audio>
<audio id="coinSound" src="https://assets.mixkit.co/sfx/preview/mixkit-coin-win-notification-919.mp3" preload="auto"></audio>
<audio id="leverSound" src="https://assets.mixkit.co/sfx/preview/mixkit-retro-arcade-game-lever-1083.mp3" preload="auto"></audio>
<audio id="jackpotSound" src="https://assets.mixkit.co/sfx/preview/mixkit-emergency-alert-alarm-1007.mp3" preload="auto"></audio>
<script>
document.addEventListener('DOMContentLoaded', function() {
// Game state
let credit = 100;
let winAmount = 0;
let isSpinning = false;
let isAutoSpinning = false;
let autoSpinCount = 0;
let autoSpinLimit = 0;
let remainingAutoSpins = 0;
// DOM elements
const spinBtn = document.getElementById('spin-btn');
const autoSpinBtn = document.getElementById('auto-spin-btn');
const autoSpinOptions = document.getElementById('auto-spin-options');
const startAutoSpinBtn = document.getElementById('start-auto-spin');
const stopAutoSpinBtn = document.getElementById('stop-auto-spin');
const autoSpinCountSelect = document.getElementById('auto-spin-count');
const autoSpinLimitSelect = document.getElementById('auto-spin-limit');
const autoSpinStatus = document.getElementById('auto-spin-status');
const autoSpinCountdown = document.getElementById('auto-spin-countdown');
const lever = document.getElementById('lever');
const coin = document.getElementById('coin');
const creditDisplay = document.getElementById('credit');
const winDisplay = document.getElementById('win');
const winMessage = document.getElementById('win-message');
const winAmountDisplay = document.getElementById('win-amount');
const closeWinBtn = document.getElementById('close-win');
const reels = [document.getElementById('reel1'), document.getElementById('reel2'), document.getElementById('reel3')];
const items = [document.getElementById('items1'), document.getElementById('items2'), document.getElementById('items3')];
// Audio elements
const spinSound = document.getElementById('spinSound');
const winSound = document.getElementById('winSound');
const coinSound = document.getElementById('coinSound');
const leverSound = document.getElementById('leverSound');
const jackpotSound = document.getElementById('jackpotSound');
// Paytable
const paytable = {
'πŸ’πŸ’πŸ’': 50,
'πŸ’°πŸ’°πŸ’°': 100,
'πŸ‡πŸ‡πŸ‡': 20,
'πŸ””πŸ””πŸ””': 30,
'🍊🍊🍊': 15,
'🍏🍏🍏': 10
};
// Initialize the game
function init() {
// Set initial positions
items.forEach(item => {
item.style.transform = 'translateY(0)';
});
updateDisplay();
// Event listeners for auto-spin
autoSpinBtn.addEventListener('click', toggleAutoSpinOptions);
startAutoSpinBtn.addEventListener('click', startAutoSpin);
stopAutoSpinBtn.addEventListener('click', stopAutoSpin);
}
// Update display
function updateDisplay() {
creditDisplay.textContent = credit;
winDisplay.textContent = winAmount;
// Disable spin button if no credit
spinBtn.disabled = credit <= 0 || isSpinning;
autoSpinBtn.disabled = credit <= 0 || isSpinning;
}
// Insert coin animation
function insertCoin() {
if (isSpinning) return;
coin.classList.add('inserted');
coinSound.currentTime = 0;
coinSound.play();
setTimeout(() => {
coin.classList.remove('inserted');
coin.style.display = 'block';
}, 300);
}
// Pull lever animation
function pullLever() {
lever.classList.add('pulled');
leverSound.currentTime = 0;
leverSound.play();
setTimeout(() => {
lever.classList.remove('pulled');
}, 300);
}
// Toggle auto-spin options
function toggleAutoSpinOptions() {
if (autoSpinOptions.classList.contains('hidden')) {
autoSpinOptions.classList.remove('hidden');
} else {
autoSpinOptions.classList.add('hidden');
}
}
// Start auto-spin
function startAutoSpin() {
autoSpinCount = parseInt(autoSpinCountSelect.value);
autoSpinLimit = parseInt(autoSpinLimitSelect.value);
if (autoSpinCount === 0) {
remainingAutoSpins = Infinity;
} else {
remainingAutoSpins = autoSpinCount;
}
isAutoSpinning = true;
autoSpinBtn.classList.add('auto-spin-active');
autoSpinOptions.classList.add('hidden');
autoSpinStatus.classList.remove('hidden');
updateAutoSpinStatus();
// Start the first spin
if (!isSpinning) {
spin();
}
}
// Stop auto-spin
function stopAutoSpin() {
isAutoSpinning = false;
autoSpinBtn.classList.remove('auto-spin-active');
autoSpinOptions.classList.add('hidden');
autoSpinStatus.classList.add('hidden');
}
// Update auto-spin status display
function updateAutoSpinStatus() {
if (isAutoSpinning) {
if (remainingAutoSpins === Infinity) {
autoSpinCountdown.textContent = "Auto-spin: Unlimited";
} else {
autoSpinCountdown.textContent = `Auto-spin: ${remainingAutoSpins} remaining`;
}
}
}
// Spin the reels
function spin() {
if (isSpinning || credit <= 0) return;
// Check auto-spin stop conditions
if (isAutoSpinning) {
if (autoSpinLimit > 0 && credit < autoSpinLimit) {
stopAutoSpin();
return;
}
if (remainingAutoSpins !== Infinity) {
remainingAutoSpins--;
updateAutoSpinStatus();
if (remainingAutoSpins <= 0) {
stopAutoSpin();
}
}
}
// Deduct credit
credit--;
updateDisplay();
// Play sounds
spinSound.currentTime = 0;
spinSound.play();
// Pull lever animation
pullLever();
insertCoin();
isSpinning = true;
winAmount = 0;
updateDisplay();
// Start spinning animation
reels.forEach(reel => {
reel.querySelector('.slot-items').classList.add('spinning');
});
// Stop reels at different times
setTimeout(() => stopReel(0), 1000 + Math.random() * 500);
setTimeout(() => stopReel(1), 1500 + Math.random() * 500);
setTimeout(() => stopReel(2), 2000 + Math.random() * 500);
}
// Stop a single reel
function stopReel(reelIndex) {
const reel = reels[reelIndex];
const itemsContainer = items[reelIndex];
// Remove spinning class
itemsContainer.classList.remove('spinning');
// Calculate random position
const itemHeight = 100; // height of each item
const itemCount = itemsContainer.children.length;
const randomPosition = Math.floor(Math.random() * itemCount) * -itemHeight;
// Set final position
itemsContainer.style.transform = `translateY(${randomPosition}px)`;
// If this is the last reel, check for win
if (reelIndex === 2) {
setTimeout(checkWin, 500);
}
}
// Check for winning combination
function checkWin() {
isSpinning = false;
// Get the symbols from each reel
const symbols = [];
for (let i = 0; i < 3; i++) {
const itemsContainer = items[i];
const position = parseInt(itemsContainer.style.transform.split('(')[1].split('px)')[0]);
const itemIndex = Math.abs(position / 100) % itemsContainer.children.length;
symbols.push(itemsContainer.children[itemIndex].textContent);
}
// Check for matches
const combination = symbols.join('');
if (paytable[combination]) {
winAmount = paytable[combination];
// Special handling for jackpot
if (combination === 'πŸ’°πŸ’°πŸ’°') {
jackpotWin();
} else {
regularWin();
}
} else {
updateDisplay();
// If auto-spinning and not showing win message, start next spin
if (isAutoSpinning && !winMessage.classList.contains('hidden') === false) {
setTimeout(() => {
if (credit > 0 && !isSpinning) {
spin();
}
}, 500);
}
}
}
// Regular win
function regularWin() {
credit += winAmount;
updateDisplay();
// Add win animation to reels
reels.forEach(reel => {
reel.classList.add('win-animation');
});
// Play win sound
winSound.currentTime = 0;
winSound.play();
// Show win message
winAmountDisplay.textContent = winAmount;
winMessage.classList.remove('hidden');
// Remove animation after delay
setTimeout(() => {
reels.forEach(reel => {
reel.classList.remove('win-animation');
});
// If auto-spinning, continue after win
if (isAutoSpinning) {
setTimeout(() => {
if (credit > 0 && !isSpinning) {
spin();
}
}, 1000);
}
}, 2000);
}
// Jackpot win
function jackpotWin() {
credit += winAmount;
updateDisplay();
// Add jackpot animation to reels
reels.forEach(reel => {
reel.classList.add('jackpot');
});
// Play jackpot sound
jackpotSound.currentTime = 0;
jackpotSound.play();
// Show win message
winAmountDisplay.textContent = winAmount;
winMessage.classList.remove('hidden');
// Remove animation after delay
setTimeout(() => {
reels.forEach(reel => {
reel.classList.remove('jackpot');
});
// If auto-spinning, continue after win
if (isAutoSpinning) {
setTimeout(() => {
if (credit > 0 && !isSpinning) {
spin();
}
}, 1000);
}
}, 3000);
}
// Event listeners
spinBtn.addEventListener('click', spin);
lever.addEventListener('mousedown', function() {
if (!isSpinning && credit > 0) {
pullLever();
spin();
}
});
coin.addEventListener('click', insertCoin);
closeWinBtn.addEventListener('click', function() {
winMessage.classList.add('hidden');
updateDisplay();
// If auto-spinning, continue after closing win message
if (isAutoSpinning && credit > 0 && !isSpinning) {
setTimeout(spin, 500);
}
});
// Keyboard support
document.addEventListener('keydown', function(e) {
if (e.code === 'Space' && !isSpinning && credit > 0) {
spin();
}
});
// Initialize the game
init();
});
</script>
</body>
</html>