sdurdiyev commited on
Commit
f4f6626
·
verified ·
1 Parent(s): 735160d

Add 2 files

Browse files
Files changed (2) hide show
  1. index.html +1240 -271
  2. prompts.txt +3 -1
index.html CHANGED
@@ -3,408 +3,1169 @@
3
  <head>
4
  <meta charset="UTF-8">
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>100 Men vs 1 Gorilla</title>
7
  <script src="https://cdn.tailwindcss.com"></script>
8
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
 
9
  <style>
10
- @keyframes menAttack {
11
- 0% { transform: translateX(0); }
12
- 50% { transform: translateX(-10px); }
13
- 100% { transform: translateX(0); }
14
  }
15
 
16
- @keyframes gorillaAttack {
17
- 0% { transform: scale(1); }
18
- 50% { transform: scale(1.1); }
19
- 100% { transform: scale(1); }
20
  }
21
 
22
- @keyframes manDie {
23
- 0% { opacity: 1; transform: translateY(0) rotate(0deg); }
24
- 100% { opacity: 0; transform: translateY(100px) rotate(360deg); }
25
  }
26
 
27
- .men-attack {
28
- animation: menAttack 0.5s infinite;
 
29
  }
30
 
31
- .gorilla-attack {
32
- animation: gorillaAttack 0.3s infinite;
33
- }
34
-
35
- .man-die {
36
- animation: manDie 1s forwards;
37
- }
38
-
39
- .progress-bar {
40
- transition: width 0.3s ease;
41
  }
42
 
