KBLLR commited on
Commit
ee6e524
·
verified ·
1 Parent(s): e676143

(index):64 cdn.tailwindcss.com should not be used in production. To use Tailwind CSS in production, install it as a PostCSS plugin or use the Tailwind CLI: https://tailwindcss.com/docs/installation

Browse files

(anonymous) @ (index):64
(anonymous) @ (index):64Understand this warning
OrbitControls.js:1 Uncaught SyntaxError: Cannot use import statement outside a moduleUnderstand this error
GLTFLoader.js:1 Uncaught SyntaxError: Cannot use import statement outside a moduleUnderstand this error
VM448 about:srcdoc:124 Three.js not loaded
(anonymous) @ VM448 about:srcdoc:124Understand this error
VM448 about:srcdoc:133 Uncaught (in promise) ReferenceError: THREE is not defined
at loadThreeJSModules (VM448 about:srcdoc:133:13)
at HTMLDocument.<anonymous> (VM448 about:srcdoc:126:17)
loadThreeJSModules @ VM448 about:srcdoc:133
(anonymous) @ VM448 about:srcdoc:126Understand this error
VM448 about:srcdoc:333 Three.js is not loaded properly
initThreeJS @ VM448 about:srcdoc:333
startGame @ VM448 about:srcdoc:245Understand this error
VM448 about:srcdoc:337 Ignored call to 'alert()'. The document is sandboxed, and the 'allow-modals' keyword is not set.

Files changed (1) hide show
  1. index.html +77 -39
index.html CHANGED
@@ -4,10 +4,9 @@
4
  <meta charset="UTF-8">
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
  <title>3D Character World</title>
7
- <script src="https://cdn.tailwindcss.com"></script>
8
  <script src="https://cdn.jsdelivr.net/npm/three@0.167.0/build/three.min.js"></script>
9
- <script src="https://cdn.jsdelivr.net/npm/three@0.167.0/examples/jsm/controls/OrbitControls.js"></script>
10
- <script src="https://cdn.jsdelivr.net/npm/three@0.167.0/examples/jsm/loaders/GLTFLoader.js"></script>
11
  <style>
12
  body {
13
  margin: 0;
@@ -188,9 +187,20 @@
188
  </div>
189
  </div>
190
  </div>
 
 
 
 
 
 
 
 
 
 
 
191
  <!-- Game UI -->
192
  <div id="game-ui" class="fixed inset-0 pointer-events-none z-20 opacity-0 transition-all">
193
- <div class="absolute bottom-4 left-4 bg-gray-800 bg-opacity-70 p-4 rounded-lg">
194
  <div class="flex items-center space-x-2">
195
  <div class="w-3 h-3 rounded-full bg-green-500"></div>
196
  <span>WASD: Move</span>
@@ -369,25 +379,45 @@
369
 
370
  // Initialize audio context on user interaction
371
  document.addEventListener('click', initializeAudio, { once: true });
372
-
373
- // Check if Three.js modules are available
374
- if (typeof THREE === 'undefined') {
375
- console.error('Three.js not loaded');
376
- // Try to load modules dynamically if needed
 
 
 
 
377
  loadThreeJSModules();
378
- }
379
- });
380
-
 
 
 
 
381
  // Function to dynamically load Three.js modules if needed
382
  function loadThreeJSModules() {
383
  // Check if OrbitControls is available
384
  if (typeof THREE.OrbitControls === 'undefined') {
385
- console.warn('OrbitControls not available, using fallback controls');
 
 
 
 
 
 
386
  }
387
 
388
  // Check if GLTFLoader is available
389
  if (typeof THREE.GLTFLoader === 'undefined') {
390
- console.warn('GLTFLoader not available, using fallback geometry');
 
 
 
 
 
 
391
  }
392
  }
