Aleksmorshen commited on
Commit
e0245e2
·
verified ·
1 Parent(s): cacc3d1

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +288 -31
index.html CHANGED
@@ -2,7 +2,7 @@
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>Doom-Style 3D Shooter</title>
7
  <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
8
  <script src="https://cdn.jsdelivr.net/npm/[email protected]/examples/js/controls/PointerLockControls.min.js"></script>
@@ -12,6 +12,7 @@
12
  padding: 0;
13
  box-sizing: border-box;
14
  font-family: 'Courier New', monospace;
 
15
  }
16
 
17
  body {
@@ -258,6 +259,79 @@
258
  opacity: 0;
259
  z-index: 5;
260
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
261
  </style>
262
  </head>
263
  <body>
@@ -276,6 +350,15 @@
276
  <div id="bloodEffect"></div>
277
  </div>
278
 
 
 
 
 
 
 
 
 
 
279
  <div id="startScreen">
280
  <h1 id="title">DEMON SLAYER</h1>
281
  <p id="subtitle">Eliminate all demons to survive</p>
@@ -306,6 +389,12 @@
306
  let shotCooldown = 300; // ms
307
  let enemySpawnTimer = 0;
308
  let clock = new THREE.Clock();
 
 
 
 
 
 
309
 
310
  // Initialize the game
311
  function init() {
@@ -357,14 +446,21 @@
357
  scene.add(player);
358
  player.add(camera);
359
 
360
- // Add pointer lock controls
361
- controls = new THREE.PointerLockControls(camera, document.body);
 
 
362
 
363
  // Event listeners
364
- document.addEventListener('keydown', onKeyDown, false);
365
- document.addEventListener('keyup', onKeyUp, false);
366
- document.addEventListener('mousedown', onMouseDown, false);
367
- document.addEventListener('mousemove', onMouseMove, false);
 
 
 
 
 
368
  window.addEventListener('resize', onWindowResize, false);
369
 
370
  // Start button event
@@ -436,26 +532,107 @@
436
  });
437
  }
438
 
439
- function spawnEnemy() {
440
- const enemyGeometry = new THREE.ConeGeometry(1, 3, 8);
441
- const enemyMaterial = new THREE.MeshStandardMaterial({
 
 
 
 
442
  color: 0x880000,
443
- roughness: 0.8,
444
- metalness: 0.2
445
  });
446
-
447
- const enemy = new THREE.Mesh(enemyGeometry, enemyMaterial);
448
- enemy.position.set(
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
449
  (Math.random() - 0.5) * 40,
450
- 1.5,
451
  (Math.random() - 0.5) * 40
452
  );
453
- enemy.rotation.y = Math.random() * Math.PI * 2;
454
- enemy.castShadow = true;
455
- scene.add(enemy);
456
 
457
  enemies.push({
458
- mesh: enemy,
459
  health: 100,
460
  speed: 0.02 + Math.random() * 0.03,
461
  lastAttack: 0,
@@ -465,7 +642,9 @@
465
 
466
  function startGame() {
467
  document.getElementById('startScreen').style.display = 'none';
468
- controls.lock();
 
 
469
  gameActive = true;
470
 
471
  // Spawn initial enemies
@@ -501,13 +680,17 @@
501
  spawnEnemy();
502
  }
503
 
504
- controls.lock();
 
 
505
  gameActive = true;
506
  }
507
 
508
  function gameOver() {
509
  gameActive = false;
510
- controls.unlock();
 
 
511
  document.getElementById('finalScore').textContent = `SCORE: ${score}`;
512
  document.getElementById('gameOverScreen').style.display = 'flex';
513
  }
@@ -547,7 +730,7 @@
547
  }
548
 
549
  function onMouseMove(event) {
550
- if (!gameActive) return;
551
 
552
  // Add weapon sway effect
553
  const weapon = document.getElementById('weapon');
@@ -607,6 +790,70 @@
607
  }, 50);
608
  }
