KBLLR commited on
Commit
e70468a
·
verified ·
1 Parent(s): 53b06e3

I think the controller is not working propperly, can you make it more robust?

Browse files
Files changed (1) hide show
  1. index.html +124 -51
index.html CHANGED
@@ -453,12 +453,11 @@ function addEnvironmentObjects() {
453
 
454
  group.position.y = 0;
455
  scene.add(group);
456
-
457
  gameState.player = {
458
  model: group,
459
- speed: 0.1,
460
- runSpeed: 0.2,
461
- rotationSpeed: 0.05,
462
  isMoving: false,
463
  animations: {
464
  idle: null,
@@ -468,8 +467,7 @@ function addEnvironmentObjects() {
468
  },
469
  currentAnimation: null
470
  };
471
-
472
- // Add a simple animation mixer for the player
473
  mixer = new THREE.AnimationMixer(group);
474
 
475
  // Create simple animations
@@ -600,7 +598,7 @@ function loadNPCCharacters() {
600
  function animate() {
601
  requestAnimationFrame(animate);
602
 
603
- const delta = clock.getDelta();
604
 
605
  // Update player animation mixer
606
  if (mixer) {
@@ -615,13 +613,24 @@ function loadNPCCharacters() {
615
 
616
  renderer.render(scene, camera);
617
  }
618
- function handlePlayerMovement(delta) {
619
  if (!gameState.player) return;
620
 
621
  const player = gameState.player;
622
  let moving = false;
623
  let moveDirection = new THREE.Vector3();
624
 
 
 
 
 
 
 
 
 
 
 
 
625
  // Forward/backward movement
626
  if (gameState.keys.w) {
627
  moveDirection.z = -1;
@@ -646,50 +655,73 @@ function loadNPCCharacters() {
646
  if (moving) {
647
  moveDirection.normalize();
648
 
649
- // Calculate speed
650
- const speed = gameState.keys.shift ? player.runSpeed : player.speed;
651
 
652
- // Apply movement relative to player's rotation
653
- const forward = new THREE.Vector3(0, 0, -1);
654
- forward.applyQuaternion(player.model.quaternion);
655
- forward.y = 0;
656
- forward.normalize();
657
 
658
- const right = new THREE.Vector3(1, 0, 0);
659
- right.applyQuaternion(player.model.quaternion);
660
- right.y = 0;
661
- right.normalize();
662
 
663
  const moveVector = new THREE.Vector3();
664
- moveVector.addScaledVector(forward, moveDirection.z * speed);
665
- moveVector.addScaledVector(right, moveDirection.x * speed);
666
 
667
  player.model.position.add(moveVector);
668
 
669
- // Update rotation only if moving significantly
670
  if (moveDirection.length() > 0.1) {
671
- const targetRotation = Math.atan2(moveDirection.x, moveDirection.z);
672
- player.model.rotation.y = targetRotation;
673
  }
674
  }
 
675
  // Jumping - only trigger when not showing dialog and not already jumping
676
- if (gameState.keys.space && !gameState.isJumping && !document.getElementById('dialog-box').classList.contains('translate-y-full')) {
677
  gameState.isJumping = true;
678
  setPlayerAnimation('jump');
679
- setTimeout(() => {
680
- gameState.isJumping = false;
681
- updatePlayerAnimation();
682
- }, 1000);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
683
  }
684
- // Update animation based on movement
 
685
  if (moving !== player.isMoving || gameState.keys.shift) {
686
  player.isMoving = moving;
687
  updatePlayerAnimation();
688
  }
689
 
690
- // Update camera position to follow player
691
- const cameraOffset = new THREE.Vector3(0, 5, 10);
692
- camera.position.copy(player.model.position.clone().add(cameraOffset));
693
  camera.lookAt(player.model.position);
694
  }
695
  function updatePlayerAnimation() {
@@ -769,32 +801,73 @@ function showDialog(npc) {
769
  existingPrompt.remove();
770
  }
771
  }
772
- function handleKeyDown(event) {
773
- switch (event.key.toLowerCase()) {
774
- case 'w': gameState.keys.w = true; break;
775
- case 'a': gameState.keys.a = true; break;
776
- case 's': gameState.keys.s = true; break;
777
- case 'd': gameState.keys.d = true; break;
778
- case 'shift': gameState.keys.shift = true; break;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
779
  case ' ':
780
  gameState.keys.space = true;
781
- if (gameState.nearbyNpc && !gameState.isJumping) {
 
 
782
  showDialog(gameState.nearbyNpc);
783
- event.preventDefault(); // Prevent default space behavior
784
  }
785
  break;
786
  }
787
  }
788
- function handleKeyUp(event) {
789
- switch (event.key.toLowerCase()) {
790
- case 'w': gameState.keys.w = false; break;
791
- case 'a': gameState.keys.a = false; break;
792
- case 's': gameState.keys.s = false; break;
793
- case 'd': gameState.keys.d = false; break;
794
- case 'shift': gameState.keys.shift = false; break;
795
- case ' ': gameState.keys.space = false; break;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
796
  }
797
  }
798
- </script>
799
  <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=KBLLR/character-selector" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
800
  </html>
 
453
 
454
  group.position.y = 0;
455
  scene.add(group);
 
456
  gameState.player = {
457
  model: group,
458
+ speed: 0.08,
459
+ runSpeed: 0.15,
460
+ rotationSpeed: 0.08,
461
  isMoving: false,
462
  animations: {
463
  idle: null,
 
467
  },
468
  currentAnimation: null
469
  };
470
+ // Add a simple animation mixer for the player
 
471
  mixer = new THREE.AnimationMixer(group);
472
 
473
  // Create simple animations
 
598
  function animate() {
599
  requestAnimationFrame(animate);
600
 
601
+ const delta = Math.min(clock.getDelta(), 0.1); // Cap delta to prevent large jumps
602
 
603
  // Update player animation mixer
604
  if (mixer) {
 
613
 
614
  renderer.render(scene, camera);
615
  }
616
+ function handlePlayerMovement(delta) {
617
  if (!gameState.player) return;
618
 
619
  const player = gameState.player;
620
  let moving = false;
621
  let moveDirection = new THREE.Vector3();
622
 
623
+ // Check if dialog is open - disable movement if dialog is active
624
+ const isDialogOpen = !document.getElementById('dialog-box').classList.contains('translate-y-full');
625
+ if (isDialogOpen) {
626
+ // Stop any movement and reset animation
627
+ if (player.isMoving) {
628
+ player.isMoving = false;
629
+ updatePlayerAnimation();
630
+ }
631
+ return;
632
+ }
633
+
634
  // Forward/backward movement
635
  if (gameState.keys.w) {
636
  moveDirection.z = -1;
 
655
  if (moving) {
656
  moveDirection.normalize();
657
 
658
+ // Calculate speed with delta time for consistent movement
659
+ const speed = (gameState.keys.shift ? player.runSpeed : player.speed) * delta * 60;
660
 
661
+ // Apply movement relative to camera direction
662
+ const cameraForward = new THREE.Vector3();
663
+ camera.getWorldDirection(cameraForward);
664
+ cameraForward.y = 0;
665
+ cameraForward.normalize();
666
 
667
+ const cameraRight = new THREE.Vector3();
668
+ cameraRight.crossVectors(cameraForward, new THREE.Vector3(0, 1, 0));
669
+ cameraRight.normalize();
 
670
 
671
  const moveVector = new THREE.Vector3();
672
+ moveVector.addScaledVector(cameraForward, moveDirection.z * speed);
673
+ moveVector.addScaledVector(cameraRight, moveDirection.x * speed);
674
 
675
  player.model.position.add(moveVector);
676
 
677
+ // Update player rotation to face movement direction
678
  if (moveDirection.length() > 0.1) {
679
+ const targetRotation = Math.atan2(moveDirection.x, moveDirection.z) + camera.rotation.y;
680
+ player.model.rotation.y = THREE.MathUtils.lerp(player.model.rotation.y, targetRotation, player.rotationSpeed * delta * 60);
681
  }
682
  }
683
+
684
  // Jumping - only trigger when not showing dialog and not already jumping
685
+ if (gameState.keys.space && !gameState.isJumping && !isDialogOpen) {
686
  gameState.isJumping = true;
687
  setPlayerAnimation('jump');
688
+
689
+ // Create a more robust jump animation
690
+ let jumpStartTime = performance.now();
691
+ const jumpDuration = 1000; // 1 second
692
+ const originalY = player.model.position.y;
693
+ const jumpHeight = 1.5;
694
+
695
+ function performJump() {
696
+ const currentTime = performance.now();
697
+ const elapsed = currentTime - jumpStartTime;
698
+ const progress = Math.min(elapsed / jumpDuration, 1);
699
+
700
+ // Parabolic jump curve
701
+ const jumpProgress = 1 - Math.pow(2 * progress - 1, 2);
702
+ player.model.position.y = originalY + jumpHeight * jumpProgress;
703
+
704
+ if (progress < 1) {
705
+ requestAnimationFrame(performJump);
706
+ } else {
707
+ gameState.isJumping = false;
708
+ player.model.position.y = originalY;
709
+ updatePlayerAnimation();
710
+ }
711
+ }
712
+
713
+ performJump();
714
  }
715
+
716
+ // Update animation based on movement
717
  if (moving !== player.isMoving || gameState.keys.shift) {
718
  player.isMoving = moving;
719
  updatePlayerAnimation();
720
  }
721
 
722
+ // Update camera position to follow player with smooth interpolation
723
+ const targetCameraPosition = player.model.position.clone().add(new THREE.Vector3(0, 5, 10));
724
+ camera.position.lerp(targetCameraPosition, 0.1 * delta * 60);
725
  camera.lookAt(player.model.position);
726
  }
727
  function updatePlayerAnimation() {
 
801
  existingPrompt.remove();
802
  }
803
  }
804
+ function handleKeyDown(event) {
805
+ // Prevent default for space to avoid page scrolling
806
+ if (event.key === ' ') {
807
+ event.preventDefault();
808
+ }
809
+
810
+ // Ignore key repeats
811
+ if (event.repeat) return;
812
+
813
+ const key = event.key.toLowerCase();
814
+ switch (key) {
815
+ case 'w':
816
+ gameState.keys.w = true;
817
+ break;
818
+ case 'a':
819
+ gameState.keys.a = true;
820
+ break;
821
+ case 's':
822
+ gameState.keys.s = true;
823
+ break;
824
+ case 'd':
825
+ gameState.keys.d = true;
826
+ break;
827
+ case 'shift':
828
+ gameState.keys.shift = true;
829
+ break;
830
  case ' ':
831
  gameState.keys.space = true;
832
+ // Check if we're near an NPC and dialog isn't already open
833
+ const isDialogOpen = !document.getElementById('dialog-box').classList.contains('translate-y-full');
834
+ if (gameState.nearbyNpc && !gameState.isJumping && !isDialogOpen) {
835
  showDialog(gameState.nearbyNpc);
 
836
  }
837
  break;
838
  }
839
  }
840
+ function handleKeyUp(event) {
841
+ // Ignore key repeats
842
+ if (event.repeat) return;
843
+
844
+ const key = event.key.toLowerCase();
845
+ switch (key) {
846
+ case 'w':
847
+ gameState.keys.w = false;
848
+ break;
849
+ case 'a':
850
+ gameState.keys.a = false;
851
+ break;
852
+ case 's':
853
+ gameState.keys.s = false;
854
+ break;
855
+ case 'd':
856
+ gameState.keys.d = false;
857
+ break;
858
+ case 'shift':
859
+ gameState.keys.shift = false;
860
+ break;
861
+ case ' ':
862
+ gameState.keys.space = false;
863
+ break;
864
+ }
865
+
866
+ // Update animation when keys are released
867
+ if (gameState.player) {
868
+ updatePlayerAnimation();
869
  }
870
  }
871
+ </script>
872
  <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=KBLLR/character-selector" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
873
  </html>