393
  function initializeAudio() {
@@ -481,11 +511,11 @@ function showCharacterSelection() {
481
  }
482
  function startGame() {
483
  if (gameState.selectedWorldCharacters.length < 2) {
484
- alert('Please select 2 characters for your world!');
 
485
  return;
486
  }
487
-
488
- // Ensure audio is initialized when game starts
489
  if (!audioContext) {
490
  initializeAudio();
491
  }
@@ -582,18 +612,26 @@ card.addEventListener('click', () => {
582
  function initThreeJS() {
583
  if (typeof THREE === 'undefined') {
584
  console.error('Three.js is not loaded properly');
585
- // Try to reload or show error
586
- setTimeout(() => {
587
- if (typeof THREE === 'undefined') {
588
- alert('Three.js failed to load. Please refresh the page.');
589
- } else {
590
- initThreeJS(); // Retry initialization
591
- }
592
- }, 100);
593
  return;
594
  }
595
 
596
- try {
 
 
 
 
 
 
 
 
597
  // Set up Three.js scene
598
  scene = new THREE.Scene();
599
  scene.background = new THREE.Color(0x87CEEB); // Sky blue
@@ -676,23 +714,23 @@ card.addEventListener('click', () => {
676
 
677
  // Add some environment objects
678
  addEnvironmentObjects();
679
-
680
  // Initialize OrbitControls with fallback
 
681
  if (typeof THREE.OrbitControls !== 'undefined') {
682
  controls = new THREE.OrbitControls(camera, renderer.domElement);
683
  controls.enableDamping = true;
684
  controls.dampingFactor = 0.05;
685
  controls.enabled = false; // Start with controls disabled for follow camera
686
  } else {
687
- console.warn('OrbitControls not available, using fallback');
688
  controls = {
689
  enabled: false,
690
  update: () => {},
691
  target: new THREE.Vector3()
692
  };
693
  }
694
-
695
- // Load player character
696
  loadPlayerCharacter();
697
 
698
  // Load NPC characters
@@ -710,8 +748,8 @@ card.addEventListener('click', () => {
710
  } catch (error) {
711
  console.error('Error initializing Three.js:', error);
712
  // Show user-friendly error message
713
- alert('Error initializing 3D graphics. Please check your browser supports WebGL.');
714
- }
715
  }
716
  function addEnvironmentObjects() {
717
  // Add some trees
@@ -748,8 +786,9 @@ function addEnvironmentObjects() {
748
  }
749
  }
750
  function loadPlayerCharacter() {
751
- if (loader && typeof THREE.GLTFLoader !== 'undefined') {
752
- loader.load(gameState.selectedCharacter.modelUrl, (gltf) => {
 
753
  const model = gltf.scene;
754
  // Scale and position the RPM avatar model - adjusted for human proportions
755
  model.scale.set(0.8, 0.8, 0.8);
@@ -803,9 +842,10 @@ function addEnvironmentObjects() {
803
  });
804
  } else {
805
  // GLTFLoader not available, use fallback
 
806
  loadPlayerCharacterFallback();
807
  }
808
- }
809
  function loadPlayerCharacterFallback() {
810
  const group = new THREE.Group();
811
 
@@ -1014,7 +1054,7 @@ scene.add(group);
1014
  // Update camera based on mode
1015
  updateCamera(delta);
1016
  // Update OrbitControls if enabled
1017
- if (controls && controls.enabled) {
1018
  controls.update();
1019
  }
1020
  renderer.render(scene, camera);
@@ -1167,13 +1207,11 @@ function handlePlayerMovement(delta) {
1167
  // Update UI display
1168
  document.getElementById('camera-mode-display').textContent =
1169
  gameState.cameraMode.charAt(0).toUpperCase() + gameState.cameraMode.slice(1);
1170
-
1171
  // Enable/disable OrbitControls based on mode
1172
  if (controls && typeof controls.enabled !== 'undefined') {
1173
  controls.enabled = (gameState.cameraMode === 'orbit');
1174
  }
1175
-
1176
- // Reset camera position for first-person mode
1177
  if (gameState.cameraMode === 'first-person') {
1178
  camera.rotation.set(0, 0, 0);
1179
  }
 
4
  <meta charset="UTF-8">
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
  <title>3D Character World</title>
 
7
  <script src="https://cdn.jsdelivr.net/npm/three@0.167.0/build/three.min.js"></script>
8
+ <script src="https://cdn.jsdelivr.net/npm/three@0.167.0/examples/jsm/controls/OrbitControls.min.js"></script>
9
+ <script src="https://cdn.jsdelivr.net/npm/three@0.167.0/examples/jsm/loaders/GLTFLoader.min.js"></script>
10
  <style>
11
  body {
12
  margin: 0;
 
187
  </div>
188
  </div>
189
  </div>
190
+ <!-- Modal for alerts -->
191
+ <div id="modal-overlay" class="fixed inset-0 bg-black/80 backdrop-blur-sm flex items-center justify-center z-50 opacity-0 pointer-events-none transition-all">
192
+ <div class="bg-gray-900/90 border border-white/10 rounded-xl p-6 max-w-md mx-4 shadow-2xl">
193
+ <h3 id="modal-title" class="text-xl font-bold text-white mb-2"></h3>
194
+ <p id="modal-message" class="text-gray-300 mb-4"></p>
195
+ <button id="modal-close" class="w-full bg-gradient-to-r from-purple-600 to-blue-600 text-white py-2 rounded-lg font-semibold hover:from-purple-700 hover:to-blue-700 transition-all">
196
+ OK
197
+ </button>
198
+ </div>
199
+ </div>
200
+
201
  <!-- Game UI -->
202
  <div id="game-ui" class="fixed inset-0 pointer-events-none z-20 opacity-0 transition-all">
203
+ <div class="absolute bottom-4 left-4 bg-gray-800 bg-opacity-70 p-4 rounded-lg">
204
  <div class="flex items-center space-x-2">
205
  <div class="w-3 h-3 rounded-full bg-green-500"></div>
206
  <span>WASD: Move</span>
 
379
 
380
  // Initialize audio context on user interaction
381
  document.addEventListener('click', initializeAudio, { once: true });
382
+ // Check if Three.js is loaded
383
+ if (typeof THREE === 'undefined') {
384
+ console.error('Three.js not loaded');
385
+ // Fallback to loading from CDN
386
+ const script = document.createElement('script');
387
+ script.src = 'https://cdn.jsdelivr.net/npm/three@0.167.0/build/three.min.js';
388
+ script.onload = () => {
389
+ console.log('Three.js loaded via fallback');
390
+ // Now load the modules
391
  loadThreeJSModules();
392
+ };
393
+ document.head.appendChild(script);
394
+ } else {
395
+ // Three.js is loaded, check if modules are available
396
+ loadThreeJSModules();
397
+ }
398
+ });
399
  // Function to dynamically load Three.js modules if needed
400
  function loadThreeJSModules() {
401
  // Check if OrbitControls is available
402
  if (typeof THREE.OrbitControls === 'undefined') {
403
+ console.log('Loading OrbitControls...');
404
+ const orbitScript = document.createElement('script');
405
+ orbitScript.src = 'https://cdn.jsdelivr.net/npm/three@0.167.0/examples/jsm/controls/OrbitControls.min.js';
406
+ orbitScript.onload = () => {
407
+ console.log('OrbitControls loaded');
408
+ };
409
+ document.head.appendChild(orbitScript);
410
  }
411
 
412
  // Check if GLTFLoader is available
413
  if (typeof THREE.GLTFLoader === 'undefined') {
414
+ console.log('Loading GLTFLoader...');
415
+ const gltfScript = document.createElement('script');
416
+ gltfScript.src = 'https://cdn.jsdelivr.net/npm/three@0.167.0/examples/jsm/loaders/GLTFLoader.min.js';
417
+ gltfScript.onload = () => {
418
+ console.log('GLTFLoader loaded');
419
+ };
420
+ document.head.appendChild(gltfScript);
421
  }
422
  }
423
  function initializeAudio() {
 
511
  }
512
  function startGame() {
513
  if (gameState.selectedWorldCharacters.length < 2) {
514
+ // Use a custom modal instead of alert for better UX
515
+ showModal('Selection Required', 'Please select 2 characters for your world!');
516
  return;
517
  }
518
+ // Ensure audio is initialized when game starts
 
519
  if (!audioContext) {
520
  initializeAudio();
521
  }
 
612
  function initThreeJS() {
613
  if (typeof THREE === 'undefined') {
614
  console.error('Three.js is not loaded properly');
615
+ // Try to load Three.js dynamically
616
+ const script = document.createElement('script');
617
+ script.src = 'https://cdn.jsdelivr.net/npm/three@0.167.0/build/three.min.js';
618
+ script.onload = () => {
619
+ console.log('Three.js loaded, retrying initialization...');
620
+ initThreeJS(); // Retry initialization
621
+ };
622
+ document.head.appendChild(script);
623
  return;
624
  }
625
 
626
+ // Check if required modules are available
627
+ if (typeof THREE.OrbitControls === 'undefined') {
628
+ console.warn('OrbitControls not available, using fallback camera controls');
629
+ }
630
+
631
+ if (typeof THREE.GLTFLoader === 'undefined') {
632
+ console.warn('GLTFLoader not available, using fallback geometry');
633
+ }
634
+ try {
635
  // Set up Three.js scene
636
  scene = new THREE.Scene();
637
  scene.background = new THREE.Color(0x87CEEB); // Sky blue
 
714
 
715
  // Add some environment objects
716
  addEnvironmentObjects();
 
717
  // Initialize OrbitControls with fallback
718
+ let controls;
719
  if (typeof THREE.OrbitControls !== 'undefined') {
720
  controls = new THREE.OrbitControls(camera, renderer.domElement);
721
  controls.enableDamping = true;
722
  controls.dampingFactor = 0.05;
723
  controls.enabled = false; // Start with controls disabled for follow camera
724
  } else {
725
+ console.warn('OrbitControls not available, using fallback camera controls');
726
  controls = {
727
  enabled: false,
728
  update: () => {},
729
  target: new THREE.Vector3()
730
  };
731
  }
732
+ window.controls = controls; // Make globally available
733
+ // Load player character
734
  loadPlayerCharacter();
735
 
736
  // Load NPC characters
 
748
  } catch (error) {
749
  console.error('Error initializing Three.js:', error);
750
  // Show user-friendly error message
751
+ showModal('3D Graphics Error', 'Error initializing 3D graphics. Please check your browser supports WebGL and try refreshing the page.');
752
+ }
753
  }
754
  function addEnvironmentObjects() {
755
  // Add some trees
 
786
  }
787
  }
788
  function loadPlayerCharacter() {
789
+ if (typeof THREE.GLTFLoader !== 'undefined') {
790
+ const loader = new THREE.GLTFLoader();
791
+ loader.load(gameState.selectedCharacter.modelUrl, (gltf) => {
792
  const model = gltf.scene;
793
  // Scale and position the RPM avatar model - adjusted for human proportions
794
  model.scale.set(0.8, 0.8, 0.8);
 
842
  });
843
  } else {
844
  // GLTFLoader not available, use fallback
845
+ console.warn('GLTFLoader not available, using fallback character');
846
  loadPlayerCharacterFallback();
847
  }
848
+ }
849
  function loadPlayerCharacterFallback() {
850
  const group = new THREE.Group();
851
 
 
1054
  // Update camera based on mode
1055
  updateCamera(delta);
1056
  // Update OrbitControls if enabled
1057
+ if (controls && controls.enabled && typeof controls.update === 'function') {
1058
  controls.update();
1059
  }
1060
  renderer.render(scene, camera);
 
1207
  // Update UI display
1208
  document.getElementById('camera-mode-display').textContent =
1209
  gameState.cameraMode.charAt(0).toUpperCase() + gameState.cameraMode.slice(1);
 
1210
  // Enable/disable OrbitControls based on mode
1211
  if (controls && typeof controls.enabled !== 'undefined') {
1212
  controls.enabled = (gameState.cameraMode === 'orbit');
1213
  }
1214
+ // Reset camera position for first-person mode
 
1215
  if (gameState.cameraMode === 'first-person') {
1216
  camera.rotation.set(0, 0, 0);
1217
  }