openfree commited on
Commit
612b3da
·
verified ·
1 Parent(s): 2fa2170

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +719 -19
index.html CHANGED
@@ -1,19 +1,719 @@
1
- <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width" />
6
- <title>My static Space</title>
7
- <link rel="stylesheet" href="style.css" />
8
- </head>
9
- <body>
10
- <div class="card">
11
- <h1>Welcome to your static Space!</h1>
12
- <p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
13
- <p>
14
- Also don't forget to check the
15
- <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
16
- </p>
17
- </div>
18
- </body>
19
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Ethereal Workshop Battle Royale</title>
7
+ <style>
8
+ * {
9
+ margin: 0;
10
+ padding: 0;
11
+ box-sizing: border-box;
12
+ }
13
+
14
+ body {
15
+ font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
16
+ background-color: #0a0a1a;
17
+ color: #fff;
18
+ overflow-x: hidden;
19
+ }
20
+
21
+ .game-container {
22
+ width: 100%;
23
+ max-width: 1200px;
24
+ margin: 0 auto;
25
+ padding: 20px;
26
+ }
27
+
28
+ h1 {
29
+ text-align: center;
30
+ margin-bottom: 20px;
31
+ font-size: 2.5rem;
32
+ color: #c9a0ff;
33
+ text-shadow: 0 0 10px rgba(201, 160, 255, 0.6);
34
+ }
35
+
36
+ .subtitle {
37
+ text-align: center;
38
+ margin-bottom: 30px;
39
+ font-size: 1.2rem;
40
+ color: #8a7aa9;
41
+ }
42
+
43
+ .battle-arena {
44
+ position: relative;
45
+ width: 100%;
46
+ height: 600px;
47
+ background-image: url('https://static.wikia.nocookie.net/mysingingmonsters/images/4/4b/Ethereal_Workshop_Empty.png');
48
+ background-size: cover;
49
+ background-position: center;
50
+ border-radius: 12px;
51
+ margin-bottom: 30px;
52
+ box-shadow: 0 5px 25px rgba(201, 160, 255, 0.3);
53
+ overflow: hidden;
54
+ }
55
+
56
+ .monster {
57
+ position: absolute;
58
+ width: 100px;
59
+ height: 100px;
60
+ background-size: contain;
61
+ background-repeat: no-repeat;
62
+ background-position: center;
63
+ transition: all 0.3s ease;
64
+ filter: drop-shadow(0 0 8px rgba(201, 160, 255, 0.7));
65
+ z-index: 5;
66
+ cursor: pointer;
67
+ }
68
+
69
+ .monster.attacking {
70
+ filter: drop-shadow(0 0 15px rgba(255, 86, 86, 0.9));
71
+ transform: scale(1.2);
72
+ }
73
+
74
+ .monster.damaged {
75
+ filter: drop-shadow(0 0 15px rgba(255, 0, 0, 0.9));
76
+ opacity: 0.7;
77
+ }
78
+
79
+ .monster.eliminated {
80
+ opacity: 0.3;
81
+ filter: grayscale(100%);
82
+ pointer-events: none;
83
+ }
84
+
85
+ .sword {
86
+ position: absolute;
87
+ width: 40px;
88
+ height: 40px;
89
+ background-size: contain;
90
+ background-repeat: no-repeat;
91
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23c9a0ff'%3E%3Cpath d='M14.5,15.88L19.64,21L21,19.64L15.89,14.5L16.24,14.16L21.7,9.5L19.84,7.64L14.28,13.19L13.93,13.54L13.59,13.19L8.7,8.3L11.24,5.76L7.45,2L2,7.45L5.82,11.27L8.3,8.79L13.54,14.04L13.19,14.39L7.64,19.93L9.5,21.8L14.16,17.13L14.5,16.79V15.88Z'/%3E%3C/svg%3E");
92
+ transform: rotate(45deg);
93
+ opacity: 0;
94
+ z-index: 4;
95
+ transition: opacity 0.2s;
96
+ }
97
+
98
+ .health-bar-container {
99
+ position: absolute;
100
+ bottom: -15px;
101
+ left: 50%;
102
+ transform: translateX(-50%);
103
+ width: 80px;
104
+ height: 10px;
105
+ background-color: rgba(0, 0, 0, 0.5);
106
+ border-radius: 5px;
107
+ overflow: hidden;
108
+ }
109
+
110
+ .health-bar {
111
+ height: 100%;
112
+ width: 100%;
113
+ background-color: #2ecc71;
114
+ transition: width 0.3s ease;
115
+ }
116
+
117
+ .battle-log {
118
+ background-color: rgba(20, 20, 40, 0.8);
119
+ border-radius: 8px;
120
+ padding: 15px;
121
+ max-height: 200px;
122
+ overflow-y: auto;
123
+ border: 1px solid rgba(201, 160, 255, 0.3);
124
+ }
125
+
126
+ .log-entry {
127
+ margin-bottom: 8px;
128
+ padding-bottom: 8px;
129
+ border-bottom: 1px solid rgba(201, 160, 255, 0.2);
130
+ font-size: 14px;
131
+ }
132
+
133
+ .controls {
134
+ display: flex;
135
+ justify-content: center;
136
+ margin-top: 20px;
137
+ gap: 15px;
138
+ }
139
+
140
+ button {
141
+ background-color: #7851a9;
142
+ color: white;
143
+ border: none;
144
+ padding: 10px 20px;
145
+ border-radius: 5px;
146
+ cursor: pointer;
147
+ font-size: 16px;
148
+ transition: all 0.3s ease;
149
+ }
150
+
151
+ button:hover {
152
+ background-color: #9d71cf;
153
+ transform: translateY(-2px);
154
+ box-shadow: 0 5px 15px rgba(157, 113, 207, 0.4);
155
+ }
156
+
157
+ button:disabled {
158
+ background-color: #4a3863;
159
+ cursor: not-allowed;
160
+ transform: none;
161
+ box-shadow: none;
162
+ }
163
+
164
+ .winner-display {
165
+ display: none;
166
+ position: absolute;
167
+ top: 50%;
168
+ left: 50%;
169
+ transform: translate(-50%, -50%);
170
+ background-color: rgba(20, 20, 40, 0.9);
171
+ padding: 20px;
172
+ border-radius: 10px;
173
+ text-align: center;
174
+ z-index: 100;
175
+ box-shadow: 0 0 30px rgba(201, 160, 255, 0.8);
176
+ animation: pulse 2s infinite;
177
+ }
178
+
179
+ .winner-display h2 {
180
+ color: #c9a0ff;
181
+ margin-bottom: 10px;
182
+ }
183
+
184
+ .winner-display .winner-img {
185
+ width: 150px;
186
+ height: 150px;
187
+ margin: 0 auto;
188
+ background-size: contain;
189
+ background-repeat: no-repeat;
190
+ background-position: center;
191
+ filter: drop-shadow(0 0 15px rgba(201, 160, 255, 0.9));
192
+ }
193
+
194
+ @keyframes pulse {
195
+ 0% { box-shadow: 0 0 30px rgba(201, 160, 255, 0.6); }
196
+ 50% { box-shadow: 0 0 30px rgba(201, 160, 255, 1); }
197
+ 100% { box-shadow: 0 0 30px rgba(201, 160, 255, 0.6); }
198
+ }
199
+
200
+ .sparks {
201
+ position: absolute;
202
+ width: 5px;
203
+ height: 5px;
204
+ background-color: #ffeb3b;
205
+ border-radius: 50%;
206
+ z-index: 10;
207
+ box-shadow: 0 0 10px #ff9800;
208
+ opacity: 0;
209
+ }
210
+
211
+ .immunity-badge {
212
+ position: absolute;
213
+ top: -25px;
214
+ left: 50%;
215
+ transform: translateX(-50%);
216
+ background-color: gold;
217
+ color: #333;
218
+ font-size: 10px;
219
+ font-weight: bold;
220
+ padding: 3px 6px;
221
+ border-radius: 10px;
222
+ display: none;
223
+ }
224
+
225
+ @media (max-width: 768px) {
226
+ .battle-arena {
227
+ height: 400px;
228
+ }
229
+
230
+ .monster {
231
+ width: 80px;
232
+ height: 80px;
233
+ }
234
+ }
235
+
236
+ @media (max-width: 480px) {
237
+ h1 {
238
+ font-size: 1.8rem;
239
+ }
240
+
241
+ .battle-arena {
242
+ height: 300px;
243
+ }
244
+
245
+ .monster {
246
+ width: 60px;
247
+ height: 60px;
248
+ }
249
+ }
250
+ </style>
251
+ </head>
252
+ <body>
253
+ <div class="game-container">
254
+ <h1>Ethereal Workshop Battle Royale</h1>
255
+ <p class="subtitle">Last ethereal standing wins immunity! Click Start Battle to begin.</p>
256
+
257
+ <div class="battle-arena" id="arena">
258
+ <!-- Monsters will be added here by JavaScript -->
259
+
260
+ <div class="winner-display" id="winnerDisplay">
261
+ <h2>WINNER!</h2>
262
+ <div class="winner-img" id="winnerImg"></div>
263
+ <p>has won immunity!</p>
264
+ </div>
265
+ </div>
266
+
267
+ <div class="battle-log" id="battleLog">
268
+ <div class="log-entry">Welcome to the Ethereal Workshop Battle Royale! Click the Start Battle button to begin.</div>
269
+ </div>
270
+
271
+ <div class="controls">
272
+ <button id="startButton">Start Battle</button>
273
+ <button id="resetButton" disabled>Reset Battle</button>
274
+ </div>
275
+ </div>
276
+
277
+ <script>
278
+ document.addEventListener('DOMContentLoaded', function() {
279
+ // Define monsters
280
+ const monsters = [
281
+ {
282
+ name: "Yooreek",
283
+ image: "https://static.wikia.nocookie.net/mysingingmonsters/images/1/13/Yooreek.png",
284
+ health: 100,
285
+ power: 25,
286
+ speed: 4,
287
+ eliminated: false,
288
+ position: { x: 10, y: 50 }
289
+ },
290
+ {
291
+ name: "Meebkin",
292
+ image: "https://static.wikia.nocookie.net/mysingingmonsters/images/f/f1/Meebkin.png",
293
+ health: 100,
294
+ power: 20,
295
+ speed: 5,
296
+ eliminated: false,
297
+ position: { x: 30, y: 60 }
298
+ },
299
+ {
300
+ name: "Blarret",
301
+ image: "https://static.wikia.nocookie.net/mysingingmonsters/images/9/93/Blarret.png",
302
+ health: 100,
303
+ power: 30,
304
+ speed: 3,
305
+ eliminated: false,
306
+ position: { x: 50, y: 30 }
307
+ },
308
+ {
309
+ name: "Gaddzooks",
310
+ image: "https://static.wikia.nocookie.net/mysingingmonsters/images/f/f3/Gaddzooks.png",
311
+ health: 100,
312
+ power: 15,
313
+ speed: 6,
314
+ eliminated: false,
315
+ position: { x: 70, y: 40 }
316
+ },
317
+ {
318
+ name: "Auglur",
319
+ image: "https://static.wikia.nocookie.net/mysingingmonsters/images/d/db/Auglur.png",
320
+ health: 100,
321
+ power: 35,
322
+ speed: 2,
323
+ eliminated: false,
324
+ position: { x: 85, y: 70 }
325
+ }
326
+ ];
327
+
328
+ const arena = document.getElementById('arena');
329
+ const battleLog = document.getElementById('battleLog');
330
+ const startButton = document.getElementById('startButton');
331
+ const resetButton = document.getElementById('resetButton');
332
+ const winnerDisplay = document.getElementById('winnerDisplay');
333
+ const winnerImg = document.getElementById('winnerImg');
334
+
335
+ let battleInProgress = false;
336
+ let monsterElements = [];
337
+ let battleInterval;
338
+ let animationFrameId;
339
+
340
+ // Initialize the battle arena
341
+ function initializeBattle() {
342
+ // Reset monsters
343
+ monsters.forEach(monster => {
344
+ monster.health = 100;
345
+ monster.eliminated = false;
346
+ });
347
+
348
+ // Clear arena
349
+ arena.innerHTML = '';
350
+ monsterElements = [];
351
+
352
+ // Hide winner display
353
+ winnerDisplay.style.display = 'none';
354
+
355
+ // Add monster elements to arena
356
+ monsters.forEach((monster, index) => {
357
+ const monsterElement = document.createElement('div');
358
+ monsterElement.className = 'monster';
359
+ monsterElement.id = `monster-${index}`;
360
+ monsterElement.style.backgroundImage = `url(${monster.image})`;
361
+ monsterElement.style.left = `${monster.position.x}%`;
362
+ monsterElement.style.top = `${monster.position.y}%`;
363
+
364
+ // Add health bar
365
+ const healthBarContainer = document.createElement('div');
366
+ healthBarContainer.className = 'health-bar-container';
367
+
368
+ const healthBar = document.createElement('div');
369
+ healthBar.className = 'health-bar';
370
+ healthBarContainer.appendChild(healthBar);
371
+
372
+ // Add immunity badge
373
+ const immunityBadge = document.createElement('div');
374
+ immunityBadge.className = 'immunity-badge';
375
+ immunityBadge.textContent = 'IMMUNE';
376
+
377
+ monsterElement.appendChild(healthBarContainer);
378
+ monsterElement.appendChild(immunityBadge);
379
+
380
+ arena.appendChild(monsterElement);
381
+ monsterElements.push(monsterElement);
382
+ });
383
+
384
+ // Add winner display back to arena
385
+ arena.appendChild(winnerDisplay);
386
+
387
+ // Reset battle log
388
+ battleLog.innerHTML = '<div class="log-entry">The battle is about to begin! Ethereal monsters take their positions.</div>';
389
+ }
390
+
391
+ // Update monster health bars
392
+ function updateHealthBars() {
393
+ monsters.forEach((monster, index) => {
394
+ const healthBar = monsterElements[index].querySelector('.health-bar');
395
+ healthBar.style.width = `${monster.health}%`;
396
+
397
+ // Change color based on health
398
+ if (monster.health > 60) {
399
+ healthBar.style.backgroundColor = '#2ecc71';
400
+ } else if (monster.health > 30) {
401
+ healthBar.style.backgroundColor = '#f39c12';
402
+ } else {
403
+ healthBar.style.backgroundColor = '#e74c3c';
404
+ }
405
+ });
406
+ }
407
+
408
+ // Add log entry
409
+ function addLogEntry(text) {
410
+ const entry = document.createElement('div');
411
+ entry.className = 'log-entry';
412
+ entry.textContent = text;
413
+ battleLog.appendChild(entry);
414
+ battleLog.scrollTop = battleLog.scrollHeight;
415
+ }
416
+
417
+ // Create sword attack animation
418
+ function swordAttack(attackerIndex, targetIndex) {
419
+ const attacker = monsterElements[attackerIndex];
420
+ const target = monsterElements[targetIndex];
421
+
422
+ // Get positions
423
+ const attackerRect = attacker.getBoundingClientRect();
424
+ const targetRect = target.getBoundingClientRect();
425
+ const arenaRect = arena.getBoundingClientRect();
426
+
427
+ // Create sword
428
+ const sword = document.createElement('div');
429
+ sword.className = 'sword';
430
+ sword.style.left = `${(attackerRect.left + attackerRect.width/2) - arenaRect.left}px`;
431
+ sword.style.top = `${(attackerRect.top + attackerRect.height/2) - arenaRect.top}px`;
432
+ arena.appendChild(sword);
433
+
434
+ // Show sword
435
+ setTimeout(() => { sword.style.opacity = '1'; }, 10);
436
+
437
+ // Animate sword to target
438
+ const targetX = (targetRect.left + targetRect.width/2) - arenaRect.left;
439
+ const targetY = (targetRect.top + targetRect.height/2) - arenaRect.top;
440
+
441
+ let progress = 0;
442
+ const startX = parseFloat(sword.style.left);
443
+ const startY = parseFloat(sword.style.top);
444
+
445
+ function animateSword() {
446
+ progress += 0.05;
447
+
448
+ if (progress >= 1) {
449
+ sword.style.opacity = '0';
450
+
451
+ // Create sparks at impact
452
+ createSparks(targetX, targetY);
453
+
454
+ // Add damaged class to target
455
+ target.classList.add('damaged');
456
+ setTimeout(() => {
457
+ target.classList.remove('damaged');
458
+ }, 300);
459
+
460
+ // Remove sword after animation
461
+ setTimeout(() => {
462
+ sword.remove();
463
+ }, 200);
464
+
465
+ return;
466
+ }
467
+
468
+ const currentX = startX + (targetX - startX) * progress;
469
+ const currentY = startY + (targetY - startY) * progress;
470
+
471
+ sword.style.left = `${currentX}px`;
472
+ sword.style.top = `${currentY}px`;
473
+
474
+ requestAnimationFrame(animateSword);
475
+ }
476
+
477
+ requestAnimationFrame(animateSword);
478
+ }
479
+
480
+ // Create spark effects
481
+ function createSparks(x, y) {
482
+ for (let i = 0; i < 15; i++) {
483
+ const spark = document.createElement('div');
484
+ spark.className = 'sparks';
485
+ spark.style.left = `${x}px`;
486
+ spark.style.top = `${y}px`;
487
+ arena.appendChild(spark);
488
+
489
+ // Random direction and speed
490
+ const angle = Math.random() * Math.PI * 2;
491
+ const speed = 2 + Math.random() * 3;
492
+ const distance = 30 + Math.random() * 40;
493
+
494
+ // Set initial properties
495
+ spark.style.opacity = '1';
496
+
497
+ // Animate the spark
498
+ let progress = 0;
499
+ const startX = x;
500
+ const startY = y;
501
+
502
+ function animateSpark() {
503
+ progress += 0.03;
504
+
505
+ if (progress >= 1) {
506
+ spark.remove();
507
+ return;
508
+ }
509
+
510
+ const currentX = startX + Math.cos(angle) * distance * progress;
511
+ const currentY = startY + Math.sin(angle) * distance * progress;
512
+
513
+ spark.style.left = `${currentX}px`;
514
+ spark.style.top = `${currentY}px`;
515
+ spark.style.opacity = 1 - progress;
516
+
517
+ requestAnimationFrame(animateSpark);
518
+ }
519
+
520
+ requestAnimationFrame(animateSpark);
521
+ }
522
+ }
523
+
524
+ // Find nearest target
525
+ function findNearestTarget(attacker) {
526
+ let nearestTarget = -1;
527
+ let minDistance = Infinity;
528
+
529
+ for (let i = 0; i < monsters.length; i++) {
530
+ if (i !== attacker && !monsters[i].eliminated) {
531
+ const distance = Math.sqrt(
532
+ Math.pow(monsters[attacker].position.x - monsters[i].position.x, 2) +
533
+ Math.pow(monsters[attacker].position.y - monsters[i].position.y, 2)
534
+ );
535
+
536
+ if (distance < minDistance) {
537
+ minDistance = distance;
538
+ nearestTarget = i;
539
+ }
540
+ }
541
+ }
542
+
543
+ return nearestTarget;
544
+ }
545
+
546
+ // Move towards target
547
+ function moveTowardsTarget(attackerIndex, targetIndex) {
548
+ const attacker = monsters[attackerIndex];
549
+ const target = monsters[targetIndex];
550
+
551
+ // Calculate direction
552
+ const dx = target.position.x - attacker.position.x;
553
+ const dy = target.position.y - attacker.position.y;
554
+ const distance = Math.sqrt(dx * dx + dy * dy);
555
+
556
+ if (distance > 10) { // Only move if not close enough
557
+ // Normalize direction and scale by speed
558
+ const moveX = (dx / distance) * (attacker.speed * 0.5);
559
+ const moveY = (dy / distance) * (attacker.speed * 0.5);
560
+
561
+ // Update position
562
+ attacker.position.x += moveX;
563
+ attacker.position.y += moveY;
564
+
565
+ // Keep within bounds
566
+ attacker.position.x = Math.max(0, Math.min(90, attacker.position.x));
567
+ attacker.position.y = Math.max(0, Math.min(85, attacker.position.y));
568
+
569
+ // Update element position
570
+ monsterElements[attackerIndex].style.left = `${attacker.position.x}%`;
571
+ monsterElements[attackerIndex].style.top = `${attacker.position.y}%`;
572
+ }
573
+
574
+ return distance <= 15; // Return true if close enough to attack
575
+ }
576
+
577
+ // Perform battle round
578
+ function battleRound() {
579
+ // Check for battle end
580
+ let activeMonstersCount = 0;
581
+ let lastStanding = -1;
582
+
583
+ monsters.forEach((monster, index) => {
584
+ if (!monster.eliminated) {
585
+ activeMonstersCount++;
586
+ lastStanding = index;
587
+ }
588
+ });
589
+
590
+ if (activeMonstersCount <= 1) {
591
+ endBattle(lastStanding);
592
+ return;
593
+ }
594
+
595
+ // Process each monster's turn
596
+ monsters.forEach((monster, attackerIndex) => {
597
+ if (monster.eliminated) return;
598
+
599
+ // Find target
600
+ const targetIndex = findNearestTarget(attackerIndex);
601
+ if (targetIndex === -1) return;
602
+
603
+ // Try to move closer to target
604
+ const canAttack = moveTowardsTarget(attackerIndex, targetIndex);
605
+
606
+ if (canAttack) {
607
+ // Chance to attack based on speed
608
+ if (Math.random() < monster.speed / 10) {
609
+ // Add attacking class
610
+ monsterElements[attackerIndex].classList.add('attacking');
611
+
612
+ // Calculate damage with some randomness
613
+ const baseDamage = monster.power;
614
+ const randomFactor = 0.8 + Math.random() * 0.4; // 0.8 to 1.2
615
+ const damage = Math.round(baseDamage * randomFactor);
616
+
617
+ // Apply damage
618
+ monsters[targetIndex].health -= damage;
619
+ monsters[targetIndex].health = Math.max(0, monsters[targetIndex].health);
620
+
621
+ // Update health bars
622
+ updateHealthBars();
623
+
624
+ // Create sword attack animation
625
+ swordAttack(attackerIndex, targetIndex);
626
+
627
+ // Log the attack
628
+ addLogEntry(`${monster.name} attacks ${monsters[targetIndex].name} for ${damage} damage!`);
629
+
630
+ // Check if target is eliminated
631
+ if (monsters[targetIndex].health <= 0 && !monsters[targetIndex].eliminated) {
632
+ monsters[targetIndex].eliminated = true;
633
+ monsterElements[targetIndex].classList.add('eliminated');
634
+ addLogEntry(`${monsters[targetIndex].name} has been eliminated from the battle!`);
635
+ }
636
+
637
+ // Remove attacking class after a delay
638
+ setTimeout(() => {
639
+ monsterElements[attackerIndex].classList.remove('attacking');
640
+ }, 300);
641
+ }
642
+ }
643
+ });
644
+ }
645
+
646
+ // Start the battle
647
+ function startBattle() {
648
+ if (battleInProgress) return;
649
+
650
+ battleInProgress = true;
651
+ startButton.disabled = true;
652
+ resetButton.disabled = false;
653
+
654
+ addLogEntry("The battle has begun! Ethereal monsters are fighting for immunity!");
655
+
656
+ // Run battle rounds at intervals
657
+ battleInterval = setInterval(() => {
658
+ battleRound();
659
+ }, 1000);
660
+
661
+ // Start animation loop
662
+ function animationLoop() {
663
+ if (!battleInProgress) return;
664
+
665
+ // Any continuous animations can go here
666
+
667
+ animationFrameId = requestAnimationFrame(animationLoop);
668
+ }
669
+
670
+ animationLoop();
671
+ }
672
+
673
+ // End the battle
674
+ function endBattle(winnerIndex) {
675
+ battleInProgress = false;
676
+ clearInterval(battleInterval);
677
+ cancelAnimationFrame(animationFrameId);
678
+
679
+ // Display winner
680
+ if (winnerIndex >= 0) {
681
+ const winner = monsters[winnerIndex];
682
+ addLogEntry(`${winner.name} is the last ethereal standing and has won immunity!`);
683
+
684
+ // Show winner banner
685
+ winnerImg.style.backgroundImage = `url(${winner.image})`;
686
+ winnerDisplay.style.display = 'block';
687
+
688
+ // Show immunity badge
689
+ const immunityBadge = monsterElements[winnerIndex].querySelector('.immunity-badge');
690
+ immunityBadge.style.display = 'block';
691
+ } else {
692
+ addLogEntry("The battle has ended in a draw!");
693
+ }
694
+
695
+ resetButton.disabled = false;
696
+ }
697
+
698
+ // Reset the battle
699
+ function resetBattle() {
700
+ battleInProgress = false;
701
+ clearInterval(battleInterval);
702
+ cancelAnimationFrame(animationFrameId);
703
+
704
+ startButton.disabled = false;
705
+ resetButton.disabled = true;
706
+
707
+ initializeBattle();
708
+ }
709
+
710
+ // Event listeners
711
+ startButton.addEventListener('click', startBattle);
712
+ resetButton.addEventListener('click', resetBattle);
713
+
714
+ // Initialize the battle arena on load
715
+ initializeBattle();
716
+ });
717
+ </script>
718
+ </body>
719
+ </html>