Spaces:
Running
Running
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Text Adventure Game</title> | |
| <link rel="icon" type="image/x-icon" href="/static/favicon.ico"> | |
| <script src="https://cdn.tailwindcss.com"></script> | |
| <script src="https://cdn.jsdelivr.net/npm/feather-icons/dist/feather.min.js"></script> | |
| <script src="https://cdn.jsdelivr.net/npm/animejs/lib/anime.iife.min.js"></script> | |
| <script src="https://unpkg.com/feather-icons"></script> | |
| <style> | |
| @import url('https://fonts.googleapis.com/css2?family=MedievalSharp&family=Press+Start+2P&display=swap'); | |
| body { | |
| font-family: 'MedievalSharp', cursive; | |
| background: linear-gradient(135deg, #1a202c 0%, #2d3748 100%); | |
| color: #e2e8f0; | |
| } | |
| .game-font { | |
| font-family: 'Press Start 2P', cursive; | |
| } | |
| .scrollbar-custom { | |
| scrollbar-width: thin; | |
| scrollbar-color: #4a5568 #2d3748; | |
| } | |
| .scrollbar-custom::-webkit-scrollbar { | |
| width: 6px; | |
| } | |
| .scrollbar-custom::-webkit-scrollbar-track { | |
| background: #2d3748; | |
| } | |
| .scrollbar-custom::-webkit-scrollbar-thumb { | |
| background: #4a5568; | |
| border-radius: 3px; | |
| } | |
| .typewriter { | |
| overflow: hidden; | |
| border-right: 2px solid #e2e8f0; | |
| white-space: nowrap; | |
| margin: 0 auto; | |
| animation: typing 3.5s steps(40, end), blink-caret 0.75s step-end infinite; | |
| } | |
| @keyframes typing { | |
| from { width: 0 } | |
| to { width: 100% } | |
| } | |
| @keyframes blink-caret { | |
| from, to { border-color: transparent } | |
| 50% { border-color: #e2e8f0 } | |
| } | |
| .fade-in { | |
| animation: fadeIn 0.5s ease-in; | |
| } | |
| @keyframes fadeIn { | |
| from { opacity: 0; transform: translateY(10px); } | |
| to { opacity: 1; transform: translateY(0); } | |
| } | |
| .pixel-border { | |
| border: 4px solid; | |
| border-image: | |
| linear-gradient(45deg, #e53e3e, #dd6b20, #38a169, #3182ce, #805ad5) 1; | |
| } | |
| .glow { | |
| box-shadow: 0 0 20px rgba(66, 153, 225, 0.5); | |
| } | |
| </style> | |
| </head> | |
| <body class="min-h-screen flex flex-col"> | |
| <!-- Header --> | |
| <header class="bg-gray-900 border-b-4 border-yellow-600"> | |
| <div class="container mx-auto px-4 py-4"> | |
| <div class="flex items-center justify-between"> | |
| <div class="flex items-center space-x-4"> | |
| <div class="w-12 h-12 bg-red-600 rounded-full flex items-center justify-center glow"> | |
| <i data-feather="sword" class="text-white"></i> | |
| </div> | |
| <h1 class="text-2xl game-font text-yellow-400">DRAGON'S LEGACY</h1> | |
| </div> | |
| <div class="flex items-center space-x-6"> | |
| <div class="flex items-center space-x-2"> | |
| <i data-feather="heart" class="text-red-500"></i> | |
| <span class="game-font">HP: <span id="health">100</span>/100</span> | |
| </div> | |
| <div class="flex items-center space-x-2"> | |
| <i data-feather="star" class="text-yellow-500"></i> | |
| <span class="game-font">Level: <span id="level">1</span></span> | |
| </div> | |
| <div class="flex items-center space-x-2"> | |
| <i data-feather="award" class="text-green-500"></i> | |
| <span class="game-font">XP: <span id="xp">0</span>/100</span> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </header> | |
| <!-- Main Content --> | |
| <main class="flex-1 container mx-auto px-4 py-8"> | |
| <div class="grid grid-cols-1 lg:grid-cols-3 gap-8"> | |
| <!-- Game Area --> | |
| <div class="lg:col-span-2 space-y-6"> | |
| <!-- Location & Description --> | |
| <div class="bg-gray-800 rounded-lg p-6 pixel-border fade-in"> | |
| <div class="flex items-center justify-between mb-4"> | |
| <h2 class="text-xl game-font text-yellow-400" id="location">The Old Forest</h2> | |
| <div class="flex space-x-2"> | |
| <button class="bg-blue-600 hover:bg-blue-700 px-3 py-1 rounded game-font text-sm" onclick="saveGame()"> | |
| <i data-feather="save" class="w-4 h-4 inline mr-1"></i>Save | |
| </button> | |
| <button class="bg-green-600 hover:bg-green-700 px-3 py-1 rounded game-font text-sm" onclick="loadGame()"> | |
| <i data-feather="download" class="w-4 h-4 inline mr-1"></i>Load | |
| </button> | |
| </div> | |
| </div> | |
| <div class="bg-black bg-opacity-50 rounded p-4 min-h-32"> | |
| <p id="description" class="text-gray-300 leading-relaxed"> | |
| You stand at the edge of an ancient forest. Moss-covered trees tower above you, and a narrow path | |
| winds its way into the darkness. The air is cool and carries the scent of damp earth and pine. | |
| Somewhere in the distance, a bird calls out, its cry echoing through the woods. | |
| </p> | |
| </div> | |
| </div> | |
| <!-- Action Buttons --> | |
| <div class="grid grid-cols-2 gap-4 fade-in" id="actions"> | |
| <button class="bg-gradient-to-r from-green-600 to-green-700 hover:from-green-700 hover:to-green-800 p-4 rounded-lg game-font text-sm transition-all duration-300 transform hover:scale-105" onclick="takeAction('north')"> | |
| <i data-feather="arrow-up" class="w-5 h-5 inline mr-2"></i>Go North | |
| </button> | |
| <button class="bg-gradient-to-r from-green-600 to-green-700 hover:from-green-700 hover:to-green-800 p-4 rounded-lg game-font text-sm transition-all duration-300 transform hover:scale-105" onclick="takeAction('south')"> | |
| <i data-feather="arrow-down" class="w-5 h-5 inline mr-2"></i>Go South | |
| </button> | |
| <button class="bg-gradient-to-r from-blue-600 to-blue-700 hover:from-blue-700 hover:to-blue-800 p-4 rounded-lg game-font text-sm transition-all duration-300 transform hover:scale-105" onclick="takeAction('examine')"> | |
| <i data-feather="search" class="w-5 h-5 inline mr-2"></i>Examine Area | |
| </button> | |
| <button class="bg-gradient-to-r from-purple-600 to-purple-700 hover:from-purple-700 hover:to-purple-800 p-4 rounded-lg game-font text-sm transition-all duration-300 transform hover:scale-105" onclick="takeAction('inventory')"> | |
| <i data-feather="package" class="w-5 h-5 inline mr-2"></i>Inventory | |
| </button> | |
| </div> | |
| <!-- Combat Section --> | |
| <div id="combat-section" class="hidden bg-red-900 rounded-lg p-6 pixel-border fade-in"> | |
| <h3 class="text-lg game-font text-red-300 mb-4">COMBAT!</h3> | |
| <div class="grid grid-cols-2 gap-4"> | |
| <button class="bg-red-600 hover:bg-red-700 p-3 rounded game-font text-sm" onclick="combatAction('attack')"> | |
| <i data-feather="sword" class="w-4 h-4 inline mr-2"></i>Attack | |
| </button> | |
| <button class="bg-yellow-600 hover:bg-yellow-700 p-3 rounded game-font text-sm" onclick="combatAction('defend')"> | |
| <i data-feather="shield" class="w-4 h-4 inline mr-2"></i>Defend | |
| </button> | |
| <button class="bg-blue-600 hover:bg-blue-700 p-3 rounded game-font text-sm" onclick="combatAction('spell')"> | |
| <i data-feather="zap" class="w-4 h-4 inline mr-2"></i>Cast Spell | |
| </button> | |
| <button class="bg-green-600 hover:bg-green-700 p-3 rounded game-font text-sm" onclick="combatAction('flee')"> | |
| <i data-feather="wind" class="w-4 h-4 inline mr-2"></i>Flee | |
| </button> | |
| </div> | |
| </div> | |
| <!-- Game Log --> | |
| <div class="bg-gray-900 rounded-lg p-4 pixel-border"> | |
| <h3 class="text-lg game-font text-blue-400 mb-3">GAME LOG</h3> | |
| <div id="game-log" class="h-48 overflow-y-auto scrollbar-custom bg-black bg-opacity-50 rounded p-3 space-y-2"> | |
| <div class="text-green-400 text-sm">> Welcome to Dragon's Legacy! Your adventure begins...</div> | |
| <div class="text-yellow-400 text-sm">> You find yourself at the edge of the Old Forest.</div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Sidebar --> | |
| <div class="space-y-6"> | |
| <!-- Character Info --> | |
| <div class="bg-gray-800 rounded-lg p-6 pixel-border fade-in"> | |
| <h3 class="text-lg game-font text-purple-400 mb-4">CHARACTER</h3> | |
| <div class="space-y-3"> | |
| <div class="flex justify-between"> | |
| <span>Class:</span> | |
| <span class="text-yellow-400" id="character-class">Warrior</span> | |
| </div> | |
| <div class="flex justify-between"> | |
| <span>Strength:</span> | |
| <span class="text-red-400" id="strength">12</span> | |
| </div> | |
| <div class="flex justify-between"> | |
| <span>Agility:</span> | |
| <span class="text-green-400" id="agility">10</span> | |
| </div> | |
| <div class="flex justify-between"> | |
| <span>Intelligence:</span> | |
| <span class="text-blue-400" id="intelligence">8</span> | |
| </div> | |
| <div class="flex justify-between"> | |
| <span>Gold:</span> | |
| <span class="text-yellow-400" id="gold">50</span> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Inventory --> | |
| <div class="bg-gray-800 rounded-lg p-6 pixel-border fade-in"> | |
| <h3 class="text-lg game-font text-green-400 mb-4">INVENTORY</h3> | |
| <div id="inventory-items" class="space-y-2"> | |
| <div class="flex justify-between items-center bg-gray-700 p-2 rounded"> | |
| <span>Iron Sword</span> | |
| <span class="text-xs text-gray-400">Weapon</span> | |
| </div> | |
| <div class="flex justify-between items-center bg-gray-700 p-2 rounded"> | |
| <span>Health Potion</span> | |
| <span class="text-xs text-gray-400">Consumable</span> | |
| </div> | |
| <div class="flex justify-between items-center bg-gray-700 p-2 rounded"> | |
| <span>Leather Armor</span> | |
| <span class="text-xs text-gray-400">Armor</span> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Map --> | |
| <div class="bg-gray-800 rounded-lg p-6 pixel-border fade-in"> | |
| <h3 class="text-lg game-font text-red-400 mb-4">WORLD MAP</h3> | |
| <div class="bg-black bg-opacity-50 rounded p-4 text-center"> | |
| <div class="text-gray-500 text-sm mb-2">Old Forest</div> | |
| <div class="grid grid-cols-3 gap-1 text-xs"> | |
| <div class="p-2 bg-gray-700 rounded">Mountains</div> | |
| <div class="p-2 bg-green-700 rounded text-yellow-400 glow">Old Forest</div> | |
| <div class="p-2 bg-gray-700 rounded">River</div> | |
| <div class="p-2 bg-gray-700 rounded">Village</div> | |
| <div class="p-2 bg-gray-700 rounded">Castle</div> | |
| <div class="p-2 bg-gray-700 rounded">Caves</div> | |
| <div class="p-2 bg-gray-700 rounded">Swamp</div> | |
| <div class="p-2 bg-gray-700 rounded">Ruins</div> | |
| <div class="p-2 bg-gray-700 rounded">Dungeon</div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Quests --> | |
| <div class="bg-gray-800 rounded-lg p-6 pixel-border fade-in"> | |
| <h3 class="text-lg game-font text-blue-400 mb-4">ACTIVE QUESTS</h3> | |
| <div class="space-y-3"> | |
| <div class="bg-gray-700 p-3 rounded"> | |
| <div class="flex justify-between items-start mb-2"> | |
| <span class="text-yellow-400 font-bold">The Lost Amulet</span> | |
| <span class="text-xs bg-yellow-600 px-2 py-1 rounded">Active</span> | |
| </div> | |
| <p class="text-sm text-gray-300">Find the ancient amulet hidden in the forest ruins.</p> | |
| <div class="w-full bg-gray-600 rounded-full h-2 mt-2"> | |
| <div class="bg-yellow-500 h-2 rounded-full" style="width: 30%"></div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </main> | |
| <!-- Footer --> | |
| <footer class="bg-gray-900 border-t-4 border-yellow-600 py-4"> | |
| <div class="container mx-auto px-4 text-center"> | |
| <p class="game-font text-sm text-gray-400">DRAGON'S LEGACY - A Text Adventure Game</p> | |
| </div> | |
| </footer> | |
| <!-- Game Script --> | |
| <script> | |
| // Game State | |
| const gameState = { | |
| location: 'old_forest', | |
| health: 100, | |
| maxHealth: 100, | |
| level: 1, | |
| xp: 0, | |
| xpToNextLevel: 100, | |
| gold: 50, | |
| inventory: ['Iron Sword', 'Health Potion', 'Leather Armor'], | |
| stats: { | |
| strength: 12, | |
| agility: 10, | |
| intelligence: 8 | |
| }, | |
| quests: { | |
| 'lost_amulet': { | |
| name: 'The Lost Amulet', | |
| description: 'Find the ancient amulet hidden in the forest ruins.', | |
| progress: 30, | |
| active: true | |
| } | |
| } | |
| }; | |
| // Locations Data | |
| const locations = { | |
| 'old_forest': { | |
| name: 'The Old Forest', | |
| description: 'You stand at the edge of an ancient forest. Moss-covered trees tower above you, and a narrow path winds its way into the darkness. The air is cool and carries the scent of damp earth and pine.', | |
| actions: ['north', 'south', 'examine', 'inventory'] | |
| }, | |
| 'forest_ruins': { | |
| name: 'Forest Ruins', | |
| description: 'Before you lie the crumbling remains of an ancient civilization. Stone pillars rise from the undergrowth, and faded carvings hint at forgotten stories.', | |
| actions: ['north', 'south', 'examine', 'search'] | |
| } | |
| }; | |
| // Game Functions | |
| function takeAction(action) { | |
| const log = document.getElementById('game-log'); | |
| let message = ''; | |
| switch(action) { | |
| case 'north': | |
| if (gameState.location === 'old_forest') { | |
| gameState.location = 'forest_ruins'; | |
| message = 'You travel north and discover ancient ruins hidden among the trees.'; | |
| } else { | |
| message = 'You cannot go that way.'; | |
| } | |
| break; | |
| case 'south': | |
| if (gameState.location === 'forest_ruins') { | |
| gameState.location = 'old_forest'; | |
| message = 'You return to the edge of the Old Forest.'; | |
| } else { | |
| message = 'You cannot go that way.'; | |
| } | |
| break; | |
| case 'examine': | |
| message = 'You carefully search the area but find nothing unusual.'; | |
| break; | |
| case 'inventory': | |
| message = 'You check your inventory.'; | |
| showInventoryModal(); | |
| break; | |
| default: | |
| message = 'Unknown action.'; | |
| } | |
| updateLocation(); | |
| addToLog(message); | |
| } | |
| function combatAction(action) { | |
| const log = document.getElementById('game-log'); | |
| let message = ''; | |
| switch(action) { | |
| case 'attack': | |
| message = 'You swing your sword at the enemy!'; | |
| break; | |
| case 'defend': | |
| message = 'You raise your shield and prepare for an attack.'; | |
| break; | |
| case 'spell': | |
| message = 'You cast a powerful spell!'; | |
| break; | |
| case 'flee': | |
| message = 'You attempt to flee from battle...'; | |
| break; | |
| } | |
| addToLog(message); | |
| } | |
| function updateLocation() { | |
| const location = locations[gameState.location]; | |
| document.getElementById('location').textContent = location.name; | |
| document.getElementById('description').textContent = location.description; | |
| // Add typewriter effect | |
| const descriptionElement = document.getElementById('description'); | |
| const text = descriptionElement.textContent; | |
| descriptionElement.textContent = ''; | |
| descriptionElement.classList.add('typewriter'); | |
| descriptionElement.style.width = '0'; | |
| setTimeout(() => { | |
| descriptionElement.textContent = text; | |
| descriptionElement.classList.remove('typewriter'); | |
| descriptionElement.style.width = 'auto'; | |
| }, 100); | |
| } | |
| function addToLog(message) { | |
| const log = document.getElementById('game-log'); | |
| const entry = document.createElement('div'); | |
| entry.className = 'text-green-400 text-sm fade-in'; | |
| entry.textContent = '> ' + message; | |
| log.appendChild(entry); | |
| log.scrollTop = log.scrollHeight; | |
| } | |
| function showInventoryModal() { | |
| // Simple inventory display - could be enhanced with a modal | |
| addToLog('Inventory: ' + gameState.inventory.join(', ')); | |
| } | |
| function saveGame() { | |
| localStorage.setItem('dragonLegacySave', JSON.stringify(gameState)); | |
| addToLog('Game saved successfully!'); | |
| } | |
| function loadGame() { | |
| const saved = localStorage.getItem('dragonLegacySave'); | |
| if (saved) { | |
| Object.assign(gameState, JSON.parse(saved)); | |
| updateUI(); | |
| addToLog('Game loaded successfully!'); | |
| } else { | |
| addToLog('No saved game found.'); | |
| } | |
| } | |
| function updateUI() { | |
| document.getElementById('health').textContent = gameState.health; | |
| document.getElementById('level').textContent = gameState.level; | |
| document.getElementById('xp').textContent = gameState.xp; | |
| document.getElementById('gold').textContent = gameState.gold; | |
| document.getElementById('strength').textContent = gameState.stats.strength; | |
| document.getElementById('agility').textContent = gameState.stats.agility; | |
| document.getElementById('intelligence').textContent = gameState.stats.intelligence; | |
| updateLocation(); | |
| } | |
| // Initialize game | |
| document.addEventListener('DOMContentLoaded', function() { | |
| feather.replace(); | |
| updateUI(); | |
| // Add some initial game messages | |
| setTimeout(() => { | |
| addToLog('Use the action buttons to explore the world.'); | |
| addToLog('Your quest: Find the Lost Amulet in the forest ruins.'); | |
| }, 1000); | |
| }); | |
| </script> | |
| </body> | |
| </html> | |