zab12 commited on
Commit
bde53c5
·
verified ·
1 Parent(s): 90d63ac

Add 2 files

Browse files
Files changed (2) hide show
  1. README.md +6 -4
  2. index.html +703 -19
README.md CHANGED
@@ -1,10 +1,12 @@
1
  ---
2
- title: Elder Derp
3
- emoji: 🚀
4
- colorFrom: indigo
5
  colorTo: blue
6
  sdk: static
7
  pinned: false
 
 
8
  ---
9
 
10
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
1
  ---
2
+ title: elder-derp
3
+ emoji: 🐳
4
+ colorFrom: blue
5
  colorTo: blue
6
  sdk: static
7
  pinned: false
8
+ tags:
9
+ - deepsite
10
  ---
11
 
12
+ Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
index.html CHANGED
@@ -1,19 +1,703 @@
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>2D Elden Ring</title>
7
+ <style>
8
+ @import url('https://fonts.googleapis.com/css2?family=MedievalSharp&display=swap');
9
+
10
+ * {
11
+ margin: 0;
12
+ padding: 0;
13
+ box-sizing: border-box;
14
+ }
15
+
16
+ body {
17
+ background-color: #111;
18
+ font-family: 'MedievalSharp', cursive;
19
+ overflow: hidden;
20
+ height: 100vh;
21
+ color: #ccc;
22
+ }
23
+
24
+ #game-container {
25
+ position: relative;
26
+ width: 100%;
27
+ height: 100%;
28
+ background: linear-gradient(to bottom, #001a33, #000);
29
+ overflow: hidden;
30
+ }
31
+
32
+ #game-canvas {
33
+ display: block;
34
+ background-color: #000;
35
+ position: absolute;
36
+ top: 0;
37
+ left: 0;
38
+ }
39
+
40
+ #hud {
41
+ position: absolute;
42
+ top: 20px;
43
+ left: 20px;
44
+ z-index: 100;
45
+ color: #fff;
46
+ text-shadow: 0 0 5px #000;
47
+ font-size: 24px;
48
+ }
49
+
50
+ #health-bar {
51
+ width: 200px;
52
+ height: 30px;
53
+ border: 3px solid #500;
54
+ background-color: #300;
55
+ position: relative;
56
+ margin-bottom: 10px;
57
+ }
58
+
59
+ #health-fill {
60
+ height: 100%;
61
+ width: 100%;
62
+ background-color: #f00;
63
+ position: absolute;
64
+ transition: width 0.3s;
65
+ }
66
+
67
+ #stamina-bar {
68
+ width: 200px;
69
+ height: 15px;
70
+ border: 2px solid #060;
71
+ background-color: #030;
72
+ position: relative;
73
+ }
74
+
75
+ #stamina-fill {
76
+ height: 100%;
77
+ width: 100%;
78
+ background-color: #0f0;
79
+ position: absolute;
80
+ transition: width 0.1s;
81
+ }
82
+
83
+ #enemy-info {
84
+ position: absolute;
85
+ top: 20px;
86
+ right: 20px;
87
+ z-index: 100;
88
+ color: #fff;
89
+ text-shadow: 0 0 5px #000;
90
+ font-size: 24px;
91
+ }
92
+
93
+ #title-screen {
94
+ position: absolute;
95
+ top: 0;
96
+ left: 0;
97
+ width: 100%;
98
+ height: 100%;
99
+ background: radial-gradient(circle, rgba(0,0,0,0.9) 0%, rgba(0,0,0,0.95) 100%);
100
+ display: flex;
101
+ flex-direction: column;
102
+ justify-content: center;
103
+ align-items: center;
104
+ z-index: 200;
105
+ }
106
+
107
+ #title {
108
+ font-size: 72px;
109
+ color: #d4af37;
110
+ text-shadow: 0 0 10px #000, 0 0 20px #d4af37;
111
+ margin-bottom: 40px;
112
+ letter-spacing: 5px;
113
+ }
114
+
115
+ #start-button {
116
+ padding: 15px 40px;
117
+ font-size: 24px;
118
+ font-family: 'MedievalSharp', cursive;
119
+ background: linear-gradient(to bottom, #d4af37, #a67c00);
120
+ color: #000;
121
+ border: none;
122
+ border-radius: 5px;
123
+ cursor: pointer;
124
+ transition: all 0.3s;
125
+ box-shadow: 0 5px 15px rgba(0,0,0,0.5);
126
+ }
127
+
128
+ #start-button:hover {
129
+ transform: translateY(-3px);
130
+ box-shadow: 0 8px 20px rgba(0,0,0,0.6);
131
+ }
132
+
133
+ #controls {
134
+ position: absolute;
135
+ bottom: 20px;
136
+ left: 20px;
137
+ font-size: 16px;
138
+ color: #aaa;
139
+ }
140
+
141
+ #message {
142
+ position: absolute;
143
+ top: 50%;
144
+ left: 50%;
145
+ transform: translate(-50%, -50%);
146
+ background-color: rgba(0,0,0,0.7);
147
+ color: #fff;
148
+ padding: 20px 40px;
149
+ border: 2px solid #d4af37;
150
+ border-radius: 5px;
151
+ font-size: 24px;
152
+ z-index: 300;
153
+ display: none;
154
+ }
155
+ </style>
156
+ </head>
157
+ <body>
158
+ <div id="game-container">
159
+ <canvas id="game-canvas"></canvas>
160
+
161
+ <div id="hud">
162
+ <div id="health-bar">
163
+ <div id="health-fill"></div>
164
+ </div>
165
+ <div id="stamina-bar">
166
+ <div id="stamina-fill"></div>
167
+ </div>
168
+ <div id="runes">Runes: 0</div>
169
+ </div>
170
+
171
+ <div id="enemy-info">
172
+ <div id="enemy-health-bar-container">
173
+ <div id="enemy-health-bar"></div>
174
+ </div>
175
+ <div id="enemy-name">—</div>
176
+ </div>
177
+
178
+ <div id="controls">
179
+ <p>WASD: Move | Space: Jump | Left Click: Attack | Shift: Roll</p>
180
+ <p>E: Interact | Q: Use Item | R: Cast Spell</p>
181
+ </div>
182
+
183
+ <div id="title-screen">
184
+ <h1 id="title">ELDEN RING</h1>
185
+ <button id="start-button">START GAME</button>
186
+ </div>
187
+
188
+ <div id="message"></div>
189
+ </div>
190
+
191
+ <script>
192
+ // Game setup
193
+ const canvas = document.getElementById('game-canvas');
194
+ const ctx = canvas.getContext('2d');
195
+ const titleScreen = document.getElementById('title-screen');
196
+ const startButton = document.getElementById('start-button');
197
+ const healthFill = document.getElementById('health-fill');
198
+ const staminaFill = document.getElementById('stamina-fill');
199
+ const runesDisplay = document.getElementById('runes');
200
+ const enemyHealthBar = document.getElementById('enemy-health-bar');
201
+ const enemyNameDisplay = document.getElementById('enemy-name');
202
+ const messageDisplay = document.getElementById('message');
203
+
204
+ // Resize canvas to full window
205
+ function resizeCanvas() {
206
+ canvas.width = window.innerWidth;
207
+ canvas.height = window.innerHeight;
208
+ }
209
+
210
+ resizeCanvas();
211
+ window.addEventListener('resize', resizeCanvas);
212
+
213
+ // Game state
214
+ let gameRunning = false;
215
+ let runes = 0;
216
+ let playerHealth = 100;
217
+ let playerMaxHealth = 100;
218
+ let playerStamina = 100;
219
+ let playerMaxStamina = 100;
220
+ let selectedEnemy = null;
221
+
222
+ // Player properties
223
+ const player = {
224
+ x: canvas.width / 4,
225
+ y: canvas.height / 2,
226
+ width: 60,
227
+ height: 100,
228
+ speed: 5,
229
+ jumpPower: 15,
230
+ isJumping: false,
231
+ isAttacking: false,
232
+ isRolling: false,
233
+ direction: 1, // 1 = right, -1 = left
234
+ velX: 0,
235
+ velY: 0,
236
+ frame: 0,
237
+ attackCooldown: 0,
238
+ rollCooldown: 0,
239
+ invulnerable: 0
240
+ };
241
+
242
+ // Enemy types
243
+ const enemies = [
244
+ {
245
+ name: "Godrick Soldier",
246
+ health: 50,
247
+ maxHealth: 50,
248
+ damage: 10,
249
+ width: 60,
250
+ height: 90,
251
+ speed: 2,
252
+ x: 800,
253
+ y: canvas.height - 100
254
+ },
255
+ {
256
+ name: "Margit's Phantom",
257
+ health: 100,
258
+ maxHealth: 100,
259
+ damage: 20,
260
+ width: 70,
261
+ height: 110,
262
+ speed: 3,
263
+ x: 1200,
264
+ y: canvas.height - 110
265
+ }
266
+ ];
267
+
268
+ // Level elements
269
+ const platforms = [
270
+ { x: 0, y: canvas.height - 50, width: canvas.width * 2, height: 50 },
271
+ { x: 500, y: canvas.height - 200, width: 200, height: 20 },
272
+ { x: 900, y: canvas.height - 300, width: 200, height: 20 }
273
+ ];
274
+
275
+ const bonfire = {
276
+ x: 400,
277
+ y: canvas.height - 70,
278
+ width: 40,
279
+ height: 40,
280
+ lit: false
281
+ };
282
+
283
+ // Start game
284
+ startButton.addEventListener('click', () => {
285
+ titleScreen.style.display = 'none';
286
+ gameRunning = true;
287
+ startGame();
288
+ });
289
+
290
+ function startGame() {
291
+ // Reset player
292
+ player.x = canvas.width / 4;
293
+ player.y = canvas.height / 2;
294
+ player.health = 100;
295
+ player.stamina = 100;
296
+ player.velX = 0;
297
+ player.velY = 0;
298
+ player.isJumping = false;
299
+ player.isAttacking = false;
300
+ player.isRolling = false;
301
+ player.invulnerable = 0;
302
+
303
+ // Reset enemies
304
+ enemies.forEach(enemy => {
305
+ enemy.health = enemy.maxHealth;
306
+ });
307
+
308
+ bonfire.lit = false;
309
+ runes = 0;
310
+ updateHUD();
311
+
312
+ // Start game loop
313
+ gameLoop();
314
+ }
315
+
316
+ // Controls
317
+ const keys = {};
318
+
319
+ document.addEventListener('keydown', (e) => {
320
+ keys[e.key.toLowerCase()] = true;
321
+
322
+ // Quick restart
323
+ if (e.key === '`') {
324
+ if (!gameRunning) {
325
+ titleScreen.style.display = 'none';
326
+ gameRunning = true;
327
+ startGame();
328
+ }
329
+ }
330
+ });
331
+
332
+ document.addEventListener('keyup', (e) => {
333
+ keys[e.key.toLowerCase()] = false;
334
+ });
335
+
336
+ canvas.addEventListener('click', (e) => {
337
+ if (player.attackCooldown <= 0 && player.stamina > 10 && !player.isJumping && gameRunning) {
338
+ player.isAttacking = true;
339
+ player.attackCooldown = 20;
340
+ player.stamina -= 10;
341
+
342
+ // Check if attack hits enemy
343
+ const attackRange = player.direction === 1 ?
344
+ { x: player.x + player.width, y: player.y, width: 50, height: player.height } :
345
+ { x: player.x - 50, y: player.y, width: 50, height: player.height };
346
+
347
+ for (const enemy of enemies) {
348
+ if (checkCollision(attackRange, enemy)) {
349
+ enemy.health -= 20;
350
+ if (enemy.health <= 0) {
351
+ runes += 50;
352
+ enemy.health = 0;
353
+ displayMessage(`${enemy.name} defeated! +50 Runes`);
354
+ }
355
+ updateHUD();
356
+ }
357
+ }
358
+ }
359
+ });
360
+
361
+ // Game loop
362
+ function gameLoop() {
363
+ if (!gameRunning) return;
364
+
365
+ update();
366
+ render();
367
+
368
+ requestAnimationFrame(gameLoop);
369
+ }
370
+
371
+ function update() {
372
+ // Player movement
373
+ if (player.isRolling || player.isAttacking) {
374
+ player.velX *= 0.9;
375
+ } else {
376
+ if (keys['a'] || keys['arrowleft']) {
377
+ player.velX = -player.speed;
378
+ player.direction = -1;
379
+ } else if (keys['d'] || keys['arrowright']) {
380
+ player.velX = player.speed;
381
+ player.direction = 1;
382
+ } else {
383
+ player.velX *= 0.8;
384
+ }
385
+ }
386
+
387
+ // Jumping
388
+ if ((keys['w'] || keys['arrowup'] || keys[' ']) && !player.isJumping && player.velY === 0) {
389
+ player.velY = -player.jumpPower;
390
+ player.isJumping = true;
391
+ }
392
+
393
+ // Rolling
394
+ if (keys['shift'] && !player.isRolling && !player.isAttacking && player.stamina > 15) {
395
+ player.isRolling = true;
396
+ player.rollCooldown = 40;
397
+ player.invulnerable = 30;
398
+ player.stamina -= 15;
399
+ player.velX = player.direction * player.speed * 2;
400
+ }
401
+
402
+ // Gravity
403
+ player.velY += 0.8;
404
+
405
+ // Apply velocity
406
+ player.x += player.velX;
407
+ player.y += player.velY;
408
+
409
+ // Platform collision
410
+ let onGround = false;
411
+ for (const platform of platforms) {
412
+ if (
413
+ player.x < platform.x + platform.width &&
414
+ player.x + player.width > platform.x &&
415
+ player.y < platform.y + platform.height &&
416
+ player.y + player.height > platform.y &&
417
+ player.velY > 0
418
+ ) {
419
+ player.y = platform.y - player.height;
420
+ player.velY = 0;
421
+ player.isJumping = false;
422
+ onGround = true;
423
+ }
424
+ }
425
+
426
+ // Boundary checks
427
+ if (player.x < 0) player.x = 0;
428
+ if (player.x + player.width > canvas.width * 2) player.x = canvas.width * 2 - player.width;
429
+ if (player.y + player.height > canvas.height) {
430
+ player.y = canvas.height - player.height;
431
+ player.velY = 0;
432
+ player.isJumping = false;
433
+ onGround = true;
434
+ }
435
+
436
+ // Check bonfire
437
+ if (
438
+ Math.abs(player.x - bonfire.x) < 50 &&
439
+ Math.abs((player.y + player.height) - (bonfire.y + bonfire.height)) < 50 &&
440
+ keys['e']
441
+ ) {
442
+ if (!bonfire.lit) {
443
+ bonfire.lit = true;
444
+ playerHealth = playerMaxHealth;
445
+ playerStamina = playerMaxStamina;
446
+ displayMessage("Bonfire lit. Health and stamina restored.");
447
+
448
+ // Reset enemies
449
+ enemies.forEach(enemy => {
450
+ enemy.health = enemy.maxHealth;
451
+ });
452
+ }
453
+ }
454
+
455
+ // Enemy updates
456
+ selectedEnemy = null;
457
+ for (const enemy of enemies) {
458
+ if (enemy.health <= 0) continue;
459
+
460
+ // Simple AI - follow player if on same platform
461
+ const playerPlatform = getPlatformUnder(player);
462
+ const enemyPlatform = getPlatformUnder(enemy);
463
+
464
+ if (playerPlatform === enemyPlatform) {
465
+ if (player.x < enemy.x) {
466
+ enemy.x -= enemy.speed;
467
+ } else {
468
+ enemy.x += enemy.speed;
469
+ }
470
+ }
471
+
472
+ // Check if enemy is attacking player
473
+ if (
474
+ Math.abs(player.x - enemy.x) < 80 &&
475
+ Math.abs(player.y - enemy.y) < player.height &&
476
+ player.invulnerable <= 0
477
+ ) {
478
+ if (playerHealth > 0) {
479
+ playerHealth -= enemy.damage;
480
+ player.invulnerable = 30;
481
+ displayMessage(`Hit by ${enemy.name}! -${enemy.damage} HP`);
482
+ if (playerHealth <= 0) {
483
+ playerHealth = 0;
484
+ displayMessage("YOU DIED", 3000);
485
+ setTimeout(() => {
486
+ gameRunning = false;
487
+ titleScreen.style.display = 'flex';
488
+ }, 3000);
489
+ }
490
+ }
491
+ }
492
+
493
+ // Check if player has targeted this enemy
494
+ if (Math.abs(player.x - enemy.x) < 200 && Math.abs(player.y - enemy.y) < 100) {
495
+ selectedEnemy = enemy;
496
+ }
497
+ }
498
+
499
+ // Update cooldowns
500
+ if (player.attackCooldown > 0) player.attackCooldown--;
501
+ else player.isAttacking = false;
502
+
503
+ if (player.rollCooldown > 0) player.rollCooldown--;
504
+ else player.isRolling = false;
505
+
506
+ if (player.invulnerable > 0) player.invulnerable--;
507
+
508
+ // Regenerate stamina when not moving
509
+ if (player.velX === 0 && player.velY === 0 && onGround) {
510
+ playerStamina = Math.min(playerMaxStamina, playerStamina + 0.5);
511
+ } else {
512
+ playerStamina = Math.min(playerMaxStamina, playerStamina + 0.1);
513
+ }
514
+
515
+ updateHUD();
516
+ updateCamera();
517
+ }
518
+
519
+ function getPlatformUnder(entity) {
520
+ for (let i = 0; i < platforms.length; i++) {
521
+ if (
522
+ entity.x + entity.width > platforms[i].x &&
523
+ entity.x < platforms[i].x + platforms[i].width &&
524
+ Math.abs((entity.y + entity.height) - platforms[i].y) < 5
525
+ ) {
526
+ return i;
527
+ }
528
+ }
529
+ return -1;
530
+ }
531
+
532
+ function updateHUD() {
533
+ healthFill.style.width = `${(playerHealth / playerMaxHealth) * 100}%`;
534
+ staminaFill.style.width = `${(playerStamina / playerMaxStamina) * 100}%`;
535
+ runesDisplay.textContent = `Runes: ${runes}`;
536
+
537
+ if (selectedEnemy) {
538
+ enemyHealthBar.style.width = `${(selectedEnemy.health / selectedEnemy.maxHealth) * 100}%`;
539
+ enemyHealthBar.style.backgroundColor = selectedEnemy.health > 50 ? '#0f0' :
540
+ selectedEnemy.health > 25 ? '#ff0' : '#f00';
541
+ enemyNameDisplay.textContent = selectedEnemy.name;
542
+ } else {
543
+ enemyHealthBar.style.width = '0%';
544
+ enemyNameDisplay.textContent = '—';
545
+ }
546
+ }
547
+
548
+ let cameraX = 0;
549
+
550
+ function updateCamera() {
551
+ // Simple camera follow with some lead space
552
+ cameraX = player.x - canvas.width / 4;
553
+ cameraX = Math.max(0, Math.min(canvas.width * 2 - canvas.width, cameraX));
554
+ }
555
+
556
+ function displayMessage(text, duration = 1500) {
557
+ messageDisplay.textContent = text;
558
+ messageDisplay.style.display = 'block';
559
+ setTimeout(() => {
560
+ messageDisplay.style.display = 'none';
561
+ }, duration);
562
+ }
563
+
564
+ function checkCollision(rect1, rect2) {
565
+ return (
566
+ rect1.x < rect2.x + rect2.width &&
567
+ rect1.x + rect1.width > rect2.x &&
568
+ rect1.y < rect2.y + rect2.height &&
569
+ rect1.y + rect1.height > rect2.y
570
+ );
571
+ }
572
+
573
+ function render() {
574
+ // Clear canvas
575
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
576
+
577
+ // Draw background
578
+ if (canvas.width >= 768) { // Only draw detailed background on larger screens
579
+ // Stars
580
+ ctx.fillStyle = '#fff';
581
+ for (let i = 0; i < 100; i++) {
582
+ const x = (i * 300 + (Math.sin(Date.now() / 1000 + i) * 100)) % (canvas.width * 2);
583
+ const y = (Math.sin(i) * 100 + i * 50) % canvas.height;
584
+ const size = 1 + Math.random();
585
+ ctx.fillRect(x - cameraX, y, size, size);
586
+ }
587
+
588
+ // Moon
589
+ ctx.beginPath();
590
+ ctx.arc(
591
+ 200 - cameraX * 0.2,
592
+ 200,
593
+ 50,
594
+ 0,
595
+ Math.PI * 2
596
+ );
597
+ ctx.fillStyle = '#d4af37';
598
+ ctx.fill();
599
+ }
600
+
601
+ // Draw platforms
602
+ ctx.fillStyle = '#654321';
603
+ for (const platform of platforms) {
604
+ ctx.fillRect(platform.x - cameraX, platform.y, platform.width, platform.height);
605
+ }
606
+
607
+ // Draw bonfire
608
+ ctx.fillStyle = bonfire.lit ? '#f80' : '#666';
609
+ ctx.fillRect(bonfire.x - cameraX, bonfire.y, bonfire.width, bonfire.height);
610
+
611
+ // Draw enemies
612
+ for (const enemy of enemies) {
613
+ if (enemy.health <= 0) continue;
614
+
615
+ // Enemy body
616
+ ctx.fillStyle = enemy.name.includes('Margit') ? '#0af' : '#864';
617
+ ctx.fillRect(enemy.x - cameraX, enemy.y, enemy.width, enemy.height);
618
+
619
+ // Enemy head
620
+ ctx.fillStyle = '#fff';
621
+ ctx.beginPath();
622
+ ctx.arc(
623
+ enemy.x - cameraX + enemy.width / 2,
624
+ enemy.y - 10,
625
+ 15,
626
+ 0,
627
+ Math.PI * 2
628
+ );
629
+ ctx.fill();
630
+
631
+ // Enemy weapon
632
+ ctx.fillStyle = '#555';
633
+ ctx.fillRect(
634
+ enemy.x - cameraX + (enemy.x < player.x ? enemy.width : -20),
635
+ enemy.y + enemy.height / 2,
636
+ 30,
637
+ 5
638
+ );
639
+ }
640
+
641
+ // Draw player
642
+ if (player.invulnerable > 0 && Math.floor(player.invulnerable / 5) % 2 === 0) {
643
+ ctx.fillStyle = 'rgba(255, 255, 255, 0.5)';
644
+ } else {
645
+ ctx.fillStyle = player.isRolling ? '#369' : '#47a';
646
+ }
647
+
648
+ ctx.fillRect(player.x - cameraX, player.y, player.width, player.height);
649
+
650
+ // Player head
651
+ ctx.fillStyle = '#fff';
652
+ ctx.beginPath();
653
+ ctx.arc(
654
+ player.x - cameraX + player.width / 2,
655
+ player.y - 10,
656
+ 20,
657
+ 0,
658
+ Math.PI * 2
659
+ );
660
+ ctx.fill();
661
+
662
+ // Player weapon
663
+ ctx.fillStyle = '#d4af37';
664
+ if (player.isAttacking) {
665
+ ctx.fillRect(
666
+ player.x - cameraX + (player.direction === 1 ? player.width : -40),
667
+ player.y + player.height / 2,
668
+ 40,
669
+ 8
670
+ );
671
+ } else {
672
+ ctx.fillRect(
673
+ player.x - cameraX + (player.direction === 1 ? 10 : player.width - 30),
674
+ player.y + player.height / 2,
675
+ 20,
676
+ 4
677
+ );
678
+ }
679
+
680
+ // Draw erdtree in background
681
+ if (canvas.width >= 768) {
682
+ ctx.fillStyle = 'rgba(0, 180, 60, 0.3)';
683
+ ctx.beginPath();
684
+ ctx.moveTo(1800 - cameraX * 0.1, canvas.height);
685
+ ctx.lineTo(1850 - cameraX * 0.1, canvas.height - 150);
686
+ ctx.lineTo(1900 - cameraX * 0.1, canvas.height - 300);
687
+ ctx.lineTo(1950 - cameraX * 0.1, canvas.height - 450);
688
+ ctx.lineTo(2000 - cameraX * 0.1, canvas.height - 600);
689
+ ctx.lineTo(1950 - cameraX * 0.1, canvas.height - 450);
690
+ ctx.lineTo(1900 - cameraX * 0.1, canvas.height - 300);
691
+ ctx.lineTo(1850 - cameraX * 0.1, canvas.height - 150);
692
+ ctx.lineTo(1800 - cameraX * 0.1, canvas.height);
693
+ ctx.fill();
694
+
695
+ ctx.fillStyle = 'rgba(200, 180, 0, 0.6)';
696
+ ctx.beginPath();
697
+ ctx.arc(2000 - cameraX * 0.1, canvas.height - 650, 100, 0, Math.PI * 2);
698
+ ctx.fill();
699
+ }
700
+ }
701
+ </script>
702
+ <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 <a href="https://enzostvs-deepsite.hf.space" style="color: #fff;" target="_blank" >DeepSite</a> <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;"></p></body>
703
+ </html>