609
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
610
  function onWindowResize() {
611
  camera.aspect = window.innerWidth / window.innerHeight;
612
  camera.updateProjectionMatrix();
@@ -621,10 +868,20 @@
621
  if (gameActive) {
622
  // Player movement
623
  const speed = 0.1;
624
- if (moveForward) player.translateZ(-speed);
625
- if (moveBackward) player.translateZ(speed);
626
- if (moveLeft) player.translateX(-speed);
627
- if (moveRight) player.translateX(speed);
 
 
 
 
 
 
 
 
 
 
628
 
629
  // Keep player within bounds
630
  player.position.x = Math.max(-24, Math.min(24, player.position.x));
@@ -707,10 +964,10 @@
707
  bullets.splice(i, 1);
708
 
709
  // Enemy hit effect
710
- enemy.mesh.material.color.set(0xff0000);
711
  setTimeout(() => {
712
- if (enemy.mesh) {
713
- enemy.mesh.material.color.set(0x880000);
714
  }
715
  }, 100);
716
 
 
2
  <html lang="en">
3
  <head>
4
  <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
6
  <title>Doom-Style 3D Shooter</title>
7
  <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
8
  <script src="https://cdn.jsdelivr.net/npm/[email protected]/examples/js/controls/PointerLockControls.min.js"></script>
 
12
  padding: 0;
13
  box-sizing: border-box;
14
  font-family: 'Courier New', monospace;
15
+ touch-action: none;
16
  }
17
 
18
  body {
 
259
  opacity: 0;
260
  z-index: 5;
261
  }
262
+
263
+ /* Mobile Controls */
264
+ #mobileControls {
265
+ position: absolute;
266
+ bottom: 20px;
267
+ width: 100%;
268
+ display: none;
269
+ justify-content: space-between;
270
+ padding: 0 20px;
271
+ z-index: 10;
272
+ pointer-events: none;
273
+ }
274
+
275
+ .controlPad {
276
+ width: 120px;
277
+ height: 120px;
278
+ background: rgba(255, 0, 0, 0.3);
279
+ border-radius: 50%;
280
+ display: flex;
281
+ justify-content: center;
282
+ align-items: center;
283
+ pointer-events: auto;
284
+ }
285
+
286
+ .controlStick {
287
+ width: 50px;
288
+ height: 50px;
289
+ background: rgba(255, 85, 85, 0.7);
290
+ border-radius: 50%;
291
+ position: relative;
292
+ }
293
+
294
+ #shootButton {
295
+ width: 80px;
296
+ height: 80px;
297
+ background: rgba(255, 0, 0, 0.5);
298
+ border-radius: 50%;
299
+ display: flex;
300
+ justify-content: center;
301
+ align-items: center;
302
+ font-size: 24px;
303
+ color: white;
304
+ pointer-events: auto;
305
+ border: 2px solid #ff5555;
306
+ }
307
+
308
+ #instructions {
309
+ position: absolute;
310
+ bottom: 160px;
311
+ width: 100%;
312
+ text-align: center;
313
+ color: #ff9999;
314
+ font-size: 18px;
315
+ padding: 0 20px;
316
+ }
317
+
318
+ @media (max-width: 768px) {
319
+ #mobileControls {
320
+ display: flex;
321
+ }
322
+
323
+ #instructions {
324
+ display: block;
325
+ }
326
+
327
+ #title {
328
+ font-size: 48px;
329
+ }
330
+
331
+ #subtitle {
332
+ font-size: 18px;
333
+ }
334
+ }
335
  </style>
336
  </head>
337
  <body>
 
350
  <div id="bloodEffect"></div>
351
  </div>
352
 
353
+ <div id="mobileControls">
354
+ <div class="controlPad" id="movementPad">
355
+ <div class="controlStick" id="movementStick"></div>
356
+ </div>
357
+ <div id="shootButton">FIRE</div>
358
+ </div>
359
+
360
+ <div id="instructions">Use joystick to move, tap FIRE to shoot</div>
361
+
362
  <div id="startScreen">
363
  <h1 id="title">DEMON SLAYER</h1>
364
  <p id="subtitle">Eliminate all demons to survive</p>
 
389
  let shotCooldown = 300; // ms
390
  let enemySpawnTimer = 0;
391
  let clock = new THREE.Clock();
392
+ let isMobile = /iPhone|iPad|iPod|Android/i.test(navigator.userAgent);
393
+
394
+ // Mobile controls
395
+ let movementStickActive = false;
396
+ let movementStickPosition = { x: 0, y: 0 };
397
+ let movementStickRadius = 35;
398
 
399
  // Initialize the game
400
  function init() {
 
446
  scene.add(player);
447
  player.add(camera);
448
 
449
+ // Add pointer lock controls for desktop
450
+ if (!isMobile) {
451
+ controls = new THREE.PointerLockControls(camera, document.body);
452
+ }
453
 
454
  // Event listeners
455
+ if (!isMobile) {
456
+ document.addEventListener('keydown', onKeyDown, false);
457
+ document.addEventListener('keyup', onKeyUp, false);
458
+ document.addEventListener('mousedown', onMouseDown, false);
459
+ document.addEventListener('mousemove', onMouseMove, false);
460
+ } else {
461
+ setupMobileControls();
462
+ }
463
+
464
  window.addEventListener('resize', onWindowResize, false);
465
 
466
  // Start button event
 
532
  });
533
  }
534
 
