diff --git a/README_ASSETS.md b/README_ASSETS.md new file mode 100644 index 0000000..aec9ac3 --- /dev/null +++ b/README_ASSETS.md @@ -0,0 +1,44 @@ +# Asset Files Needed + +This Christmas Santa Clicker game template requires the following asset files to be added: + +## Required Files: + +### 1. Santa Image (`santa.png`) +- **Purpose**: The clickable Santa Claus image in the center of the game +- **Recommended Size**: 400x400 pixels +- **Format**: PNG with transparent background preferred +- **Note**: Currently displays a 🎅 emoji as fallback if image is not found + +### 2. Christmas Music (`christmas-music.mp3` or `christmas-music.ogg`) +- **Purpose**: Background music that plays on repeat +- **Format**: MP3 or OGG format (both formats supported for browser compatibility) +- **Note**: The audio will attempt to autoplay, but some browsers may require user interaction first + +## How to Add Assets: + +1. Add your `santa.png` file to the root directory of the website +2. Add your `christmas-music.mp3` (or `.ogg`) file to the root directory +3. The game will automatically use these files once they are present + +## Current Status: + +- ✅ HTML structure complete with Slovak language UI +- ✅ CSS styling with Christmas theme (red, green, gold colors) +- ✅ Animated snowflakes and gradient background +- ✅ Responsive design for mobile devices +- ✅ Upgrade system with 5 different upgrades +- ✅ Click animation effects +- ✅ Auto-production system (points per second) +- ✅ Audio element configured to loop +- ⏳ Santa image (currently using emoji fallback) +- ⏳ Christmas music file + +## Features Included: + +- **Slovak Language UI**: All text is in Slovak (Body, Kúpiť, etc.) +- **Festive Design**: Christmas colors, snowfall animation, glowing effects +- **Upgrade System**: 5 upgrades with increasing costs and production values +- **Click Effects**: Visual feedback when clicking Santa +- **Responsive Layout**: Works on desktop, tablet, and mobile devices +- **Auto-save Ready**: Game state structure ready for localStorage implementation diff --git a/general.css b/general.css new file mode 100644 index 0000000..5ffb6ac --- /dev/null +++ b/general.css @@ -0,0 +1,437 @@ +/* Reset and Base Styles */ +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +body { + font-family: 'Arial', 'Segoe UI', sans-serif; + background: linear-gradient(135deg, #1a472a 0%, #2d5a3d 25%, #0f2b1a 50%, #1a472a 75%, #2d5a3d 100%); + background-size: 400% 400%; + animation: gradientShift 15s ease infinite; + min-height: 100vh; + color: #fff; + overflow-x: hidden; +} + +@keyframes gradientShift { + 0% { background-position: 0% 50%; } + 50% { background-position: 100% 50%; } + 100% { background-position: 0% 50%; } +} + +/* Snow Animation */ +.snow-container { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + pointer-events: none; + z-index: 1; + overflow: hidden; +} + +.snowflake { + position: absolute; + top: -20px; + color: #fff; + font-size: 1.5em; + opacity: 0.8; + animation: fall linear infinite; + text-shadow: 0 0 5px rgba(255, 255, 255, 0.5); +} + +.snowflake:nth-child(1) { + left: 10%; + animation-duration: 10s; + animation-delay: 0s; +} + +.snowflake:nth-child(2) { + left: 30%; + animation-duration: 12s; + animation-delay: 2s; + font-size: 2em; +} + +.snowflake:nth-child(3) { + left: 50%; + animation-duration: 8s; + animation-delay: 4s; +} + +.snowflake:nth-child(4) { + left: 70%; + animation-duration: 14s; + animation-delay: 1s; + font-size: 1.8em; +} + +.snowflake:nth-child(5) { + left: 85%; + animation-duration: 11s; + animation-delay: 3s; +} + +.snowflake:nth-child(6) { + left: 20%; + animation-duration: 9s; + animation-delay: 5s; + font-size: 2.2em; +} + +@keyframes fall { + to { + transform: translateY(100vh) rotate(360deg); + } +} + +/* Container */ +.container { + position: relative; + z-index: 2; + max-width: 1400px; + margin: 0 auto; + padding: 20px; +} + +/* Header */ +header { + text-align: center; + background: linear-gradient(135deg, #c41e3a 0%, #8b0000 100%); + border-radius: 20px; + padding: 25px; + margin-bottom: 30px; + box-shadow: 0 8px 20px rgba(0, 0, 0, 0.4), 0 0 40px rgba(196, 30, 58, 0.3); + border: 3px solid #ffd700; +} + +header h1 { + font-size: 3em; + text-shadow: 3px 3px 6px rgba(0, 0, 0, 0.7); + margin-bottom: 15px; + animation: glow 2s ease-in-out infinite alternate; +} + +@keyframes glow { + from { + text-shadow: 3px 3px 6px rgba(0, 0, 0, 0.7), 0 0 10px rgba(255, 215, 0, 0.5); + } + to { + text-shadow: 3px 3px 6px rgba(0, 0, 0, 0.7), 0 0 20px rgba(255, 215, 0, 0.8); + } +} + +.score-display { + display: flex; + justify-content: center; + align-items: center; + gap: 10px; + font-size: 2em; + font-weight: bold; + margin: 10px 0; +} + +.score-value { + color: #ffd700; + text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.8); +} + +.per-second { + font-size: 1.2em; + color: #90ee90; + text-shadow: 1px 1px 3px rgba(0, 0, 0, 0.7); +} + +/* Main Layout */ +main { + display: grid; + grid-template-columns: 1fr 400px; + gap: 30px; + align-items: start; +} + +/* Game Area */ +.game-area { + background: linear-gradient(135deg, rgba(139, 0, 0, 0.3) 0%, rgba(196, 30, 58, 0.3) 100%); + border-radius: 20px; + padding: 40px; + box-shadow: 0 8px 20px rgba(0, 0, 0, 0.4); + border: 3px solid rgba(255, 215, 0, 0.5); +} + +.click-zone { + text-align: center; +} + +.santa-container { + position: relative; + display: inline-block; + margin: 20px 0; +} + +.santa-image { + width: 400px; + height: 400px; + cursor: pointer; + transition: transform 0.1s ease; + filter: drop-shadow(0 10px 20px rgba(0, 0, 0, 0.5)); + border-radius: 20px; + background: rgba(255, 255, 255, 0.1); + padding: 20px; +} + +.santa-image:hover { + transform: scale(1.05); + filter: drop-shadow(0 15px 30px rgba(255, 215, 0, 0.5)); +} + +.santa-image:active { + transform: scale(0.95); +} + +.santa-emoji { + width: 400px; + height: 400px; + cursor: pointer; + transition: transform 0.1s ease; + filter: drop-shadow(0 10px 20px rgba(0, 0, 0, 0.5)); + border-radius: 20px; + background: rgba(255, 255, 255, 0.1); + padding: 20px; + font-size: 300px; + display: flex; + align-items: center; + justify-content: center; + user-select: none; +} + +.santa-emoji:hover { + transform: scale(1.05); + filter: drop-shadow(0 15px 30px rgba(255, 215, 0, 0.5)); +} + +.santa-emoji:active { + transform: scale(0.95); +} + +.click-effect { + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + pointer-events: none; + font-size: 3em; + color: #ffd700; + font-weight: bold; + opacity: 0; + text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.8); +} + +.click-effect.show { + animation: floatUp 0.8s ease-out; +} + +@keyframes floatUp { + 0% { + opacity: 1; + transform: translate(-50%, -50%) translateY(0); + } + 100% { + opacity: 0; + transform: translate(-50%, -50%) translateY(-100px); + } +} + +.instruction { + font-size: 1.5em; + color: #ffd700; + text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.8); + margin-top: 20px; + animation: pulse 2s ease-in-out infinite; +} + +@keyframes pulse { + 0%, 100% { + transform: scale(1); + } + 50% { + transform: scale(1.05); + } +} + +/* Upgrades Panel */ +.upgrades-panel { + background: linear-gradient(135deg, rgba(0, 100, 0, 0.4) 0%, rgba(34, 139, 34, 0.4) 100%); + border-radius: 20px; + padding: 25px; + box-shadow: 0 8px 20px rgba(0, 0, 0, 0.4); + border: 3px solid rgba(255, 215, 0, 0.5); + max-height: 80vh; + overflow-y: auto; +} + +.upgrades-panel::-webkit-scrollbar { + width: 10px; +} + +.upgrades-panel::-webkit-scrollbar-track { + background: rgba(0, 0, 0, 0.2); + border-radius: 5px; +} + +.upgrades-panel::-webkit-scrollbar-thumb { + background: linear-gradient(135deg, #c41e3a, #8b0000); + border-radius: 5px; +} + +.upgrades-panel h2 { + text-align: center; + font-size: 2em; + margin-bottom: 20px; + text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.8); + color: #ffd700; +} + +/* Upgrade Item */ +.upgrade-item { + background: linear-gradient(135deg, rgba(255, 255, 255, 0.1) 0%, rgba(255, 255, 255, 0.05) 100%); + border-radius: 15px; + padding: 15px; + margin-bottom: 15px; + border: 2px solid rgba(255, 215, 0, 0.3); + transition: all 0.3s ease; +} + +.upgrade-item:hover { + transform: translateY(-3px); + box-shadow: 0 5px 15px rgba(255, 215, 0, 0.3); + border-color: rgba(255, 215, 0, 0.6); +} + +.upgrade-header { + display: flex; + align-items: center; + gap: 10px; + margin-bottom: 10px; +} + +.upgrade-icon { + font-size: 2em; +} + +.upgrade-name { + font-size: 1.3em; + font-weight: bold; + color: #ffd700; + text-shadow: 1px 1px 3px rgba(0, 0, 0, 0.8); +} + +.upgrade-info { + margin-bottom: 10px; +} + +.upgrade-description { + color: #90ee90; + font-size: 0.95em; + margin-bottom: 8px; +} + +.upgrade-stats { + display: flex; + justify-content: space-between; + font-size: 0.9em; + color: #ddd; +} + +.upgrade-cost { + color: #ffeb3b; +} + +.upgrade-owned { + color: #90ee90; +} + +/* Upgrade Button */ +.upgrade-button { + width: 100%; + padding: 12px; + font-size: 1.1em; + font-weight: bold; + background: linear-gradient(135deg, #c41e3a 0%, #8b0000 100%); + color: #fff; + border: 2px solid #ffd700; + border-radius: 10px; + cursor: pointer; + transition: all 0.3s ease; + text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.5); + box-shadow: 0 4px 6px rgba(0, 0, 0, 0.3); +} + +.upgrade-button:hover { + background: linear-gradient(135deg, #d41e3a 0%, #9b0000 100%); + transform: scale(1.05); + box-shadow: 0 6px 12px rgba(255, 215, 0, 0.4); +} + +.upgrade-button:active { + transform: scale(0.98); +} + +.upgrade-button:disabled { + background: linear-gradient(135deg, #555 0%, #333 100%); + cursor: not-allowed; + opacity: 0.6; + border-color: #888; +} + +/* Responsive Design */ +@media (max-width: 1024px) { + main { + grid-template-columns: 1fr; + } + + .upgrades-panel { + max-height: none; + } +} + +@media (max-width: 768px) { + header h1 { + font-size: 2em; + } + + .score-display { + font-size: 1.5em; + } + + .santa-image { + width: 300px; + height: 300px; + } + + .upgrade-name { + font-size: 1.1em; + } +} + +@media (max-width: 480px) { + .container { + padding: 10px; + } + + header h1 { + font-size: 1.5em; + } + + .santa-image { + width: 250px; + height: 250px; + } + + .game-area { + padding: 20px; + } +} diff --git a/index.html b/index.html new file mode 100644 index 0000000..4365277 --- /dev/null +++ b/index.html @@ -0,0 +1,132 @@ + + + + + + Santa Clicker - Vianočná Hra + + + +
+
+
+
+
+
+
+
+ +
+
+

