|
2 | 2 | <html lang="en"> |
3 | 3 | <head> |
4 | 4 | <meta charset="UTF-8"> |
5 | | -<title>Compact Random Enemy Generator</title> |
| 5 | +<title>Random Enemy Generator with Save</title> |
6 | 6 | <style> |
7 | 7 | body { |
8 | 8 | font-family: sans-serif; |
|
11 | 11 | color: #f0f0f0; |
12 | 12 | } |
13 | 13 | h1 { margin-bottom: 10px; } |
14 | | -.buttons { display: flex; gap: 10px; margin-bottom: 20px; } |
| 14 | +.buttons { display: flex; flex-wrap: wrap; gap: 10px; margin-bottom: 20px; } |
15 | 15 | button { |
16 | 16 | padding: 8px 16px; |
17 | 17 | font-size: 14px; |
|
51 | 51 | @keyframes fadeIn { to { opacity: 1; } } |
52 | 52 | @keyframes floatEnemy { 0% { transform: translateY(0); } 100% { transform: translateY(-3px); } } |
53 | 53 |
|
54 | | -.loot.common { color: #ccc; text-shadow: 0 0 1px #ccc; } |
55 | | -.loot.rare { color: #1e90ff; text-shadow: 0 0 3px #1e90ff; } |
56 | | -.loot.epic { color: #a020f0; text-shadow: 0 0 5px #a020f0; } |
57 | | -.loot.legendary { color: #fbc02d; text-shadow: 0 0 6px #fbc02d,0 0 12px #fbc02d; animation: float 1.2s ease-in-out infinite alternate; } |
58 | | -.loot.mythic { color: #ff1493; text-shadow: 0 0 7px #ff1493,0 0 14px #ff1493; animation: float 1.2s ease-in-out infinite alternate; } |
59 | | -.loot.divine { color: #00ffff; text-shadow: 0 0 7px #00ffff,0 0 14px #00ffff; animation: float 1.2s ease-in-out infinite alternate; } |
60 | | - |
61 | | -@keyframes float { 0% { transform: translateY(0px); } 100% { transform: translateY(-4px); } } |
| 54 | +.loot.common { color: #ccc; } |
| 55 | +.loot.rare { color: #1e90ff; } |
| 56 | +.loot.epic { color: #a020f0; } |
| 57 | +.loot.legendary { color: #fbc02d; text-shadow: 0 0 6px #fbc02d; } |
| 58 | +.loot.mythic { color: #ff1493; text-shadow: 0 0 7px #ff1493; } |
| 59 | +.loot.divine { color: #00ffff; text-shadow: 0 0 7px #00ffff; } |
62 | 60 |
|
63 | 61 | .sparkle { position: absolute; width: 3px; height: 3px; border-radius: 50%; pointer-events: none; opacity: 0; animation: drift 1.2s forwards; } |
64 | 62 | @keyframes drift { 0% { transform: translate(0,0) scale(1); opacity: 1; } 100% { transform: translate(var(--x), var(--y)) scale(1.2); opacity: 0; } } |
65 | | - |
66 | | -/* Elemental effects */ |
67 | | -.elementalEffect { |
68 | | - position: absolute; |
69 | | - top: 0; left: 0; right: 0; bottom: 0; |
70 | | - pointer-events: none; |
71 | | - border-radius: 6px; |
72 | | - z-index: 0; |
73 | | -} |
74 | | -.fire { background: radial-gradient(rgba(255,69,0,0.2), transparent); animation: flicker 1s infinite alternate; } |
75 | | -.water { background: radial-gradient(rgba(30,144,255,0.2), transparent); animation: ripple 2s infinite alternate; } |
76 | | -.wind { background: radial-gradient(rgba(200,200,200,0.15), transparent); animation: swirl 3s infinite linear; } |
77 | | -.earth { background: radial-gradient(rgba(34,139,34,0.15), transparent); animation: dust 3s infinite alternate; } |
78 | | -.lightning { background: radial-gradient(rgba(249,255,0,0.2), transparent); animation: spark 0.5s infinite alternate; } |
79 | | -.ice { background: radial-gradient(rgba(160,224,255,0.2), transparent); animation: snow 2s infinite linear; } |
80 | | -.poison { background: radial-gradient(rgba(106,13,173,0.15), transparent); animation: mist 3s infinite alternate; } |
81 | | -.shadow { background: radial-gradient(rgba(85,85,85,0.2), transparent); animation: smoke 3s infinite alternate; } |
82 | | -.light { background: radial-gradient(rgba(255,215,0,0.15), transparent); animation: glowPulse 2s infinite alternate; } |
83 | | -.arcane { background: radial-gradient(rgba(184,115,255,0.15), transparent); animation: twinkle 2s infinite alternate; } |
84 | | -.nature { background: radial-gradient(rgba(50,205,50,0.15), transparent); animation: petalFall 3s infinite linear; } |
85 | | -.spirit { background: radial-gradient(rgba(240,248,255,0.15), transparent); animation: wisp 3s infinite alternate; } |
86 | | - |
87 | | -@keyframes flicker { 0% { opacity:0.3;} 50% { opacity:0.6;} 100% { opacity:0.4;} } |
88 | | -@keyframes ripple { 0% { transform: scale(0.9);} 50% { transform: scale(1.1);} 100% { transform: scale(1);} } |
89 | | -@keyframes swirl { 0% { transform: rotate(0deg);} 100% { transform: rotate(360deg);} } |
90 | | -@keyframes dust { 0% { transform: translateY(0);} 100% { transform: translateY(-4px);} } |
91 | | -@keyframes spark { 0% { opacity:0.3;} 50% { opacity:0.8;} 100% { opacity:0.3;} } |
92 | | -@keyframes snow { 0% { background-position:0 0;} 100% { background-position:15px 15px;} } |
93 | | -@keyframes mist { 0% { opacity:0.2;} 100% { opacity:0.5;} } |
94 | | -@keyframes smoke { 0% { transform: translateY(0);} 100% { transform: translateY(-6px);} } |
95 | | -@keyframes glowPulse { 0% { opacity:0.2;} 100% { opacity:0.5;} } |
96 | | -@keyframes twinkle { 0% { opacity:0.3;} 100% { opacity:0.6;} } |
97 | | -@keyframes petalFall { 0% { transform: translateY(0);} 100% { transform: translateY(6px);} } |
98 | | -@keyframes wisp { 0% { transform: translateY(0);} 100% { transform: translateY(-4px);} } |
99 | 63 | </style> |
100 | 64 | </head> |
101 | 65 | <body> |
102 | 66 |
|
103 | | -<h1>🔥 Compact Random Enemy Generator ⚔️</h1> |
| 67 | +<h1>⚔️ Random Enemy Generator 💾</h1> |
104 | 68 | <div class="buttons"> |
105 | 69 | <button id="generate">Generate Enemy</button> |
106 | 70 | <button id="clear">Clear Enemies</button> |
| 71 | + <button id="save">Save Enemies as JSON</button> |
107 | 72 | </div> |
108 | 73 | <div id="enemyList"></div> |
109 | 74 |
|
110 | 75 | <script> |
111 | 76 | // Helpers |
112 | 77 | function randomChoice(arr){return arr[Math.floor(Math.random()*arr.length)];} |
113 | 78 |
|
114 | | -// Adjectives, Names, Types, Elements, Loot |
115 | | -const adjectives=["Fierce","Ancient","Tiny","Shadowy","Savage","Corrupted","Enraged","Cunning","Mystic","Vicious","Silent","Wild","Infernal","Frozen","Electric","Venomous","Ghastly","Raging","Brutal","Cursed","Divine","Mighty","Swift","Stealthy","Burning","Spectral","Arcane","Stone","Thunderous","Twisted","Bloodthirsty","Dreadful","Ironclad","Phantom","Lurking","Shadowed","Vengeful","Golden","Ethereal","Plagued","Shimmering","Rotted","Frostbitten","Blazing","Haunted","Toxic","Stormy","Spiritbound","Emerald","Obsidian","Crystal","Radiant","Darkened","Luminous","Ancientborn"]; |
| 79 | +// Data pools |
| 80 | +const adjectives=["Fierce","Ancient","Tiny","Shadowy","Savage","Corrupted","Enraged","Cunning","Mystic","Vicious","Silent","Wild","Infernal","Frozen","Electric","Venomous","Ghastly","Raging","Brutal","Cursed","Divine","Mighty","Swift","Stealthy","Burning","Spectral","Arcane","Stone","Thunderous","Twisted","Bloodthirsty","Dreadful","Ironclad","Phantom","Lurking","Vengeful","Golden","Ethereal","Plagued","Shimmering","Rotted","Frostbitten","Blazing","Haunted","Toxic","Stormy","Spiritbound","Emerald","Obsidian","Crystal","Radiant","Darkened","Luminous","Ancientborn"]; |
116 | 81 | const names=["Goblin","Specter","Slime","Wolf","Elemental","Ogre","Reaper","Imp","Wraith","Troll","Skeleton","Zombie","Dragonling","Ghoul","Harpy","Banshee","Golem","Phantom","Lich","Spider","Mimic","Serpent","Hydra","Wyvern","Vampire","Bat","Beast","Fiend","Shade","Kraken","Chimera","Minotaur","Demon","Pixie","Fairy","Kobold","Cyclops","Salamander","Wisp","Drake","Wolverine","Raptor","Cobra","Oni","Succubus","Incubus","Necromancer","Shadebeast","Frostling","Firebrand","Stormcaller","Earthshaker","Spiritwalker","Nightstalker","Venomfang"]; |
117 | 82 | const types=[{name:"Melee",emoji:"⚔️"},{name:"Ranged",emoji:"🏹"},{name:"Caster",emoji:"🔮"},{name:"Assassin",emoji:"🗡️"},{name:"Tank",emoji:"🛡️"},{name:"Summoner",emoji:"🐾"},{name:"Berserker",emoji:"🔥"},{name:"Sniper",emoji:"🎯"},{name:"Healer",emoji:"💖"},{name:"Mage",emoji:"✨"},{name:"Necromancer",emoji:"☠️"},{name:"Elementalist",emoji:"🌪️"},{name:"Rogue",emoji:"🌙"},{name:"Shaman",emoji:"🪶"},{name:"Warlock",emoji:"💀"}]; |
118 | 83 | const elements=[{name:"Fire",emoji:"🔥",color:"#ff4500"},{name:"Water",emoji:"💧",color:"#1e90ff"},{name:"Wind",emoji:"🌪️",color:"#ccc"},{name:"Earth",emoji:"🌱",color:"#228b22"},{name:"Lightning",emoji:"⚡",color:"#f9ff00"},{name:"Ice",emoji:"❄️",color:"#a0e0ff"},{name:"Poison",emoji:"☠️",color:"#6a0dad"},{name:"Shadow",emoji:"🌑",color:"#555"},{name:"Light",emoji:"🌞",color:"#ffd700"},{name:"Arcane",emoji:"💫",color:"#b873ff"},{name:"Nature",emoji:"🌸",color:"#32cd32"},{name:"Spirit",emoji:"🪶",color:"#f0f8ff"}]; |
119 | 84 | const lootRarities=[{name:"🪓 Common",class:"common"},{name:"🟦 Uncommon",class:"rare"},{name:"🟩 Rare",class:"rare"},{name:"🟪 Epic",class:"epic"},{name:"🟨 Legendary",class:"legendary"},{name:"💎 Mythic",class:"mythic"},{name:"🌟 Divine",class:"divine"}]; |
120 | 85 | const lootItems=["Sword","Bow","Staff","Dagger","Amulet","Ring","Armor","Wand","Helm","Shield","Gauntlets","Boots","Cape","Potion","Scroll","Orb","Talisman","Scepter","Lance","Crossbow","Grimoire","Crystal","Charm","Pendant","Totem","Bracer","Mask","Crown","Belt","Gemstone","Lantern"]; |
121 | 86 |
|
| 87 | +let enemies = []; |
| 88 | + |
122 | 89 | function generateEnemy(){ |
123 | 90 | const isBoss=Math.random()<0.05; |
124 | 91 | const type=randomChoice(types); |
@@ -160,26 +127,44 @@ <h1>🔥 Compact Random Enemy Generator ⚔️</h1> |
160 | 127 | container.style.animation=`fadeIn 0.4s ease forwards, floatEnemy 1.5s ease-in-out infinite alternate`; |
161 | 128 | container.className=`enemy ${enemy.strengthElement.name.toLowerCase()}`+(enemy.isBoss?' boss':''); |
162 | 129 | container.innerHTML=` |
163 | | - <div class="elementalEffect ${enemy.strengthElement.name.toLowerCase()}"></div> |
164 | 130 | <strong>${enemy.name}</strong> (${enemy.type.emoji} ${enemy.type.name})<br> |
165 | 131 | ❤️ ${enemy.hp} | 🔵 ${enemy.mp}<br> |
166 | 132 | 💪 ${enemy.strength} | 🏃 ${enemy.dexterity} | 🧠 ${enemy.intelligence}<br> |
167 | 133 | 🛡️ ${enemy.defense} | ✨ ${enemy.resistance} | ⚡ ${enemy.speed} | 🍀 ${enemy.luck}<br> |
168 | | - ⚡ <span class="${enemy.strengthElement.name.toLowerCase()}">${enemy.strengthElement.emoji} ${enemy.strengthElement.name}</span> | |
169 | | - ❌ <span class="${enemy.weakness.name.toLowerCase()}">${enemy.weakness.emoji} ${enemy.weakness.name}</span><br> |
| 134 | + ⚡ <span>${enemy.strengthElement.emoji} ${enemy.strengthElement.name}</span> | |
| 135 | + ❌ <span>${enemy.weakness.emoji} ${enemy.weakness.name}</span><br> |
170 | 136 | 🎁 <span class="loot ${enemy.loot.rarity.class}">${enemy.loot.rarity.name} ${enemy.loot.element.emoji} ${enemy.loot.element.name} ${enemy.loot.item}</span> |
171 | 137 | `; |
172 | 138 | document.getElementById('enemyList').prepend(container); |
173 | | - createDriftSparkles(container,enemy.strengthElement.color,12); |
174 | | - if(enemy.isBoss) createDriftSparkles(container,'#ffd700',12); |
175 | | - if(['legendary','mythic','divine'].includes(enemy.loot.rarity.class)){ |
176 | | - const lootElem=container.querySelector('.loot'); |
177 | | - createDriftSparkles(lootElem,'#fbc02d',12); |
178 | | - } |
| 139 | + createDriftSparkles(container,enemy.strengthElement.color,10); |
| 140 | + if(enemy.isBoss) createDriftSparkles(container,'#ffd700',10); |
179 | 141 | } |
180 | 142 |
|
181 | | -document.getElementById('generate').addEventListener('click',()=>displayEnemy(generateEnemy())); |
182 | | -document.getElementById('clear').addEventListener('click',()=>document.getElementById('enemyList').innerHTML=''); |
| 143 | +document.getElementById('generate').addEventListener('click',()=>{ |
| 144 | + const enemy = generateEnemy(); |
| 145 | + enemies.push(enemy); |
| 146 | + displayEnemy(enemy); |
| 147 | +}); |
| 148 | + |
| 149 | +document.getElementById('clear').addEventListener('click',()=>{ |
| 150 | + document.getElementById('enemyList').innerHTML=''; |
| 151 | + enemies = []; |
| 152 | +}); |
| 153 | + |
| 154 | +// 💾 Save to JSON file |
| 155 | +document.getElementById('save').addEventListener('click',()=>{ |
| 156 | + if(enemies.length===0){ |
| 157 | + alert('No enemies to save!'); |
| 158 | + return; |
| 159 | + } |
| 160 | + const blob = new Blob([JSON.stringify(enemies,null,2)],{type:'application/json'}); |
| 161 | + const url = URL.createObjectURL(blob); |
| 162 | + const a = document.createElement('a'); |
| 163 | + a.href = url; |
| 164 | + a.download = 'enemies.json'; |
| 165 | + a.click(); |
| 166 | + URL.revokeObjectURL(url); |
| 167 | +}); |
183 | 168 | </script> |
184 | 169 | </body> |
185 | 170 | </html> |
0 commit comments