diff --git a/2048.js b/2048.js index 437d8f1..589f60c 100644 --- a/2048.js +++ b/2048.js @@ -1,4 +1,4 @@ -/* 2048.js — Complete Version with WASD + Interactive Effects + Sound Controls */ + /* ------------------------ State & Variables @@ -49,6 +49,24 @@ function tryPlayBg() { }); } +/* ===== AUTO TUTORIAL FOR FIRST TIME USERS ===== */ +function checkAndShowTutorial() { + const showTutorial = sessionStorage.getItem("showTutorial"); + const loggedInUser = sessionStorage.getItem("loggedInUser"); + + // Jika user baru (showTutorial = "true"), tampilkan tutorial otomatis + if (showTutorial === "true" && loggedInUser) { + setTimeout(() => { + const tutorialOverlay = document.getElementById('tutorial-overlay'); + if (tutorialOverlay) { + tutorialOverlay.style.display = 'flex'; + } + // Set flag agar tidak muncul lagi di session ini + sessionStorage.setItem("showTutorial", "false"); + }, 500); // Delay 500ms agar halaman sudah fully loaded + } +} + /* ------------------------ DOM Ready ------------------------ */ @@ -61,6 +79,7 @@ document.addEventListener("DOMContentLoaded", () => { tryPlayBg(); document.addEventListener("keydown", handleKey); setupEventListeners(); + checkAndShowTutorial(); }); /* ------------------------ @@ -605,9 +624,6 @@ function hideGameOver() { } } -/* ============================================= - SOUND CONTROLS - ============================================= */ /* ============================================= ADVANCED VOLUME CONTROL SYSTEM ============================================= */ diff --git a/Animation_Homepage.js b/Animation_Homepage.js new file mode 100644 index 0000000..b0419d6 --- /dev/null +++ b/Animation_Homepage.js @@ -0,0 +1,66 @@ +// Neon Particles Animation - Optimized for Academic Project +const particlesContainer = document.getElementById('particles'); +const particleCount = 25; // Reduced for better performance + +function createParticle() { + const particle = document.createElement('div'); + particle.className = 'particle'; + + // Random position + particle.style.left = Math.random() * 100 + '%'; + particle.style.top = Math.random() * 100 + '%'; + + // Random animation duration + const duration = 20 + Math.random() * 20; + particle.style.animationDuration = duration + 's'; + + // Random delay + particle.style.animationDelay = Math.random() * 10 + 's'; + + // Random size variation (smaller) + const size = 3 + Math.random() * 3; + particle.style.width = size + 'px'; + particle.style.height = size + 'px'; + + // Random colors (neon theme) + const colors = [ + 'radial-gradient(circle, #00ffff, #0099ff)', + 'radial-gradient(circle, #ff00ff, #cc00ff)', + 'radial-gradient(circle, #00ff99, #00cc77)' + ]; + particle.style.background = colors[Math.floor(Math.random() * colors.length)]; + + // Add floating animation + particle.style.animation = `floatParticle ${duration}s ease-in-out infinite`; + + particlesContainer.appendChild(particle); +} + +// Create particles +for (let i = 0; i < particleCount; i++) { + createParticle(); +} + +// Add CSS animation dynamically +const style = document.createElement('style'); +style.textContent = ` + @keyframes floatParticle { + 0%, 100% { + transform: translate(0, 0) scale(1); + opacity: 0.3; + } + 25% { + transform: translate(15px, -25px) scale(1.1); + opacity: 0.6; + } + 50% { + transform: translate(-10px, -50px) scale(0.9); + opacity: 0.4; + } + 75% { + transform: translate(20px, -35px) scale(1.05); + opacity: 0.5; + } + } +`; +document.head.appendChild(style); \ No newline at end of file diff --git a/Homepage.css b/Homepage.css new file mode 100644 index 0000000..386cf74 --- /dev/null +++ b/Homepage.css @@ -0,0 +1,436 @@ +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +body { + font-family: 'Arial', sans-serif; + background: radial-gradient(circle at 20% 20%, #3b0066, #0c001a 70%); + color: #fff; + overflow-x: hidden; + min-height: 100vh; + position: relative; +} + +/* Neon Particles - MATCHING LOGIN/REGISTER */ +#particles { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + z-index: 1; + pointer-events: none; +} + +.particle { + position: absolute; + width: 5px; + height: 5px; + border-radius: 50%; + background: radial-gradient(circle, #00ffff, #0099ff); + box-shadow: 0 0 10px #00eaff, 0 0 25px #0088ff; + pointer-events: none; +} + +/* Header - MATCHING LOGIN/REGISTER THEME */ +header { + position: relative; + z-index: 10; + padding: 20px 40px; + display: flex; + justify-content: space-between; + align-items: center; + background: rgba(20, 0, 40, 0.65); + backdrop-filter: blur(10px); + border-bottom: 2px solid rgba(0, 234, 255, 0.3); +} + +.logo { + font-size: 28px; + font-weight: 900; + background: linear-gradient(90deg, #00d9ff 0%, #ff00ff 100%); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + background-clip: text; + letter-spacing: 3px; + text-transform: uppercase; +} + +.nav-buttons { + display: flex; + gap: 15px; +} + +.btn { + padding: 12px 28px; + border: none; + border-radius: 12px; + font-weight: 700; + font-size: 16px; + cursor: pointer; + transition: all 0.3s ease; + text-decoration: none; + display: inline-block; + text-align: center; + text-transform: uppercase; + letter-spacing: 2px; +} + +.btn-secondary { + background: rgba(255, 255, 255, 0.08); + color: #fff; + border: 2px solid rgba(0, 175, 255, 0.3); +} + +.btn-secondary:hover { + background: rgba(255, 255, 255, 0.15); + border-color: #00eaff; + box-shadow: 0 0 20px rgba(0, 234, 255, 0.4); + transform: translateY(-2px); +} + +.btn-primary { + background: linear-gradient(90deg, #00eaff, #ff00ff); + color: #fff; + font-weight: 900; + box-shadow: 0 5px 25px rgba(0, 217, 255, 0.4); +} + +.btn-primary:hover { + box-shadow: 0 8px 35px rgba(0, 217, 255, 0.7); + transform: translateY(-3px); +} + +/* Hero Section - IMPROVED TITLE */ +.hero { + position: relative; + z-index: 10; + text-align: center; + padding: 100px 20px 80px; + max-width: 1000px; + margin: 0 auto; +} + +.hero-title { + font-size: 120px; + font-weight: 900; + margin-bottom: 15px; + background: linear-gradient(90deg, #00d9ff 0%, #ff00ff 100%); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + background-clip: text; + letter-spacing: 12px; + text-transform: uppercase; + font-family: 'Arial Black', 'Arial Bold', sans-serif; + text-shadow: 0 0 80px rgba(0, 234, 255, 0.4); + filter: drop-shadow(0 0 30px rgba(255, 0, 255, 0.6)); + animation: titleGlow 3s ease-in-out infinite alternate; + line-height: 1.1; +} + +@keyframes titleGlow { + 0% { + filter: drop-shadow(0 0 20px rgba(0, 234, 255, 0.6)) + drop-shadow(0 0 40px rgba(0, 234, 255, 0.4)); + } + 100% { + filter: drop-shadow(0 0 30px rgba(255, 0, 255, 0.8)) + drop-shadow(0 0 60px rgba(255, 0, 255, 0.5)); + } +} + +.hero-subtitle { + font-size: 20px; + color: rgba(255, 255, 255, 0.7); + margin-bottom: 45px; + font-weight: 400; + letter-spacing: 4px; + text-transform: uppercase; +} + +.cta-buttons { + display: flex; + gap: 20px; + justify-content: center; + flex-wrap: wrap; +} + +.btn-cta { + padding: 16px 40px; + font-size: 18px; + border-radius: 12px; + font-weight: 900; + text-transform: uppercase; + letter-spacing: 2px; + border: none; +} + +.btn-play { + background: linear-gradient(90deg, #ff00ff, #ff0066); + box-shadow: 0 5px 30px rgba(255, 0, 255, 0.5); + color: #fff; +} + +.btn-play:hover { + transform: translateY(-3px); + box-shadow: 0 8px 45px rgba(255, 0, 255, 0.8); +} + +.btn-leaderboard { + background: linear-gradient(90deg, #ffd700, #ffaa00); + color: #0c001a; + box-shadow: 0 5px 30px rgba(255, 215, 0, 0.5); +} + +.btn-leaderboard:hover { + transform: translateY(-3px); + box-shadow: 0 8px 45px rgba(255, 215, 0, 0.8); +} + +/* Section Title - MATCHING THEME */ +.section-title { + position: relative; + z-index: 10; + text-align: center; + font-size: 36px; + margin-bottom: 50px; + background: linear-gradient(90deg, #00d9ff 0%, #ff00ff 100%); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + background-clip: text; + text-transform: uppercase; + letter-spacing: 3px; + font-weight: 900; +} + +/* Features Section */ +.features { + position: relative; + z-index: 10; + max-width: 1200px; + margin: 80px auto; + padding: 0 40px; +} + +.features-grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); + gap: 25px; +} + +.feature-card { + background: rgba(30, 0, 50, 0.5); + border: 2px solid rgba(0, 234, 255, 0.25); + border-radius: 20px; + padding: 35px 25px; + text-align: center; + transition: all 0.3s ease; + backdrop-filter: blur(10px); +} + +.feature-card:hover { + transform: translateY(-8px); + border-color: #00eaff; + box-shadow: 0 10px 35px rgba(0, 234, 255, 0.4); + background: rgba(30, 0, 50, 0.7); +} + +.feature-icon { + font-size: 50px; + margin-bottom: 18px; + filter: drop-shadow(0 0 15px currentColor); +} + +.feature-card h3 { + font-size: 20px; + margin-bottom: 12px; + font-weight: 800; + color: #00eaff; + text-transform: uppercase; + letter-spacing: 1px; +} + +.feature-card p { + font-size: 15px; + color: rgba(255, 255, 255, 0.7); + line-height: 1.6; +} + +/* How to Play Section */ +.how-to-play { + position: relative; + z-index: 10; + max-width: 1200px; + margin: 80px auto; + padding: 0 40px; +} + +.steps { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); + gap: 25px; +} + +.step { + background: rgba(30, 0, 50, 0.5); + border: 2px solid rgba(0, 234, 255, 0.25); + border-radius: 20px; + padding: 35px 25px; + text-align: center; + transition: all 0.3s ease; + backdrop-filter: blur(10px); +} + +.step:hover { + transform: translateY(-8px); + border-color: #00eaff; + box-shadow: 0 10px 35px rgba(0, 234, 255, 0.4); +} + +.step-number { + width: 60px; + height: 60px; + margin: 0 auto 20px; + border-radius: 50%; + background: linear-gradient(135deg, #00eaff, #ff00ff); + color: #fff; + font-size: 28px; + font-weight: 900; + display: flex; + align-items: center; + justify-content: center; + box-shadow: 0 0 25px rgba(0, 234, 255, 0.6); +} + +.step h3 { + font-size: 20px; + margin-bottom: 12px; + color: #00eaff; + text-transform: uppercase; + letter-spacing: 1px; + font-weight: 800; +} + +.step p { + font-size: 15px; + color: rgba(255, 255, 255, 0.7); + line-height: 1.6; +} + +/* Footer */ +footer { + position: relative; + z-index: 10; + text-align: center; + padding: 40px 20px; + margin-top: 100px; + background: rgba(20, 0, 40, 0.65); + backdrop-filter: blur(10px); + border-top: 2px solid rgba(0, 234, 255, 0.3); +} + +footer p { + color: rgba(255, 255, 255, 0.6); + font-size: 15px; +} + +/* Responsive */ +@media (max-width: 1024px) { + .hero-title { + font-size: 90px; + letter-spacing: 8px; + } +} + +@media (max-width: 768px) { + header { + padding: 15px 20px; + flex-direction: column; + gap: 15px; + } + + .logo { + font-size: 24px; + } + + .hero { + padding: 70px 20px 60px; + } + + .hero-title { + font-size: 64px; + letter-spacing: 6px; + } + + .hero-subtitle { + font-size: 16px; + letter-spacing: 2px; + } + + .btn-cta { + padding: 14px 32px; + font-size: 16px; + } + + .features, + .how-to-play { + padding: 0 20px; + margin: 60px auto; + } + + .section-title { + font-size: 28px; + margin-bottom: 35px; + } + + .features-grid, + .steps { + grid-template-columns: 1fr; + gap: 20px; + } +} + +@media (max-width: 480px) { + .hero { + padding: 50px 15px 40px; + } + + .hero-title { + font-size: 48px; + letter-spacing: 4px; + } + + .hero-subtitle { + font-size: 14px; + letter-spacing: 2px; + margin-bottom: 35px; + } + + .btn-cta { + padding: 13px 28px; + font-size: 15px; + } + + .section-title { + font-size: 24px; + letter-spacing: 2px; + } + + .feature-card, + .step { + padding: 28px 20px; + } + + .feature-icon { + font-size: 45px; + } +} + +@media (max-width: 360px) { + .hero-title { + font-size: 40px; + letter-spacing: 3px; + } +} \ No newline at end of file diff --git a/Homepage.html b/Homepage.html new file mode 100644 index 0000000..d075c64 --- /dev/null +++ b/Homepage.html @@ -0,0 +1,105 @@ + + + + + + Homepage - 2048 + + + + +
+ + +
+ + +
+ + +
+
2048
+

Join the tiles, reach 2048

+
+ Play Now + 🏆 Leaderboard +
+
+ + +
+

Game Features

+
+
+
🎮
+

Responsive Controls

+

Play using arrow keys or WASD controls with smooth tile animations and instant feedback

+
+ +
+
+

Visual Effects

+

Neon-themed interface with particle effects, combo animations, and dynamic color schemes

+
+ +
+
🎵
+

Sound System

+

Background music and sound effects with individual volume controls for complete customization

+
+ +
+
🏆
+

Leaderboard

+

Track high scores and compete with other players in a global ranking system

+
+ +
+
👤
+

User System

+

Register and login to save your progress and maintain your score history

+
+ +
+
📱
+

Mobile Support

+

Fully responsive design with touch swipe controls for mobile devices

+
+
+
+ + +
+

How to Play

+
+
+
1
+

Move Tiles

+

Use arrow keys, WASD, or swipe to move tiles in any direction

+
+ +
+
2
+

Merge Numbers

+

When two tiles with the same number touch, they merge into one

+
+ +
+
3
+

Reach 2048

+

Keep merging tiles to reach the 2048 tile and win the game

+
+
+
+ + + + + + + \ No newline at end of file