535
+ // Create a detailed demon model
536
+ function createDemon() {
537
+ const demonGroup = new THREE.Group();
538
+
539
+ // Body
540
+ const bodyGeometry = new THREE.SphereGeometry(0.8, 16, 16);
541
+ const bodyMaterial = new THREE.MeshStandardMaterial({
542
  color: 0x880000,
543
+ roughness: 0.7,
544
+ metalness: 0.3
545
  });
546
+ const body = new THREE.Mesh(bodyGeometry, bodyMaterial);
547
+ body.position.y = 1;
548
+ body.castShadow = true;
549
+ demonGroup.add(body);
550
+
551
+ // Head
552
+ const headGeometry = new THREE.SphereGeometry(0.6, 16, 16);
553
+ const headMaterial = new THREE.MeshStandardMaterial({
554
+ color: 0xaa0000,
555
+ roughness: 0.7,
556
+ metalness: 0.3
557
+ });
558
+ const head = new THREE.Mesh(headGeometry, headMaterial);
559
+ head.position.y = 1.8;
560
+ head.castShadow = true;
561
+ demonGroup.add(head);
562
+
563
+ // Horns
564
+ const hornGeometry = new THREE.ConeGeometry(0.1, 0.8, 8);
565
+ const hornMaterial = new THREE.MeshStandardMaterial({ color: 0x333333 });
566
+
567
+ const horn1 = new THREE.Mesh(hornGeometry, hornMaterial);
568
+ horn1.position.set(-0.2, 2.3, 0);
569
+ horn1.rotation.z = Math.PI / 6;
570
+ horn1.castShadow = true;
571
+ demonGroup.add(horn1);
572
+
573
+ const horn2 = new THREE.Mesh(hornGeometry, hornMaterial);
574
+ horn2.position.set(0.2, 2.3, 0);
575
+ horn2.rotation.z = -Math.PI / 6;
576
+ horn2.castShadow = true;
577
+ demonGroup.add(horn2);
578
+
579
+ // Eyes
580
+ const eyeGeometry = new THREE.SphereGeometry(0.15, 8, 8);
581
+ const eyeMaterial = new THREE.MeshStandardMaterial({ color: 0xffff00 });
582
+
583
+ const eye1 = new THREE.Mesh(eyeGeometry, eyeMaterial);
584
+ eye1.position.set(-0.25, 1.9, 0.4);
585
+ demonGroup.add(eye1);
586
+
587
+ const eye2 = new THREE.Mesh(eyeGeometry, eyeMaterial);
588
+ eye2.position.set(0.25, 1.9, 0.4);
589
+ demonGroup.add(eye2);
590
+
591
+ // Arms
592
+ const armGeometry = new THREE.CylinderGeometry(0.15, 0.15, 1.2, 8);
593
+ const armMaterial = new THREE.MeshStandardMaterial({ color: 0x770000 });
594
+
595
+ const arm1 = new THREE.Mesh(armGeometry, armMaterial);
596
+ arm1.position.set(-0.9, 1, 0);
597
+ arm1.rotation.z = Math.PI / 4;
598
+ arm1.castShadow = true;
599
+ demonGroup.add(arm1);
600
+
601
+ const arm2 = new THREE.Mesh(armGeometry, armMaterial);
602
+ arm2.position.set(0.9, 1, 0);
603
+ arm2.rotation.z = -Math.PI / 4;
604
+ arm2.castShadow = true;
605
+ demonGroup.add(arm2);
606
+
607
+ // Legs
608
+ const legGeometry = new THREE.CylinderGeometry(0.2, 0.2, 1, 8);
609
+ const legMaterial = new THREE.MeshStandardMaterial({ color: 0x660000 });
610
+
611
+ const leg1 = new THREE.Mesh(legGeometry, legMaterial);
612
+ leg1.position.set(-0.4, 0.3, 0);
613
+ leg1.castShadow = true;
614
+ demonGroup.add(leg1);
615
+
616
+ const leg2 = new THREE.Mesh(legGeometry, legMaterial);
617
+ leg2.position.set(0.4, 0.3, 0);
618
+ leg2.castShadow = true;
619
+ demonGroup.add(leg2);
620
+
621
+ return demonGroup;
622
+ }
623
+
624
+ function spawnEnemy() {
625
+ const demon = createDemon();
626
+ demon.position.set(
627
  (Math.random() - 0.5) * 40,
628
+ 0,
629
  (Math.random() - 0.5) * 40
630
  );
631
+ demon.rotation.y = Math.random() * Math.PI * 2;
632
+ scene.add(demon);
 
633
 
634
  enemies.push({
635
+ mesh: demon,
636
  health: 100,
637
  speed: 0.02 + Math.random() * 0.03,
638
  lastAttack: 0,
 
642
 
643
  function startGame() {
644
  document.getElementById('startScreen').style.display = 'none';
645
+ if (!isMobile) {
646
+ controls.lock();
647
+ }
648
  gameActive = true;
649
 
650
  // Spawn initial enemies
 
680
  spawnEnemy();
681
  }
682
 
683
+ if (!isMobile) {
684
+ controls.lock();
685
+ }
686
  gameActive = true;
687
  }
688
 
689
  function gameOver() {
690
  gameActive = false;
691
+ if (!isMobile) {
692
+ controls.unlock();
693
+ }
694
  document.getElementById('finalScore').textContent = `SCORE: ${score}`;
695
  document.getElementById('gameOverScreen').style.display = 'flex';
696
  }
 
730
  }
731
 
732
  function onMouseMove(event) {
733
+ if (!gameActive || isMobile) return;
734
 
735
  // Add weapon sway effect
736
  const weapon = document.getElementById('weapon');
 
790
  }, 50);