43
  .battlefield {
44
- background-image: linear-gradient(to bottom, #4a7c59, #3a5a40);
45
- position: relative;
46
- overflow: hidden;
 
 
 
 
 
47
  }
48
 
49
  .man {
50
- width: 20px;
51
- height: 20px;
52
  background-color: #588157;
53
  border-radius: 50%;
54
  position: absolute;
 
 
 
 
55
  transition: all 0.3s ease;
 
 
 
 
 
 
 
 
56
  }
57
 
58
  .gorilla {
59
- width: 60px;
60
- height: 60px;
61
- background-color: #3a5a40;
62
  border-radius: 50%;
63
  position: absolute;
64
- right: 50px;
65
- top: 50%;
66
- transform: translateY(-50%);
 
 
 
 
 
 
 
 
 
67
  }
68
 
69
  .blood {
70
  position: absolute;
71
- width: 10px;
72
- height: 10px;
73
- background-color: red;
74
  border-radius: 50%;
75
- opacity: 0.7;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
76
  }
77
  </style>
78
  </head>
79
- <body class="bg-gray-100 min-h-screen flex flex-col items-center justify-center p-4">
80
- <div class="max-w-4xl w-full bg-white rounded-xl shadow-xl overflow-hidden">
81
- <div class="bg-green-800 text-white p-4">
82
- <h1 class="text-3xl font-bold text-center">100 Men vs 1 Gorilla</h1>
83
- <p class="text-center text-green-200">Who will win this epic battle?</p>
84
  </div>
85
 
86
  <div class="p-6">
87
- <div class="flex justify-between items-center mb-4">
88
- <div class="text-center">
89
- <div class="text-xl font-bold text-green-800">100 Men</div>
90
- <div class="text-sm text-gray-600">Strength in numbers</div>
91
- </div>
92
- <div class="text-center">
93
- <div class="text-4xl font-bold text-red-600 animate-pulse">VS</div>
94
- </div>
95
- <div class="text-center">
96
- <div class="text-xl font-bold text-gray-800">1 Gorilla</div>
97
- <div class="text-sm text-gray-600">Raw power</div>
98
- </div>
99
- </div>
100
-
101
- <div class="battlefield h-64 rounded-lg mb-6 relative" id="battlefield">
102
- <!-- Battle elements will be added here by JavaScript -->
103
- </div>
104
-
105
- <div class="grid grid-cols-2 gap-4 mb-6">
106
- <div>
107
- <div class="flex justify-between mb-1">
108
- <span class="text-sm font-medium text-green-800">Men Health</span>
109
- <span class="text-sm font-medium text-green-800" id="men-count">100</span>
110
  </div>
111
- <div class="w-full bg-gray-200 rounded-full h-2.5">
112
- <div class="bg-green-600 h-2.5 rounded-full progress-bar" id="men-health" style="width: 100%"></div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
113
  </div>
114
  </div>
115
- <div>
116
- <div class="flex justify-between mb-1">
117
- <span class="text-sm font-medium text-gray-800">Gorilla Health</span>
118
- <span class="text-sm font-medium text-gray-800" id="gorilla-health-text">100</span>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
119
  </div>
120
- <div class="w-full bg-gray-200 rounded-full h-2.5">
121
- <div class="bg-gray-800 h-2.5 rounded-full progress-bar" id="gorilla-health" style="width: 100%"></div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
122
  </div>
123
  </div>
124
  </div>
125
 
126
- <div class="flex flex-col sm:flex-row gap-4">
127
- <button id="start-battle" class="flex-1 bg-red-600 hover:bg-red-700 text-white font-bold py-3 px-4 rounded-lg transition flex items-center justify-center gap-2">
128
- <i class="fas fa-fist-raised"></i> Start Battle
129
- </button>
130
- <button id="auto-battle" class="flex-1 bg-yellow-600 hover:bg-yellow-700 text-white font-bold py-3 px-4 rounded-lg transition flex items-center justify-center gap-2">
131
- <i class="fas fa-robot"></i> Auto Battle
132
- </button>
133
- <button id="reset" class="flex-1 bg-gray-600 hover:bg-gray-700 text-white font-bold py-3 px-4 rounded-lg transition flex items-center justify-center gap-2">
134
- <i class="fas fa-redo"></i> Reset
135
- </button>
136
- </div>
137
-
138
- <div class="mt-6 bg-blue-50 p-4 rounded-lg">
139
- <h3 class="font-bold text-blue-800 mb-2">Battle Stats:</h3>
140
- <div class="grid grid-cols-2 gap-4">
141
- <div>
142
- <p class="text-sm"><span class="font-semibold">Men Killed:</span> <span id="men-killed">0</span></p>
143
- <p class="text-sm"><span class="font-semibold">Gorilla Damage:</span> <span id="gorilla-damage">0</span>%</p>
144
  </div>
145
- <div>
146
- <p class="text-sm"><span class="font-semibold">Battle Time:</span> <span id="battle-time">0</span>s</p>
147
- <p class="text-sm"><span class="font-semibold">Winner:</span> <span id="winner">-</span></p>
 
 
 
 
148
  </div>
149
  </div>
150
  </div>
151
  </div>
152
  </div>
153
-
154
- <div class="mt-6 text-center text-gray-600 max-w-2xl">
155
- <p class="mb-2">Gorillas are incredibly strong - an adult male gorilla can be up to 10 times stronger than an average human!</p>
156
- <p>But can 100 men working together overcome this strength advantage?</p>
157
- </div>
158
 
159
  <script>
160
  // Game variables
161
- let menCount = 100;
162
- let gorillaHealth = 100;
163
- let battleActive = false;
164
- let autoBattleInterval;
165
- let battleTime = 0;
166
- let battleTimer;
167
- let menKilled = 0;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
168
 
169
  // DOM elements
170
  const battlefield = document.getElementById('battlefield');
 
 
 
171
  const startBattleBtn = document.getElementById('start-battle');
172
  const autoBattleBtn = document.getElementById('auto-battle');
173
  const resetBtn = document.getElementById('reset');
174
- const menCountElement = document.getElementById('men-count');
175
- const menHealthElement = document.getElementById('men-health');
176
- const gorillaHealthElement = document.getElementById('gorilla-health');
177
- const gorillaHealthText = document.getElementById('gorilla-health-text');
178
- const menKilledElement = document.getElementById('men-killed');
179
- const gorillaDamageElement = document.getElementById('gorilla-damage');
180
- const battleTimeElement = document.getElementById('battle-time');
181
- const winnerElement = document.getElementById('winner');
182
-
183
- // Initialize battlefield
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
184
  function initializeBattlefield() {
185
- battlefield.innerHTML = '';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
186
 
187
  // Create gorilla
188
- const gorilla = document.createElement('div');
189
- gorilla.className = 'gorilla flex items-center justify-center';
190
- gorilla.innerHTML = '<i class="fas fa-paw text-white text-2xl"></i>';
191
- gorilla.id = 'gorilla';
192
- battlefield.appendChild(gorilla);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
193
 
194
  // Create men
195
- for (let i = 0; i < menCount; i++) {
196
  createMan(i);
197
  }
 
 
 
 
 
 
198
  }
199
 
200
- // Create a single man
201
  function createMan(index) {
202
- const man = document.createElement('div');
203
- man.className = 'man flex items-center justify-center';
204
- man.innerHTML = '<i class="fas fa-male text-white text-xs"></i>';
205
- man.id = `man-${index}`;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
206
 
207
- // Random position on the left side
208
- const left = 20 + Math.random() * 40;
209
- const top = 20 + Math.random() * (battlefield.offsetHeight - 40);
210
 
211
- man.style.left = `${left}px`;
212
- man.style.top = `${top}px`;
213
 
214
- battlefield.appendChild(man);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
215
  }
216
 
217
  // Start battle
218
  function startBattle() {
219
- if (battleActive) return;
 
 
 
 
 
220
 
221
- battleActive = true;
222
  startBattleBtn.disabled = true;
223
  autoBattleBtn.disabled = true;
 
 
224
 
225
- // Start timer
226
- battleTime = 0;
227
- battleTimer = setInterval(() => {
228
- battleTime++;
229
- battleTimeElement.textContent = battleTime;
230
- }, 1000);
231
 
232
- // Gorilla attack
 
 
 
 
 
 
 
 
 
 
 
233
  const gorillaAttackInterval = setInterval(() => {
234
- if (!battleActive || menCount <= 0 || gorillaHealth <= 0) {
235
  clearInterval(gorillaAttackInterval);
236
  return;
237
  }
238
 
239
- // Gorilla attacks
240
- document.getElementById('gorilla').classList.add('gorilla-attack');
 
241
  setTimeout(() => {
242
- document.getElementById('gorilla').classList.remove('gorilla-attack');
243
  }, 300);
244
 
245
- // Kill random men (1-5 per attack)
246
- const menToKill = Math.min(Math.floor(Math.random() * 5) + 1, menCount);
 
 
247
 
248
- for (let i = 0; i < menToKill; i++) {
249
- if (menCount <= 0) break;
250
-
251
- const randomManIndex = Math.floor(Math.random() * menCount);
252
- const manElement = document.getElementById(`man-${randomManIndex}`);
253
 
254
- if (manElement) {
255
- // Show blood effect
256
- const rect = manElement.getBoundingClientRect();
257
- const battlefieldRect = battlefield.getBoundingClientRect();
258
-
259
- const blood = document.createElement('div');
260
- blood.className = 'blood';
261
- blood.style.left = `${rect.left - battlefieldRect.left}px`;
262
- blood.style.top = `${rect.top - battlefieldRect.top}px`;
263
- battlefield.appendChild(blood);
264
-
265
- setTimeout(() => {
266
- blood.remove();
267
- }, 1000);
268
-
269
- // Kill man
270
- manElement.classList.add('man-die');
271
- setTimeout(() => {
272
- manElement.remove();
273
- }, 1000);
274
-
275
- menCount--;
276
- menKilled++;
277
- updateStats();
278
  }
279
  }
280
 
281
- // Men attack back if any are left
282
- if (menCount > 0) {
283
- // Make men attack animation
284
- for (let i = 0; i < menCount; i++) {
285
- const manElement = document.getElementById(`man-${i}`);
286
- if (manElement) {
287
- manElement.classList.add('men-attack');
288
- setTimeout(() => {
289
- manElement.classList.remove('men-attack');
290
- }, 500);
291
- }
292
  }
293
 
294
- // Damage gorilla
295
- const damage = Math.min(Math.random() * 2, gorillaHealth);
296
- gorillaHealth -= damage;
297
- updateStats();
298
 
299
- if (gorillaHealth <= 0) {
300
- gorillaHealth = 0;
301
- endBattle('Men');
302
- }
 
 
 
 
 
 
 
303
  }
304
 
305
- if (menCount <= 0) {
306
- endBattle('Gorilla');
307
- }
308
 
309
- }, 1000);
310
- }
311
-
312
- // Auto battle - fast forward
313
- function autoBattle() {
314
- if (battleActive) return;
315
-
316
- startBattle();
317
 
318
- autoBattleInterval = setInterval(() => {
319
- if (!battleActive) {
320
- clearInterval(autoBattleInterval);
 
321
  return;
322
  }
323
 
324
- // Simulate 5 seconds of battle per iteration
325
- for (let i = 0; i < 5; i++) {
326
- // Gorilla kills men
327
- const menToKill = Math.min(Math.floor(Math.random() * 5) + 1, menCount);
328
- menCount -= menToKill;
329
- menKilled += menToKill;
330
 
331
- // Men damage gorilla if any are left
332
- if (menCount > 0) {
333
- const damage = Math.min(Math.random() * 10, gorillaHealth);
334
- gorillaHealth -= damage;
335
- }
336
-
337
- // Check win conditions
338
- if (gorillaHealth <= 0) {
339
- gorillaHealth = 0;
340
- endBattle('Men');
341
- return;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
342
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
343
 
344
- if (menCount <= 0) {
345
- menCount = 0;
346
- endBattle('Gorilla');
347
- return;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
348
  }
349
  }
350
 
 
 
 
 
 
351
  updateStats();
352
 
353
- }, 100);
354
  }
355
 
356
- // Update stats display
357
- function updateStats() {
358
- menCountElement.textContent = menCount;
359
- menHealthElement.style.width = `${(menCount / 100) * 100}%`;
360
- gorillaHealthElement.style.width = `${gorillaHealth}%`;
361
- gorillaHealthText.textContent = Math.round(gorillaHealth);
362
- menKilledElement.textContent = menKilled;
363
- gorillaDamageElement.textContent = 100 - Math.round(gorillaHealth);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
364
  }
365
 
366
- // End battle
367
- function endBattle(winner) {
368
- battleActive = false;
369
- clearInterval(battleTimer);
370
 
371
- if (autoBattleInterval) {
372
- clearInterval(autoBattleInterval);
 
 
 
 
 
 
 
 
 
 
373
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
374
 
375
- winnerElement.textContent = winner;
376
- winnerElement.className = winner === 'Gorilla' ? 'text-red-600 font-bold' : 'text-green-600 font-bold';
 
 
 
 
 
 
 
 
377
 
378
- // Show celebration
379
- if (winner === 'Men') {
380
- battlefield.style.backgroundImage = 'linear-gradient(to bottom, #4a7c59, #2d6a4f)';
381
- document.getElementById('gorilla').innerHTML = '<i class="fas fa-skull text-white text-2xl"></i>';
382
- } else {
383
- battlefield.style.backgroundImage = 'linear-gradient(to bottom, #3a5a40, #1b4332)';
 
384
  }
385
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
386
  startBattleBtn.disabled = false;
387
  autoBattleBtn.disabled = false;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
388
  }
389
 
390
  // Reset game
391
  function resetGame() {
392
- battleActive = false;
393
- clearInterval(battleTimer);
394
- if (autoBattleInterval) clearInterval(autoBattleInterval);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
395
 
396
- menCount = 100;
397
- gorillaHealth = 100;
398
- menKilled = 0;
399
- battleTime = 0;
400
 
401
- updateStats();
402
  initializeBattlefield();
 
403
 
404
- battlefield.style.backgroundImage = 'linear-gradient(to bottom, #4a7c59, #3a5a40)';
405
- winnerElement.textContent = '-';
406
- winnerElement.className = '';
407
- battleTimeElement.textContent = '0';
 
 
408
 
409
  startBattleBtn.disabled = false;
410
  autoBattleBtn.disabled = false;
@@ -412,11 +1173,219 @@
412
 
413
  // Event listeners
414
  startBattleBtn.addEventListener('click', startBattle);
415
- autoBattleBtn.addEventListener('click', autoBattle);
416
  resetBtn.addEventListener('click', resetGame);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
417
 
418
  // Initialize game
419
- resetGame();
420
  </script>
421
  <p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=sdurdiyev/100menvs1gorilla" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
422
  </html>
 
3
  <head>
4
  <meta charset="UTF-8">
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>100 Men vs 1 Gorilla - Interactive Battle</title>
7
  <script src="https://cdn.tailwindcss.com"></script>
8
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
9
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/matter-js/0.18.0/matter.min.js"></script>
10
  <style>
11
+ @keyframes punch {
12
+ 0% { transform: translateX(0) rotate(0deg); }
13
+ 50% { transform: translateX(-20px) rotate(-10deg); }
14
+ 100% { transform: translateX(0) rotate(0deg); }
15
  }
16
 
17
+ @keyframes gorillaSwing {
18
+ 0% { transform: rotate(0deg); }
19
+ 50% { transform: rotate(30deg); }
20
+ 100% { transform: rotate(0deg); }
21
  }
22
 
23
+ @keyframes bloodSpray {
24
+ 0% { transform: scale(0); opacity: 1; }
25
+ 100% { transform: scale(3); opacity: 0; }
26
  }
27
 
28
+ @keyframes boneBreak {
29
+ 0% { transform: rotate(0deg); }
30
+ 100% { transform: rotate(90deg); }
31
  }
32
 
33
+ .battlefield-container {
34
+ perspective: 1000px;
 
 
 
 
 
 
 
 
35
  }
36
 
37
  .battlefield {
38
+ transform-style: preserve-3d;
39
+ background-image:
40
+ linear-gradient(to bottom, rgba(58, 90, 64, 0.8), rgba(26, 83, 92, 0.9)),
41
+ url('https://images.unsplash.com/photo-1476231682824-37e0bc4606aa?ixlib=rb-1.2.1&auto=format&fit=crop&w=1350&q=80');
42
+ background-size: cover;
43
+ background-position: center;
44
+ box-shadow: inset 0 0 50px rgba(0, 0, 0, 0.7);
45
+ touch-action: none;
46
  }
47
 
48
  .man {
49
+ width: 24px;
50
+ height: 24px;
51
  background-color: #588157;
52
  border-radius: 50%;
53
  position: absolute;
54
+ display: flex;
55
+ align-items: center;
56
+ justify-content: center;
57
+ box-shadow: 0 2px 5px rgba(0, 0, 0, 0.3);
58
  transition: all 0.3s ease;
59
+ z-index: 10;
60
+ cursor: move;
61
+ user-select: none;
62
+ }
63
+
64
+ .man.selected {
65
+ box-shadow: 0 0 0 3px #3b82f6;
66
+ z-index: 30;
67
  }
68
 
69
  .gorilla {
70
+ width: 80px;
71
+ height: 80px;
72
+ background-color: #343a40;
73
  border-radius: 50%;
74
  position: absolute;
75
+ display: flex;
76
+ align-items: center;
77
+ justify-content: center;
78
+ box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5);
79
+ z-index: 20;
80
+ cursor: move;
81
+ user-select: none;
82
+ }
83
+
84
+ .gorilla.selected {
85
+ box-shadow: 0 0 0 5px #3b82f6;
86
+ z-index: 30;
87
  }
88
 
89
  .blood {
90
  position: absolute;
91
+ width: 30px;
92
+ height: 30px;
93
+ background: radial-gradient(circle, rgba(200,0,0,0.8) 0%, rgba(100,0,0,0.5) 70%, transparent 100%);
94
  border-radius: 50%;
95
+ transform-origin: center;
96
+ z-index: 5;
97
+ }
98
+
99
+ .bone {
100
+ position: absolute;
101
+ width: 4px;
102
+ height: 20px;
103
+ background-color: #f8f9fa;
104
+ border-radius: 2px;
105
+ z-index: 15;
106
+ }
107
+
108
+ .weapon {
109
+ position: absolute;
110
+ width: 15px;
111
+ height: 30px;
112
+ background-color: #6c757d;
113
+ border-radius: 2px;
114
+ z-index: 15;
115
+ transform-origin: bottom center;
116
+ }
117
+
118
+ .environment {
119
+ position: absolute;
120
+ background-color: #495057;
121
+ border-radius: 3px;
122
+ z-index: 1;
123
+ }
124
+
125
+ .health-bar {
126
+ position: absolute;
127
+ height: 3px;
128
+ background-color: #dc3545;
129
+ top: -8px;
130
+ left: 0;
131
+ border-radius: 2px;
132
+ transition: width 0.2s ease;
133
+ }
134
+
135
+ .stamina-bar {
136
+ position: absolute;
137
+ height: 2px;
138
+ background-color: #ffc107;
139
+ top: -4px;
140
+ left: 0;
141
+ border-radius: 2px;
142
+ transition: width 0.2s ease;
143
+ }
144
+
145
+ .damage-text {
146
+ position: absolute;
147
+ color: #dc3545;
148
+ font-weight: bold;
149
+ font-size: 12px;
150
+ text-shadow: 0 0 3px black;
151
+ animation: floatUp 1s forwards;
152
+ z-index: 30;
153
+ }
154
+
155
+ @keyframes floatUp {
156
+ 0% { transform: translateY(0); opacity: 1; }
157
+ 100% { transform: translateY(-30px); opacity: 0; }
158
+ }
159
+
160
+ .fear-indicator {
161
+ position: absolute;
162
+ width: 20px;
163
+ height: 20px;
164
+ background-color: rgba(255, 193, 7, 0.3);
165
+ border-radius: 50%;
166
+ border: 2px solid #ffc107;
167
+ top: -25px;
168
+ left: 50%;
169
+ transform: translateX(-50%);
170
+ display: none;
171
+ z-index: 25;
172
+ }
173
+
174
+ .fear-active .fear-indicator {
175
+ display: block;
176
+ animation: pulse 1s infinite;
177
+ }
178
+
179
+ @keyframes pulse {
180
+ 0% { transform: translateX(-50%) scale(1); }
181
+ 50% { transform: translateX(-50%) scale(1.2); }
182
+ 100% { transform: translateX(-50%) scale(1); }
183
+ }
184
+
185
+ .physics-debug {
186
+ position: absolute;
187
+ top: 0;
188
+ left: 0;
189
+ width: 100%;
190
+ height: 100%;
191
+ pointer-events: none;
192
+ z-index: 100;
193
+ }
194
+
195
+ .selection-rectangle {
196
+ position: absolute;
197
+ background-color: rgba(59, 130, 246, 0.3);
198
+ border: 2px solid #3b82f6;
199
+ z-index: 40;
200
+ pointer-events: none;
201
+ display: none;
202
  }
203
  </style>
204
  </head>
205
+ <body class="bg-gray-900 min-h-screen flex flex-col items-center justify-center p-4">
206
+ <div class="max-w-6xl w-full bg-gray-800 rounded-xl shadow-2xl overflow-hidden">
207
+ <div class="bg-gradient-to-r from-gray-900 to-green-900 text-white p-6">
208
+ <h1 class="text-4xl font-bold text-center">100 Men vs 1 Gorilla</h1>
209
+ <p class="text-center text-green-300 mt-2">Interactive Battle Simulation</p>
210
  </div>
211
 
212
  <div class="p-6">
213
+ <div class="flex flex-col lg:flex-row gap-6">
214
+ <div class="lg:w-2/3">
215
+ <div class="battlefield-container relative">
216
+ <div class="battlefield h-96 rounded-lg mb-6 relative overflow-hidden" id="battlefield">
217
+ <!-- Physics engine canvas will be inserted here -->
218
+ <canvas id="physics-canvas" class="absolute inset-0 w-full h-full"></canvas>
219
+ <!-- Visual elements will be added here by JavaScript -->
220
+ <div id="visual-elements" class="absolute inset-0 w-full h-full"></div>
221
+ <!-- Selection rectangle -->
222
+ <div id="selection-rectangle" class="selection-rectangle"></div>
223
+ </div>
 
 
 
 
 
 
 
 
 
 
 
 
224
  </div>
225
+
226
+ <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6">
227
+ <div class="bg-gray-700 p-4 rounded-lg">
228
+ <h3 class="font-bold text-green-400 mb-3">Men Squad</h3>
229
+ <div class="space-y-2">
230
+ <div>
231
+ <div class="flex justify-between mb-1">
232
+ <span class="text-sm font-medium text-gray-300">Remaining Men</span>
233
+ <span class="text-sm font-bold text-white" id="men-count">100</span>
234
+ </div>
235
+ <div class="w-full bg-gray-600 rounded-full h-2">
236
+ <div class="bg-green-500 h-2 rounded-full" id="men-health" style="width: 100%"></div>
237
+ </div>
238
+ </div>
239
+ <div>
240
+ <div class="flex justify-between mb-1">
241
+ <span class="text-sm font-medium text-gray-300">Morale</span>
242
+ <span class="text-sm font-bold text-white" id="men-morale">100%</span>
243
+ </div>
244
+ <div class="w-full bg-gray-600 rounded-full h-2">
245
+ <div class="bg-blue-500 h-2 rounded-full" id="men-morale-bar" style="width: 100%"></div>
246
+ </div>
247
+ </div>
248
+ <div class="flex justify-between text-xs text-gray-400 mt-2">
249
+ <span>Killed: <span id="men-killed">0</span></span>
250
+ <span>Injured: <span id="men-injured">0</span></span>
251
+ <span>Fleeing: <span id="men-fleeing">0</span></span>
252
+ </div>
253
+ </div>
254
+ </div>
255
+
256
+ <div class="bg-gray-700 p-4 rounded-lg">
257
+ <h3 class="font-bold text-red-400 mb-3">Silverback Gorilla</h3>
258
+ <div class="space-y-2">
259
+ <div>
260
+ <div class="flex justify-between mb-1">
261
+ <span class="text-sm font-medium text-gray-300">Health</span>
262
+ <span class="text-sm font-bold text-white" id="gorilla-health-text">100%</span>
263
+ </div>
264
+ <div class="w-full bg-gray-600 rounded-full h-2">
265
+ <div class="bg-red-500 h-2 rounded-full" id="gorilla-health" style="width: 100%"></div>
266
+ </div>
267
+ </div>
268
+ <div>
269
+ <div class="flex justify-between mb-1">
270
+ <span class="text-sm font-medium text-gray-300">Rage</span>
271
+ <span class="text-sm font-bold text-white" id="gorilla-rage">0%</span>
272
+ </div>
273
+ <div class="w-full bg-gray-600 rounded-full h-2">
274
+ <div class="bg-orange-500 h-2 rounded-full" id="gorilla-rage-bar" style="width: 0%"></div>
275
+ </div>
276
+ </div>
277
+ <div class="flex justify-between text-xs text-gray-400 mt-2">
278
+ <span>Damage Dealt: <span id="gorilla-damage">0</span></span>
279
+ <span>Critical Hits: <span id="gorilla-crits">0</span></span>
280
+ <span>Kill Streak: <span id="gorilla-streak">0</span></span>
281
+ </div>
282
+ </div>
283
+ </div>
284
  </div>
285
  </div>
286
+
287
+ <div class="lg:w-1/3">
288
+ <div class="bg-gray-700 p-4 rounded-lg mb-6">
289
+ <h3 class="font-bold text-yellow-400 mb-3">Battle Controls</h3>
290
+ <div class="space-y-3">
291
+ <button id="start-battle" class="w-full bg-red-600 hover:bg-red-700 text-white font-bold py-3 px-4 rounded-lg transition flex items-center justify-center gap-2">
292
+ <i class="fas fa-play"></i> Start Battle
293
+ </button>
294
+ <button id="auto-battle" class="w-full bg-purple-600 hover:bg-purple-700 text-white font-bold py-3 px-4 rounded-lg transition flex items-center justify-center gap-2">
295
+ <i class="fas fa-bolt"></i> Fast Forward
296
+ </button>
297
+ <button id="reset" class="w-full bg-gray-600 hover:bg-gray-700 text-white font-bold py-3 px-4 rounded-lg transition flex items-center justify-center gap-2">
298
+ <i class="fas fa-redo"></i> Reset Simulation
299
+ </button>
300
+ </div>
301
+
302
+ <div class="mt-4">
303
+ <label class="block text-sm font-medium text-gray-300 mb-2">Simulation Speed</label>
304
+ <input type="range" id="speed-control" min="1" max="10" value="1" class="w-full h-2 bg-gray-600 rounded-lg appearance-none cursor-pointer">
305
+ <div class="flex justify-between text-xs text-gray-400 mt-1">
306
+ <span>1x</span>
307
+ <span>5x</span>
308
+ <span>10x</span>
309
+ </div>
310
+ </div>
311
  </div>
312
+
313
+ <div class="bg-gray-700 p-4 rounded-lg">
314
+ <h3 class="font-bold text-blue-400 mb-3">Battle Statistics</h3>
315
+ <div class="grid grid-cols-2 gap-3 text-sm">
316
+ <div>
317
+ <p class="text-gray-300"><span class="font-semibold">Battle Time:</span> <span id="battle-time" class="text-white">0</span>s</p>
318
+ <p class="text-gray-300"><span class="font-semibold">FPS:</span> <span id="fps-counter" class="text-white">0</span></p>
319
+ <p class="text-gray-300"><span class="font-semibold">Physics:</span> <span id="physics-stats" class="text-white">Active</span></p>
320
+ </div>
321
+ <div>
322
+ <p class="text-gray-300"><span class="font-semibold">Winner:</span> <span id="winner" class="font-bold">-</span></p>
323
+ <p class="text-gray-300"><span class="font-semibold">Victory Type:</span> <span id="victory-type" class="text-white">-</span></p>
324
+ <p class="text-gray-300"><span class="font-semibold">Simulation:</span> <span id="simulation-state" class="text-green-400">Ready</span></p>
325
+ </div>
326
+ </div>
327
+
328
+ <div class="mt-4 pt-4 border-t border-gray-600">
329
+ <h4 class="font-bold text-yellow-400 mb-2">Combat Log</h4>
330
+ <div id="combat-log" class="h-32 overflow-y-auto text-xs bg-gray-800 p-2 rounded space-y-1">
331
+ <div class="text-gray-400 italic">Waiting for battle to begin...</div>
332
+ </div>
333
+ </div>
334
  </div>
335
  </div>
336
  </div>
337
 
338
+ <div class="bg-gray-700 p-4 rounded-lg mt-4">
339
+ <h3 class="font-bold text-green-400 mb-2">Controls Guide</h3>
340
+ <div class="grid grid-cols-2 md:grid-cols-3 gap-3 text-sm">
341
+ <div class="flex items-center gap-2">
342
+ <div class="w-4 h-4 border-2 border-blue-500 rounded-sm"></div>
343
+ <span class="text-gray-300">Click to select</span>
344
+ </div>
345
+ <div class="flex items-center gap-2">
346
+ <div class="w-4 h-4 border-2 border-blue-500 rounded-sm bg-blue-500 bg-opacity-30"></div>
347
+ <span class="text-gray-300">Drag to move</span>
348
+ </div>
349
+ <div class="flex items-center gap-2">
350
+ <div class="w-4 h-4 border-2 border-blue-500"></div>
351
+ <span class="text-gray-300">Shift+Click for multi-select</span>
352
+ </div>
353
+ <div class="flex items-center gap-2">
354
+ <div class="w-4 h-4 border-2 border-blue-500 bg-blue-500"></div>
355
+ <span class="text-gray-300">Drag area to select multiple</span>
356
  </div>
357
+ <div class="flex items-center gap-2">
358
+ <div class="w-4 h-4 border-2 border-blue-500 bg-blue-500"></div>
359
+ <span class="text-gray-300">Right-click to throw</span>
360
+ </div>
361
+ <div class="flex items-center gap-2">
362
+ <div class="w-4 h-4 border-2 border-blue-500"></div>
363
+ <span class="text-gray-300">ESC to deselect</span>
364
  </div>
365
  </div>
366
  </div>
367
  </div>
368
  </div>
 
 
 
 
 
369
 
370
  <script>
371
  // Game variables
372
+ const config = {
373
+ menCount: 100,
374
+ gorillaHealth: 1000, // Gorilla has 10x health of a man
375
+ gorillaBaseDamage: 50,
376
+ gorillaCriticalChance: 0.2,
377
+ gorillaAttackSpeed: 1000, // ms
378
+ manBaseDamage: 1,
379
+ manCriticalChance: 0.05,
380
+ manAttackSpeed: 500, // ms
381
+ moraleImpact: 0.5, // How much morale affects performance
382
+ fearThreshold: 30, // % health when fear kicks in
383
+ fleeChance: 0.1, // Base chance to flee
384
+ injuryChance: 0.3, // Chance to get injured instead of killed
385
+ weaponChance: 0.4, // Chance for a man to have a weapon
386
+ environmentObjects: 15, // Number of environmental objects
387
+ simulationSpeed: 1
388
+ };
389
+
390
+ let state = {
391
+ activeMen: config.menCount,
392
+ injuredMen: 0,
393
+ fleeingMen: 0,
394
+ killedMen: 0,
395
+ gorillaHealth: config.gorillaHealth,
396
+ gorillaRage: 0,
397
+ gorillaDamageDealt: 0,
398
+ gorillaCriticalHits: 0,
399
+ gorillaKillStreak: 0,
400
+ menMorale: 100,
401
+ battleTime: 0,
402
+ battleActive: false,
403
+ winner: null,
404
+ victoryType: null,
405
+ lastFrameTime: 0,
406
+ fps: 0,
407
+ physicsBodies: {},
408
+ visualElements: {},
409
+ combatLog: [],
410
+ selectedBodies: new Set(),
411
+ selectionStart: null,
412
+ isSelecting: false,
413
+ shiftPressed: false
414
+ };
415
+
416
+ // Physics engine setup
417
+ const engine = Matter.Engine.create({
418
+ gravity: { x: 0, y: 0.5 }
419
+ });
420
+ const world = engine.world;
421
 
422
  // DOM elements
423
  const battlefield = document.getElementById('battlefield');
424
+ const physicsCanvas = document.getElementById('physics-canvas');
425
+ const visualElements = document.getElementById('visual-elements');
426
+ const selectionRectangle = document.getElementById('selection-rectangle');
427
  const startBattleBtn = document.getElementById('start-battle');
428
  const autoBattleBtn = document.getElementById('auto-battle');
429
  const resetBtn = document.getElementById('reset');
430
+ const speedControl = document.getElementById('speed-control');
431
+
432
+ // Renderer for physics debug (hidden in production)
433
+ const render = Matter.Render.create({
434
+ canvas: physicsCanvas,
435
+ engine: engine,
436
+ options: {
437
+ width: battlefield.offsetWidth,
438
+ height: battlefield.offsetHeight,
439
+ wireframes: false,
440
+ background: 'transparent',
441
+ showAngleIndicator: false,
442
+ showCollisions: false,
443
+ showVelocity: false
444
+ }
445
+ });
446
+ Matter.Render.run(render);
447
+
448
+ // Mouse control
449
+ const mouse = Matter.Mouse.create(battlefield);
450
+ const mouseConstraint = Matter.MouseConstraint.create(engine, {
451
+ mouse: mouse,
452
+ constraint: {
453
+ stiffness: 0.2,
454
+ render: {
455
+ visible: false
456
+ }
457
+ }
458
+ });
459
+
460
+ Matter.Composite.add(world, mouseConstraint);
461
+
462
+ // Keep mouse in sync with render
463
+ Matter.Events.on(render, 'afterRender', function() {
464
+ Matter.Mouse.setOffset(mouse, render.bounds);
465
+ });
466
+
467
+ // Initialize battlefield with physics
468
  function initializeBattlefield() {
469
+ // Clear previous state
470
+ visualElements.innerHTML = '';
471
+ state.physicsBodies = {};
472
+ state.visualElements = {};
473
+ state.combatLog = [];
474
+ state.selectedBodies = new Set();
475
+ document.getElementById('combat-log').innerHTML = '<div class="text-gray-400 italic">Battlefield initialized...</div>';
476
+
477
+ // Create physics boundaries
478
+ const boundaryOptions = { isStatic: true, render: { visible: false } };
479
+ const ground = Matter.Bodies.rectangle(battlefield.offsetWidth/2, battlefield.offsetHeight, battlefield.offsetWidth, 10, boundaryOptions);
480
+ const ceiling = Matter.Bodies.rectangle(battlefield.offsetWidth/2, 0, battlefield.offsetWidth, 10, boundaryOptions);
481
+ const leftWall = Matter.Bodies.rectangle(0, battlefield.offsetHeight/2, 10, battlefield.offsetHeight, boundaryOptions);
482
+ const rightWall = Matter.Bodies.rectangle(battlefield.offsetWidth, battlefield.offsetHeight/2, 10, battlefield.offsetHeight, boundaryOptions);
483
+
484
+ Matter.Composite.add(world, [ground, ceiling, leftWall, rightWall]);
485
+
486
+ // Create environmental objects (rocks, trees, etc.)
487
+ for (let i = 0; i < config.environmentObjects; i++) {
488
+ const size = 20 + Math.random() * 40;
489
+ const x = 50 + Math.random() * (battlefield.offsetWidth - 100);
490
+ const y = 50 + Math.random() * (battlefield.offsetHeight - 100);
491
+
492
+ const envBody = Matter.Bodies.rectangle(x, y, size, size, {
493
+ isStatic: true,
494
+ render: {
495
+ fillStyle: '#495057'
496
+ }
497
+ });
498
+
499
+ Matter.Composite.add(world, envBody);
500
+
501
+ // Add visual element
502
+ const envElement = document.createElement('div');
503
+ envElement.className = 'environment';
504
+ envElement.style.width = `${size}px`;
505
+ envElement.style.height = `${size}px`;
506
+ envElement.style.left = `${x - size/2}px`;
507
+ envElement.style.top = `${y - size/2}px`;
508
+ visualElements.appendChild(envElement);
509
+ }
510
 
511
  // Create gorilla
512
+ const gorillaSize = 80;
513
+ const gorillaX = battlefield.offsetWidth - 100;
514
+ const gorillaY = battlefield.offsetHeight / 2;
515
+
516
+ const gorillaBody = Matter.Bodies.circle(gorillaX, gorillaY, gorillaSize/2, {
517
+ mass: 100,
518
+ friction: 0.05,
519
+ restitution: 0.3,
520
+ render: {
521
+ fillStyle: '#343a40'
522
+ },
523
+ label: 'gorilla'
524
+ });
525
+
526
+ Matter.Composite.add(world, gorillaBody);
527
+ state.physicsBodies.gorilla = gorillaBody;
528
+
529
+ // Add visual gorilla
530
+ const gorillaElement = document.createElement('div');
531
+ gorillaElement.className = 'gorilla';
532
+ gorillaElement.innerHTML = '<i class="fas fa-paw text-gray-300 text-3xl"></i>';
533
+ gorillaElement.id = 'gorilla-visual';
534
+ gorillaElement.style.width = `${gorillaSize}px`;
535
+ gorillaElement.style.height = `${gorillaSize}px`;
536
+ visualElements.appendChild(gorillaElement);
537
+ state.visualElements.gorilla = gorillaElement;
538
+
539
+ // Add health bar to gorilla
540
+ const gorillaHealthBar = document.createElement('div');
541
+ gorillaHealthBar.className = 'health-bar';
542
+ gorillaHealthBar.style.width = '100%';
543
+ gorillaElement.appendChild(gorillaHealthBar);
544
+
545
+ // Add stamina bar to gorilla
546
+ const gorillaStaminaBar = document.createElement('div');
547
+ gorillaStaminaBar.className = 'stamina-bar';
548
+ gorillaStaminaBar.style.width = '100%';
549
+ gorillaElement.appendChild(gorillaStaminaBar);
550
 
551
  // Create men
552
+ for (let i = 0; i < config.menCount; i++) {
553
  createMan(i);
554
  }
555
+
556
+ // Start physics engine
557
+ Matter.Engine.run(engine);
558
+
559
+ // Start game loop
560
+ requestAnimationFrame(gameLoop);
561
  }
562
 
563
+ // Create a single man with physics
564
  function createMan(index) {
565
+ const manSize = 24;
566
+ const padding = 50;
567
+ const x = padding + Math.random() * (battlefield.offsetWidth/2 - padding);
568
+ const y = padding + Math.random() * (battlefield.offsetHeight - padding * 2);
569
+
570
+ const manBody = Matter.Bodies.circle(x, y, manSize/2, {
571
+ mass: 10,
572
+ friction: 0.1,
573
+ restitution: 0.2,
574
+ render: {
575
+ fillStyle: '#588157'
576
+ },
577
+ label: `man-${index}`
578
+ });
579
+
580
+ Matter.Composite.add(world, manBody);
581
+ state.physicsBodies[`man-${index}`] = manBody;
582
+
583
+ // Add visual man
584
+ const manElement = document.createElement('div');
585
+ manElement.className = 'man';
586
+ manElement.id = `man-visual-${index}`;
587
+
588
+ // Random chance to have a weapon
589
+ if (Math.random() < config.weaponChance) {
590
+ const weaponType = Math.random() < 0.3 ? 'spear' : 'club';
591
+ const weaponElement = document.createElement('div');
592
+ weaponElement.className = 'weapon';
593
+ weaponElement.style.backgroundColor = weaponType === 'spear' ? '#adb5bd' : '#6c757d';
594
+ manElement.appendChild(weaponElement);
595
+ manBody.weapon = weaponType;
596
+ }
597
+
598
+ visualElements.appendChild(manElement);
599
+ state.visualElements[`man-${index}`] = manElement;
600
+
601
+ // Add health bar
602
+ const healthBar = document.createElement('div');
603
+ healthBar.className = 'health-bar';
604
+ healthBar.style.width = '100%';
605
+ manElement.appendChild(healthBar);
606
+
607
+ // Add fear indicator
608
+ const fearIndicator = document.createElement('div');
609
+ fearIndicator.className = 'fear-indicator';
610
+ manElement.appendChild(fearIndicator);
611
+ }
612
+
613
+ // Select a physics body
614
+ function selectBody(bodyId, addToSelection = false) {
615
+ if (!addToSelection) {
616
+ // Deselect all first
617
+ deselectAll();
618
+ }
619
 
620
+ const body = state.physicsBodies[bodyId];
621
+ if (!body) return;
 
622
 
623
+ state.selectedBodies.add(bodyId);
 
624
 
625
+ // Highlight visual element
626
+ const visualElement = state.visualElements[bodyId];
627
+ if (visualElement) {
628
+ visualElement.classList.add('selected');
629
+ }
630
+ }
631
+
632
+ // Deselect a physics body
633
+ function deselectBody(bodyId) {
634
+ state.selectedBodies.delete(bodyId);
635
+
636
+ // Remove highlight from visual element
637
+ const visualElement = state.visualElements[bodyId];
638
+ if (visualElement) {
639
+ visualElement.classList.remove('selected');
640
+ }
641
+ }
642
+
643
+ // Deselect all bodies
644
+ function deselectAll() {
645
+ state.selectedBodies.forEach(bodyId => {
646
+ deselectBody(bodyId);
647
+ });
648
+ state.selectedBodies.clear();
649
+ }
650
+
651
+ // Move selected bodies to position
652
+ function moveSelectedTo(position) {
653
+ state.selectedBodies.forEach(bodyId => {
654
+ const body = state.physicsBodies[bodyId];
655
+ if (body) {
656
+ Matter.Body.setPosition(body, position);
657
+ }
658
+ });
659
+ }
660
+
661
+ // Apply force to selected bodies
662
+ function throwSelected(velocity) {
663
+ state.selectedBodies.forEach(bodyId => {
664
+ const body = state.physicsBodies[bodyId];
665
+ if (body) {
666
+ Matter.Body.setVelocity(body, velocity);
667
+ }
668
+ });
669
+ }
670
+
671
+ // Game loop for updating visuals
672
+ function gameLoop(timestamp) {
673
+ // Calculate FPS
674
+ if (state.lastFrameTime) {
675
+ state.fps = Math.round(1000 / (timestamp - state.lastFrameTime));
676
+ document.getElementById('fps-counter').textContent = state.fps;
677
+ }
678
+ state.lastFrameTime = timestamp;
679
+
680
+ // Update physics bodies positions
681
+ for (const [id, body] of Object.entries(state.physicsBodies)) {
682
+ if (body.render.visible !== false) {
683
+ const visualElement = state.visualElements[id];
684
+ if (visualElement) {
685
+ visualElement.style.transform = `translate(${body.position.x - visualElement.offsetWidth/2}px, ${body.position.y - visualElement.offsetHeight/2}px) rotate(${body.angle}rad)`;
686
+
687
+ // Update health bars
688
+ if (body.health !== undefined) {
689
+ const healthBar = visualElement.querySelector('.health-bar');
690
+ if (healthBar) {
691
+ healthBar.style.width = `${body.health}%`;
692
+ }
693
+ }
694
+ }
695
+ }
696
+ }
697
+
698
+ // Update selection rectangle
699
+ if (state.isSelecting && state.selectionStart) {
700
+ const currentMouse = mouse.position;
701
+ const left = Math.min(state.selectionStart.x, currentMouse.x);
702
+ const top = Math.min(state.selectionStart.y, currentMouse.y);
703
+ const width = Math.abs(currentMouse.x - state.selectionStart.x);
704
+ const height = Math.abs(currentMouse.y - state.selectionStart.y);
705
+
706
+ selectionRectangle.style.display = 'block';
707
+ selectionRectangle.style.left = `${left}px`;
708
+ selectionRectangle.style.top = `${top}px`;
709
+ selectionRectangle.style.width = `${width}px`;
710
+ selectionRectangle.style.height = `${height}px`;
711
+ }
712
+
713
+ // Battle time update
714
+ if (state.battleActive) {
715
+ state.battleTime += (1/60) * config.simulationSpeed;
716
+ document.getElementById('battle-time').textContent = Math.round(state.battleTime);
717
+ }
718
+
719
+ requestAnimationFrame(gameLoop);
720
  }
721
 
722
  // Start battle
723
  function startBattle() {
724
+ if (state.battleActive) return;
725
+
726
+ state.battleActive = true;
727
+ state.winner = null;
728
+ state.victoryType = null;
729
+ state.lastFrameTime = 0;
730
 
 
731
  startBattleBtn.disabled = true;
732
  autoBattleBtn.disabled = true;
733
+ document.getElementById('simulation-state').textContent = 'Running';
734
+ document.getElementById('simulation-state').className = 'text-yellow-400';
735
 
736
+ addCombatLog("The battle begins! 100 men charge at the gorilla.");
 
 
 
 
 
737
 
738
+ // Initialize health for all combatants
739
+ for (const [id, body] of Object.entries(state.physicsBodies)) {
740
+ if (id === 'gorilla') {
741
+ body.health = 100;
742
+ } else if (id.startsWith('man-')) {
743
+ body.health = 100;
744
+ body.isInjured = false;
745
+ body.isFleeing = false;
746
+ }
747
+ }
748
+
749
+ // Gorilla attack pattern
750
  const gorillaAttackInterval = setInterval(() => {
751
+ if (!state.battleActive || state.gorillaHealth <= 0 || state.activeMen <= 0) {
752
  clearInterval(gorillaAttackInterval);
753
  return;
754
  }
755
 
756
+ // Gorilla attack animation
757
+ const gorillaVisual = document.getElementById('gorilla-visual');
758
+ gorillaVisual.style.animation = 'gorillaSwing 0.3s';
759
  setTimeout(() => {
760
+ gorillaVisual.style.animation = '';
761
  }, 300);
762
 
763
+ // Find closest men to attack
764
+ const gorillaPos = state.physicsBodies.gorilla.position;
765
+ let closestMen = null;
766
+ let minDistance = Infinity;
767
 
768
+ for (let i = 0; i < config.menCount; i++) {
769
+ const manId = `man-${i}`;
770
+ const manBody = state.physicsBodies[manId];
 
 
771
 
772
+ if (manBody && !manBody.isFleeing) {
773
+ const distance = Matter.Vector.magnitude(Matter.Vector.sub(manBody.position, gorillaPos));
774
+ if (distance < minDistance) {
775
+ minDistance = distance;
776
+ closestMen = manBody;
777
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
778
  }
779
  }
780
 
781
+ if (closestMen && minDistance < 150) {
782
+ // Calculate damage
783
+ const isCritical = Math.random() < config.gorillaCriticalChance;
784
+ let damage = config.gorillaBaseDamage * (1 + state.gorillaRage/100);
785
+ if (isCritical) {
786
+ damage *= 2;
787
+ state.gorillaCriticalHits++;
788
+ addCombatLog(`Gorilla CRITICALLY hits a man for ${Math.round(damage)} damage!`);
789
+ } else {
790
+ addCombatLog(`Gorilla attacks a man for ${Math.round(damage)} damage.`);
 
791
  }
792
 
793
+ // Apply damage
794
+ applyDamage(closestMen, damage, isCritical);
 
 
795
 
796
+ // Increase gorilla stats
797
+ state.gorillaDamageDealt += damage;
798
+ state.gorillaKillStreak++;
799
+
800
+ // Apply knockback
801
+ const direction = Matter.Vector.normalise(Matter.Vector.sub(closestMen.position, gorillaPos));
802
+ const force = Matter.Vector.mult(direction, 0.1 * damage);
803
+ Matter.Body.applyForce(closestMen, closestMen.position, force);
804
+
805
+ // Rage increases with each attack
806
+ state.gorillaRage = Math.min(100, state.gorillaRage + 2);
807
  }
808
 
809
+ updateStats();
 
 
810
 
811
+ }, config.gorillaAttackSpeed / config.simulationSpeed);
 
 
 
 
 
 
 
812
 
813
+ // Men attack pattern
814
+ const menAttackInterval = setInterval(() => {
815
+ if (!state.battleActive || state.gorillaHealth <= 0 || state.activeMen <= 0) {
816
+ clearInterval(menAttackInterval);
817
  return;
818
  }
819
 
820
+ // Each active man has a chance to attack
821
+ for (let i = 0; i < config.menCount; i++) {
822
+ const manId = `man-${i}`;
823
+ const manBody = state.physicsBodies[manId];
 
 
824
 
825
+ if (manBody && !manBody.isFleeing && !manBody.isInjured) {
826
+ const distanceToGorilla = Matter.Vector.magnitude(Matter.Vector.sub(manBody.position, state.physicsBodies.gorilla.position));
827
+
828
+ if (distanceToGorilla < 100 && Math.random() < 0.7) { // 70% chance to attack if in range
829
+ // Attack animation
830
+ const manVisual = state.visualElements[manId];
831
+ manVisual.style.animation = 'punch 0.2s';
832
+ setTimeout(() => {
833
+ manVisual.style.animation = '';
834
+ }, 200);
835
+
836
+ // Calculate damage
837
+ const isCritical = Math.random() < config.manCriticalChance;
838
+ let damage = config.manBaseDamage;
839
+
840
+ // Weapon bonus
841
+ if (manBody.weapon === 'spear') damage *= 3;
842
+ else if (manBody.weapon === 'club') damage *= 2;
843
+
844
+ // Morale impact
845
+ damage *= (state.menMorale / 100) * config.moraleImpact;
846
+
847
+ if (isCritical) {
848
+ damage *= 2;
849
+ addCombatLog(`A man lands a CRITICAL hit on the gorilla for ${Math.round(damage)} damage!`);
850
+ }
851
+
852
+ // Apply damage to gorilla
853
+ state.gorillaHealth -= damage;
854
+ if (state.gorillaHealth <= 0) {
855
+ state.gorillaHealth = 0;
856
+ endBattle('Men', 'Total Annihilation');
857
+ return;
858
+ }
859
+
860
+ // Show damage text
861
+ showDamageText(state.physicsBodies.gorilla.position, Math.round(damage), isCritical);
862
+
863
+ // Reset gorilla kill streak when hit
864
+ state.gorillaKillStreak = 0;
865
+
866
+ // Update gorilla health bar
867
+ const gorillaHealthPercent = (state.gorillaHealth / config.gorillaHealth) * 100;
868
+ state.physicsBodies.gorilla.health = gorillaHealthPercent;
869
+
870
+ // Check for fear state
871
+ if (gorillaHealthPercent < config.fearThreshold && Math.random() < 0.3) {
872
+ addCombatLog("The gorilla shows signs of fear!");
873
+ const gorillaVisual = document.getElementById('gorilla-visual');
874
+ gorillaVisual.classList.add('fear-active');
875
+ }
876
+ }
877
  }
878
+ }
879
+
880
+ updateStats();
881
+
882
+ }, config.manAttackSpeed / config.simulationSpeed);
883
+
884
+ // Morale check interval
885
+ const moraleCheckInterval = setInterval(() => {
886
+ if (!state.battleActive || state.gorillaHealth <= 0 || state.activeMen <= 0) {
887
+ clearInterval(moraleCheckInterval);
888
+ return;
889
+ }
890
+
891
+ // Morale decreases based on casualties
892
+ const casualtyRate = (state.killedMen + state.injuredMen) / config.menCount;
893
+ state.menMorale = Math.max(0, 100 - (casualtyRate * 150));
894
+
895
+ // Check for fleeing men
896
+ if (state.menMorale < 30) {
897
+ const fleeChance = config.fleeChance + (30 - state.menMorale) / 50;
898
 
899
+ for (let i = 0; i < config.menCount; i++) {
900
+ const manId = `man-${i}`;
901
+ const manBody = state.physicsBodies[manId];
902
+
903
+ if (manBody && !manBody.isFleeing && !manBody.isInjured && Math.random() < fleeChance) {
904
+ manBody.isFleeing = true;
905
+ state.fleeingMen++;
906
+ state.activeMen--;
907
+
908
+ // Visual indication
909
+ const manVisual = state.visualElements[manId];
910
+ manVisual.classList.add('fear-active');
911
+ manVisual.style.backgroundColor = '#6c757d';
912
+
913
+ // Apply flee force (move left)
914
+ Matter.Body.applyForce(manBody, manBody.position, { x: -0.05, y: -0.02 });
915
+
916
+ addCombatLog(`A man flees in terror! ${state.fleeingMen} have fled so far.`);
917
+ }
918
  }
919
  }
920
 
921
+ // If too many men flee, gorilla wins
922
+ if (state.fleeingMen > config.menCount * 0.7) {
923
+ endBattle('Gorilla', 'Men Routed');
924
+ }
925
+
926
  updateStats();
927
 
928
+ }, 1000 / config.simulationSpeed);
929
  }
930
 
931
+ // Apply damage to a man
932
+ function applyDamage(manBody, damage, isCritical) {
933
+ // Calculate actual damage (can be reduced by armor, etc.)
934
+ const actualDamage = damage;
935
+
936
+ // Check for injury instead of death
937
+ const isInjury = manBody.health - actualDamage > 0 && Math.random() < config.injuryChance;
938
+
939
+ if (isInjury) {
940
+ manBody.health -= actualDamage;
941
+ manBody.isInjured = true;
942
+ state.injuredMen++;
943
+ state.activeMen--;
944
+
945
+ // Visual indication
946
+ const manId = manBody.label;
947
+ const manVisual = state.visualElements[manId];
948
+ manVisual.style.backgroundColor = '#e9c46a';
949
+
950
+ // Add bone break effect
951
+ const bone = document.createElement('div');
952
+ bone.className = 'bone';
953
+ bone.style.left = '50%';
954
+ bone.style.top = '50%';
955
+ bone.style.transform = 'translate(-50%, -50%)';
956
+ manVisual.appendChild(bone);
957
+
958
+ addCombatLog(`A man is badly injured! ${state.injuredMen} men are out of combat.`);
959
+ } else {
960
+ // Kill the man
961
+ const manId = manBody.label;
962
+
963
+ // Blood effect
964
+ createBloodEffect(manBody.position, isCritical);
965
+
966
+ // Remove from physics
967
+ Matter.Composite.remove(world, manBody);
968
+ delete state.physicsBodies[manId];
969
+
970
+ // Visual death
971
+ const manVisual = state.visualElements[manId];
972
+ manVisual.style.opacity = '0';
973
+ manVisual.style.transform += ' scale(0)';
974
+ setTimeout(() => {
975
+ manVisual.remove();
976
+ }, 1000);
977
+
978
+ state.killedMen++;
979
+ state.activeMen--;
980
+
981
+ addCombatLog(`A man is killed! ${state.killedMen} men have died.`);
982
+ }
983
+
984
+ // Check if all men are dead
985
+ if (state.activeMen <= 0) {
986
+ endBattle('Gorilla', 'Total Annihilation');
987
+ }
988
  }
989
 
990
+ // Create blood effect
991
+ function createBloodEffect(position, isCritical) {
992
+ const bloodCount = isCritical ? 5 : 3;
 
993
 
994
+ for (let i = 0; i < bloodCount; i++) {
995
+ const blood = document.createElement('div');
996
+ blood.className = 'blood';
997
+ blood.style.left = `${position.x - 15 + Math.random() * 30}px`;
998
+ blood.style.top = `${position.y - 15 + Math.random() * 30}px`;
999
+ blood.style.transform = 'scale(0)';
1000
+ blood.style.animation = 'bloodSpray 0.5s forwards';
1001
+ visualElements.appendChild(blood);
1002
+
1003
+ setTimeout(() => {
1004
+ blood.remove();
1005
+ }, 500);
1006
  }
1007
+ }
1008
+
1009
+ // Show damage text
1010
+ function showDamageText(position, amount, isCritical) {
1011
+ const damageText = document.createElement('div');
1012
+ damageText.className = 'damage-text';
1013
+ damageText.textContent = `-${amount}`;
1014
+ damageText.style.left = `${position.x}px`;
1015
+ damageText.style.top = `${position.y}px`;
1016
+ if (isCritical) {
1017
+ damageText.style.color = '#ffc107';
1018
+ damageText.style.fontSize = '14px';
1019
+ }
1020
+ visualElements.appendChild(damageText);
1021
 
1022
+ setTimeout(() => {
1023
+ damageText.remove();
1024
+ }, 1000);
1025
+ }
1026
+
1027
+ // Add message to combat log
1028
+ function addCombatLog(message) {
1029
+ const logEntry = document.createElement('div');
1030
+ logEntry.className = 'text-gray-300';
1031
+ logEntry.textContent = `[${Math.round(state.battleTime)}s] ${message}`;
1032
 
1033
+ const combatLog = document.getElementById('combat-log');
1034
+ combatLog.appendChild(logEntry);
1035
+ combatLog.scrollTop = combatLog.scrollHeight;
1036
+
1037
+ // Keep log manageable
1038
+ if (combatLog.children.length > 50) {
1039
+ combatLog.removeChild(combatLog.children[0]);
1040
  }
1041
 
1042
+ state.combatLog.push(message);
1043
+ }
1044
+
1045
+ // Update all stats displays
1046
+ function updateStats() {
1047
+ // Men stats
1048
+ document.getElementById('men-count').textContent = state.activeMen;
1049
+ document.getElementById('men-health').style.width = `${(state.activeMen / config.menCount) * 100}%`;
1050
+ document.getElementById('men-morale').textContent = `${Math.round(state.menMorale)}%`;
1051
+ document.getElementById('men-morale-bar').style.width = `${state.menMorale}%`;
1052
+ document.getElementById('men-killed').textContent = state.killedMen;
1053
+ document.getElementById('men-injured').textContent = state.injuredMen;
1054
+ document.getElementById('men-fleeing').textContent = state.fleeingMen;
1055
+
1056
+ // Gorilla stats
1057
+ const gorillaHealthPercent = (state.gorillaHealth / config.gorillaHealth) * 100;
1058
+ document.getElementById('gorilla-health-text').textContent = `${Math.round(gorillaHealthPercent)}%`;
1059
+ document.getElementById('gorilla-health').style.width = `${gorillaHealthPercent}%`;
1060
+ document.getElementById('gorilla-rage').textContent = `${Math.round(state.gorillaRage)}%`;
1061
+ document.getElementById('gorilla-rage-bar').style.width = `${state.gorillaRage}%`;
1062
+ document.getElementById('gorilla-damage').textContent = Math.round(state.gorillaDamageDealt);
1063
+ document.getElementById('gorilla-crits').textContent = state.gorillaCriticalHits;
1064
+ document.getElementById('gorilla-streak').textContent = state.gorillaKillStreak;
1065
+ }
1066
+
1067
+ // End battle
1068
+ function endBattle(winner, victoryType) {
1069
+ state.battleActive = false;
1070
+ state.winner = winner;
1071
+ state.victoryType = victoryType;
1072
+
1073
+ document.getElementById('winner').textContent = winner;
1074
+ document.getElementById('winner').className = winner === 'Gorilla' ? 'text-red-500 font-bold' : 'text-green-500 font-bold';
1075
+ document.getElementById('victory-type').textContent = victoryType;
1076
+ document.getElementById('simulation-state').textContent = 'Completed';
1077
+ document.getElementById('simulation-state').className = 'text-green-400';
1078
+
1079
  startBattleBtn.disabled = false;
1080
  autoBattleBtn.disabled = false;
1081
+
1082
+ if (winner === 'Gorilla') {
1083
+ addCombatLog(`The gorilla emerges victorious! ${victoryType}`);
1084
+
1085
+ // Gorilla victory animation
1086
+ const gorillaVisual = document.getElementById('gorilla-visual');
1087
+ gorillaVisual.innerHTML = '<i class="fas fa-crown text-yellow-400 text-3xl"></i>';
1088
+ gorillaVisual.style.boxShadow = '0 0 20px gold';
1089
+
1090
+ // Roar animation
1091
+ setTimeout(() => {
1092
+ gorillaVisual.style.transform += ' scale(1.2)';
1093
+ setTimeout(() => {
1094
+ gorillaVisual.style.transform = gorillaVisual.style.transform.replace(' scale(1.2)', '');
1095
+ }, 500);
1096
+ }, 300);
1097
+ } else {
1098
+ addCombatLog(`The men have defeated the gorilla! ${victoryType}`);
1099
+
1100
+ // Men celebration
1101
+ for (let i = 0; i < config.menCount; i++) {
1102
+ const manId = `man-${i}`;
1103
+ const manBody = state.physicsBodies[manId];
1104
+ const manVisual = state.visualElements[manId];
1105
+
1106
+ if (manBody && manVisual && !manBody.isFleeing) {
1107
+ // Jump for joy
1108
+ Matter.Body.applyForce(manBody, manBody.position, { x: 0, y: -0.1 });
1109
+
1110
+ // Visual change
1111
+ manVisual.style.backgroundColor = '#2a9d8f';
1112
+ manVisual.style.boxShadow = '0 0 10px cyan';
1113
+ }
1114
+ }
1115
+ }
1116
+ }
1117
+
1118
+ // Fast forward battle
1119
+ function fastForwardBattle() {
1120
+ if (state.battleActive) return;
1121
+
1122
+ startBattle();
1123
+ config.simulationSpeed = 5;
1124
+ document.getElementById('simulation-state').textContent = 'Fast Forwarding';
1125
+ addCombatLog("Simulation speed increased to fast forward results.");
1126
  }
1127
 
1128
  // Reset game
1129
  function resetGame() {
1130
+ state = {
1131
+ activeMen: config.menCount,
1132
+ injuredMen: 0,
1133
+ fleeingMen: 0,
1134
+ killedMen: 0,
1135
+ gorillaHealth: config.gorillaHealth,
1136
+ gorillaRage: 0,
1137
+ gorillaDamageDealt: 0,
1138
+ gorillaCriticalHits: 0,
1139
+ gorillaKillStreak: 0,
1140
+ menMorale: 100,
1141
+ battleTime: 0,
1142
+ battleActive: false,
1143
+ winner: null,
1144
+ victoryType: null,
1145
+ lastFrameTime: 0,
1146
+ fps: 0,
1147
+ physicsBodies: {},
1148
+ visualElements: {},
1149
+ combatLog: [],
1150
+ selectedBodies: new Set(),
1151
+ selectionStart: null,
1152
+ isSelecting: false,
1153
+ shiftPressed: false
1154
+ };
1155
 
1156
+ config.simulationSpeed = 1;
1157
+ speedControl.value = 1;
 
 
1158
 
1159
+ Matter.Composite.clear(world, false);
1160
  initializeBattlefield();
1161
+ updateStats();
1162
 
1163
+ document.getElementById('winner').textContent = '-';
1164
+ document.getElementById('winner').className = '';
1165
+ document.getElementById('victory-type').textContent = '-';
1166
+ document.getElementById('simulation-state').textContent = 'Ready';
1167
+ document.getElementById('simulation-state').className = 'text-green-400';
1168
+ document.getElementById('combat-log').innerHTML = '<div class="text-gray-400 italic">Simulation reset...</div>';
1169
 
1170
  startBattleBtn.disabled = false;
1171
  autoBattleBtn.disabled = false;
 
1173
 
1174
  // Event listeners
1175
  startBattleBtn.addEventListener('click', startBattle);
1176
+ autoBattleBtn.addEventListener('click', fastForwardBattle);
1177
  resetBtn.addEventListener('click', resetGame);
1178
+ speedControl.addEventListener('input', (e) => {
1179
+ config.simulationSpeed = parseInt(e.target.value);
1180
+ });
1181
+
1182
+ // Mouse interaction
1183
+ battlefield.addEventListener('mousedown', (e) => {
1184
+ if (e.button !== 0) return; // Only left click
1185
+
1186
+ const mousePosition = {
1187
+ x: e.clientX - battlefield.getBoundingClientRect().left,
1188
+ y: e.clientY - battlefield.getBoundingClientRect().top
1189
+ };
1190
+
1191
+ // Check if clicking on a body
1192
+ const bodies = Matter.Composite.allBodies(world);
1193
+ const clickedBody = bodies.find(body => {
1194
+ if (body.label && body.label.startsWith('man-') || body.label === 'gorilla') {
1195
+ const visualElement = state.visualElements[body.label];
1196
+ if (visualElement) {
1197
+ const rect = visualElement.getBoundingClientRect();
1198
+ return (
1199
+ mousePosition.x >= rect.left - battlefield.getBoundingClientRect().left &&
1200
+ mousePosition.x <= rect.right - battlefield.getBoundingClientRect().left &&
1201
+ mousePosition.y >= rect.top - battlefield.getBoundingClientRect().top &&
1202
+ mousePosition.y <= rect.bottom - battlefield.getBoundingClientRect().top
1203
+ );
1204
+ }
1205
+ }
1206
+ return false;
1207
+ });
1208
+
1209
+ if (clickedBody) {
1210
+ // Select the clicked body
1211
+ selectBody(clickedBody.label, e.shiftKey);
1212
+ } else {
1213
+ // Start area selection
1214
+ state.isSelecting = true;
1215
+ state.selectionStart = mousePosition;
1216
+ }
1217
+ });
1218
+
1219
+ battlefield.addEventListener('mousemove', (e) => {
1220
+ if (!state.isSelecting) return;
1221
+
1222
+ const mousePosition = {
1223
+ x: e.clientX - battlefield.getBoundingClientRect().left,
1224
+ y: e.clientY - battlefield.getBoundingClientRect().top
1225
+ };
1226
+
1227
+ // Update selection rectangle
1228
+ const left = Math.min(state.selectionStart.x, mousePosition.x);
1229
+ const top = Math.min(state.selectionStart.y, mousePosition.y);
1230
+ const width = Math.abs(mousePosition.x - state.selectionStart.x);
1231
+ const height = Math.abs(mousePosition.y - state.selectionStart.y);
1232
+
1233
+ selectionRectangle.style.display = 'block';
1234
+ selectionRectangle.style.left = `${left}px`;
1235
+ selectionRectangle.style.top = `${top}px`;
1236
+ selectionRectangle.style.width = `${width}px`;
1237
+ selectionRectangle.style.height = `${height}px`;
1238
+ });
1239
+
1240
+ battlefield.addEventListener('mouseup', (e) => {
1241
+ if (state.isSelecting && state.selectionStart) {
1242
+ // Finish area selection
1243
+ state.isSelecting = false;
1244
+ selectionRectangle.style.display = 'none';
1245
+
1246
+ const mousePosition = {
1247
+ x: e.clientX - battlefield.getBoundingClientRect().left,
1248
+ y: e.clientY - battlefield.getBoundingClientRect().top
1249
+ };
1250
+
1251
+ const left = Math.min(state.selectionStart.x, mousePosition.x);
1252
+ const top = Math.min(state.selectionStart.y, mousePosition.y);
1253
+ const right = Math.max(state.selectionStart.x, mousePosition.x);
1254
+ const bottom = Math.max(state.selectionStart.y, mousePosition.y);
1255
+
1256
+ // Find bodies within selection
1257
+ const bodies = Matter.Composite.allBodies(world);
1258
+ const selectedBodies = bodies.filter(body => {
1259
+ if (body.label && (body.label.startsWith('man-') || body.label === 'gorilla')) {
1260
+ const visualElement = state.visualElements[body.label];
1261
+ if (visualElement) {
1262
+ const rect = visualElement.getBoundingClientRect();
1263
+ const elementLeft = rect.left - battlefield.getBoundingClientRect().left;
1264
+ const elementRight = rect.right - battlefield.getBoundingClientRect().left;
1265
+ const elementTop = rect.top - battlefield.getBoundingClientRect().top;
1266
+ const elementBottom = rect.bottom - battlefield.getBoundingClientRect().top;
1267
+
1268
+ return (
1269
+ elementRight > left &&
1270
+ elementLeft < right &&
1271
+ elementBottom > top &&
1272
+ elementTop < bottom
1273
+ );
1274
+ }
1275
+ }
1276
+ return false;
1277
+ });
1278
+
1279
+ // Select the found bodies
1280
+ if (!e.shiftKey) deselectAll();
1281
+ selectedBodies.forEach(body => {
1282
+ selectBody(body.label, true);
1283
+ });
1284
+ }
1285
+
1286
+ state.selectionStart = null;
1287
+ });
1288
+
1289
+ battlefield.addEventListener('mouseleave', () => {
1290
+ if (state.isSelecting) {
1291
+ state.isSelecting = false;
1292
+ selectionRectangle.style.display = 'none';
1293
+ state.selectionStart = null;
1294
+ }
1295
+ });
1296
+
1297
+ // Right click to throw
1298
+ battlefield.addEventListener('contextmenu', (e) => {
1299
+ e.preventDefault();
1300
+
1301
+ if (state.selectedBodies.size > 0) {
1302
+ const mousePosition = {
1303
+ x: e.clientX - battlefield.getBoundingClientRect().left,
1304
+ y: e.clientY - battlefield.getBoundingClientRect().top
1305
+ };
1306
+
1307
+ // Calculate throw direction and force
1308
+ const center = getSelectedCenter();
1309
+ const direction = {
1310
+ x: mousePosition.x - center.x,
1311
+ y: mousePosition.y - center.y
1312
+ };
1313
+
1314
+ const distance = Math.sqrt(direction.x * direction.x + direction.y * direction.y);
1315
+ const normalizedDirection = {
1316
+ x: direction.x / distance,
1317
+ y: direction.y / distance
1318
+ };
1319
+
1320
+ const force = {
1321
+ x: normalizedDirection.x * 5,
1322
+ y: normalizedDirection.y * 5
1323
+ };
1324
+
1325
+ throwSelected(force);
1326
+ }
1327
+ });
1328
+
1329
+ // Get center of selected bodies
1330
+ function getSelectedCenter() {
1331
+ let totalX = 0;
1332
+ let totalY = 0;
1333
+ let count = 0;
1334
+
1335
+ state.selectedBodies.forEach(bodyId => {
1336
+ const body = state.physicsBodies[bodyId];
1337
+ if (body) {
1338
+ totalX += body.position.x;
1339
+ totalY += body.position.y;
1340
+ count++;
1341
+ }
1342
+ });
1343
+
1344
+ return {
1345
+ x: totalX / count,
1346
+ y: totalY / count
1347
+ };
1348
+ }
1349
+
1350
+ // Keyboard controls
1351
+ document.addEventListener('keydown', (e) => {
1352
+ if (e.key === 'Shift') {
1353
+ state.shiftPressed = true;
1354
+ }
1355
+
1356
+ if (e.key === 'Escape') {
1357
+ deselectAll();
1358
+ }
1359
+
1360
+ // Arrow key movement
1361
+ if (state.selectedBodies.size > 0) {
1362
+ const force = { x: 0, y: 0 };
1363
+ const forceAmount = 0.5;
1364
+
1365
+ if (e.key === 'ArrowUp') force.y = -forceAmount;
1366
+ if (e.key === 'ArrowDown') force.y = forceAmount;
1367
+ if (e.key === 'ArrowLeft') force.x = -forceAmount;
1368
+ if (e.key === 'ArrowRight') force.x = forceAmount;
1369
+
1370
+ if (force.x !== 0 || force.y !== 0) {
1371
+ state.selectedBodies.forEach(bodyId => {
1372
+ const body = state.physicsBodies[bodyId];
1373
+ if (body) {
1374
+ Matter.Body.applyForce(body, body.position, force);
1375
+ }
1376
+ });
1377
+ }
1378
+ }
1379
+ });
1380
+
1381
+ document.addEventListener('keyup', (e) => {
1382
+ if (e.key === 'Shift') {
1383
+ state.shiftPressed = false;
1384
+ }
1385
+ });
1386
 
1387
  // Initialize game
1388
+ initializeBattlefield();
1389
  </script>
1390
  <p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=sdurdiyev/100menvs1gorilla" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
1391
  </html>
prompts.txt CHANGED
@@ -1 +1,3 @@
1
- create a game silmulating, 100 men vs 1 gorilla , who wins
 
 
 
1
+ create a game silmulating, 100 men vs 1 gorilla , who wins
2
+ more realistic , ultra realistic
3
+ make them interacible, i wanna select and moce them