🎅 Santa Clicker 🎄

+
+
Body:
+
0
+
+
+ 0 bodov/s +
+
+ +
+
+
+
+ Santa Claus + +
+
+

Klikni na Santa! 🎁

+
+
+ + +
+
+ + + + + + diff --git a/script.js b/script.js new file mode 100644 index 0000000..c8ff4df --- /dev/null +++ b/script.js @@ -0,0 +1,112 @@ +// Game state +let score = 0; +let perSecond = 0; + +// Upgrade costs and production +const upgrades = [ + { cost: 10, production: 1, owned: 0, multiplier: 1.15 }, + { cost: 50, production: 5, owned: 0, multiplier: 1.15 }, + { cost: 200, production: 20, owned: 0, multiplier: 1.15 }, + { cost: 500, production: 50, owned: 0, multiplier: 1.15 }, + { cost: 1000, production: 100, owned: 0, multiplier: 1.15 } +]; + +// Initialize game +document.addEventListener('DOMContentLoaded', function() { + // Setup click handler for Santa + const santaImage = document.getElementById('santaImage'); + const santaEmoji = document.getElementById('santaEmoji'); + const clickEffect = document.getElementById('clickEffect'); + + const handleSantaClick = function(e) { + // Add score + score++; + updateDisplay(); + + // Show click effect + clickEffect.textContent = '+1'; + clickEffect.classList.remove('show'); + void clickEffect.offsetWidth; // Trigger reflow + clickEffect.classList.add('show'); + }; + + santaImage.addEventListener('click', handleSantaClick); + santaEmoji.addEventListener('click', handleSantaClick); + + // Setup upgrade buttons + for (let i = 0; i < 5; i++) { + const button = document.getElementById(`upgrade${i + 1}`); + button.addEventListener('click', function() { + buyUpgrade(i); + }); + } + + // Start background music + const music = document.getElementById('backgroundMusic'); + + // Try to play music (some browsers require user interaction) + const playMusic = () => { + music.play().catch(e => { + console.log('Audio autoplay prevented. Click anywhere to start music.'); + }); + }; + + // Attempt to play on load + playMusic(); + + // Also try to play on first user interaction + document.body.addEventListener('click', function playOnce() { + playMusic(); + document.body.removeEventListener('click', playOnce); + }, { once: true }); + + // Update game state every 100ms + setInterval(updateProduction, 100); + + // Update display + updateDisplay(); +}); + +function buyUpgrade(index) { + const upgrade = upgrades[index]; + + if (score >= upgrade.cost) { + score -= upgrade.cost; + upgrade.owned++; + upgrade.cost = Math.ceil(upgrade.cost * upgrade.multiplier); + + // Recalculate production + calculatePerSecond(); + updateDisplay(); + } +} + +function calculatePerSecond() { + perSecond = 0; + for (let i = 0; i < upgrades.length; i++) { + perSecond += upgrades[i].production * upgrades[i].owned; + } +} + +function updateProduction() { + if (perSecond > 0) { + score += perSecond / 10; // Divide by 10 since we update every 100ms + updateDisplay(); + } +} + +function updateDisplay() { + // Update score + document.getElementById('score').textContent = Math.floor(score); + document.getElementById('perSecond').textContent = perSecond.toFixed(1); + + // Update upgrade displays and button states + for (let i = 0; i < 5; i++) { + const upgrade = upgrades[i]; + document.getElementById(`cost${i + 1}`).textContent = upgrade.cost; + document.getElementById(`owned${i + 1}`).textContent = upgrade.owned; + + const button = document.getElementById(`upgrade${i + 1}`); + button.disabled = score < upgrade.cost; + } +}