791
  }
792
 
793
+ function setupMobileControls() {
794
+ const movementPad = document.getElementById('movementPad');
795
+ const movementStick = document.getElementById('movementStick');
796
+ const shootButton = document.getElementById('shootButton');
797
+
798
+ // Movement pad touch events
799
+ movementPad.addEventListener('touchstart', (e) => {
800
+ movementStickActive = true;
801
+ updateMovementStick(e.touches[0]);
802
+ });
803
+
804
+ movementPad.addEventListener('touchmove', (e) => {
805
+ if (movementStickActive) {
806
+ e.preventDefault();
807
+ updateMovementStick(e.touches[0]);
808
+ }
809
+ });
810
+
811
+ movementPad.addEventListener('touchend', () => {
812
+ movementStickActive = false;
813
+ movementStickPosition = { x: 0, y: 0 };
814
+ movementStick.style.transform = 'translate(0, 0)';
815
+ moveForward = false;
816
+ moveBackward = false;
817
+ moveLeft = false;
818
+ moveRight = false;
819
+ });
820
+
821
+ // Shoot button touch events
822
+ shootButton.addEventListener('touchstart', (e) => {
823
+ e.preventDefault();
824
+ if (gameActive && ammo > 0 && canShoot) {
825
+ shoot();
826
+ canShoot = false;
827
+ setTimeout(() => { canShoot = true; }, shotCooldown);
828
+ }
829
+ });
830
+
831
+ function updateMovementStick(touch) {
832
+ const padRect = movementPad.getBoundingClientRect();
833
+ const centerX = padRect.left + padRect.width / 2;
834
+ const centerY = padRect.top + padRect.height / 2;
835
+
836
+ let deltaX = touch.clientX - centerX;
837
+ let deltaY = touch.clientY - centerY;
838
+
839
+ // Limit to pad radius
840
+ const distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
841
+ if (distance > movementStickRadius) {
842
+ deltaX = deltaX * movementStickRadius / distance;
843
+ deltaY = deltaY * movementStickRadius / distance;
844
+ }
845
+
846
+ movementStickPosition = { x: deltaX, y: deltaY };
847
+ movementStick.style.transform = `translate(${deltaX}px, ${deltaY}px)`;
848
+
849
+ // Update movement flags
850
+ moveForward = deltaY < -10;
851
+ moveBackward = deltaY > 10;
852
+ moveLeft = deltaX < -10;
853
+ moveRight = deltaX > 10;
854
+ }
855
+ }
856
+
857
  function onWindowResize() {
858
  camera.aspect = window.innerWidth / window.innerHeight;
859
  camera.updateProjectionMatrix();
 
868
  if (gameActive) {
869
  // Player movement
870
  const speed = 0.1;
871
+
872
+ if (isMobile) {
873
+ // Mobile movement based on joystick
874
+ if (moveForward) player.translateZ(-speed);
875
+ if (moveBackward) player.translateZ(speed);
876
+ if (moveLeft) player.translateX(-speed);
877
+ if (moveRight) player.translateX(speed);
878
+ } else {
879
+ // Desktop movement
880
+ if (moveForward) player.translateZ(-speed);
881
+ if (moveBackward) player.translateZ(speed);
882
+ if (moveLeft) player.translateX(-speed);
883
+ if (moveRight) player.translateX(speed);
884
+ }
885
 
886
  // Keep player within bounds
887
  player.position.x = Math.max(-24, Math.min(24, player.position.x));
 
964
  bullets.splice(i, 1);
965
 
966
  // Enemy hit effect
967
+ enemy.mesh.children[0].material.color.set(0xff0000);
968
  setTimeout(() => {
969
+ if (enemy.mesh && enemy.mesh.children[0]) {
970
+ enemy.mesh.children[0].material.color.set(0x880000);
971
  }
972
  }, 100);
973