Spaces:
Running
Running
(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
VM250 about:srcdoc:124 Three.js not loaded
(anonymous) @ VM250 about:srcdoc:124Understand this error
VM250 about:srcdoc:319 Three.js is not loaded properly
initThreeJS @ VM250 about:srcdoc:319
startGame @ VM250 about:srcdoc:231Understand this error
- index.html +96 -57
index.html
CHANGED
|
@@ -370,12 +370,26 @@
|
|
| 370 |
// Initialize audio context on user interaction
|
| 371 |
document.addEventListener('click', initializeAudio, { once: true });
|
| 372 |
|
| 373 |
-
//
|
| 374 |
if (typeof THREE === 'undefined') {
|
| 375 |
console.error('Three.js not loaded');
|
| 376 |
-
|
|
|
|
| 377 |
}
|
| 378 |
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 379 |
function initializeAudio() {
|
| 380 |
if (audioContext) return;
|
| 381 |
|
|
@@ -568,6 +582,14 @@ card.addEventListener('click', () => {
|
|
| 568 |
function initThreeJS() {
|
| 569 |
if (typeof THREE === 'undefined') {
|
| 570 |
console.error('Three.js is not loaded properly');
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 571 |
return;
|
| 572 |
}
|
| 573 |
|
|
@@ -594,8 +616,14 @@ card.addEventListener('click', () => {
|
|
| 594 |
// Clock for animations
|
| 595 |
clock = new THREE.Clock();
|
| 596 |
|
| 597 |
-
// Loader
|
| 598 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 599 |
// Add environment map with error handling
|
| 600 |
const envMapLoader = new THREE.CubeTextureLoader();
|
| 601 |
envMapLoader.load([
|
|
@@ -633,6 +661,7 @@ card.addEventListener('click', () => {
|
|
| 633 |
mainLight.shadow.camera.top = 20;
|
| 634 |
mainLight.shadow.camera.bottom = -20;
|
| 635 |
scene.add(mainLight);
|
|
|
|
| 636 |
// Create ground
|
| 637 |
const groundGeometry = new THREE.PlaneGeometry(100, 100);
|
| 638 |
const groundMaterial = new THREE.MeshStandardMaterial({
|
|
@@ -648,15 +677,19 @@ card.addEventListener('click', () => {
|
|
| 648 |
// Add some environment objects
|
| 649 |
addEnvironmentObjects();
|
| 650 |
|
| 651 |
-
// Initialize OrbitControls
|
| 652 |
if (typeof THREE.OrbitControls !== 'undefined') {
|
| 653 |
controls = new THREE.OrbitControls(camera, renderer.domElement);
|
| 654 |
controls.enableDamping = true;
|
| 655 |
controls.dampingFactor = 0.05;
|
| 656 |
controls.enabled = false; // Start with controls disabled for follow camera
|
| 657 |
} else {
|
| 658 |
-
console.warn('OrbitControls not available');
|
| 659 |
-
controls = {
|
|
|
|
|
|
|
|
|
|
|
|
|
| 660 |
}
|
| 661 |
|
| 662 |
// Load player character
|
|
@@ -676,6 +709,8 @@ card.addEventListener('click', () => {
|
|
| 676 |
});
|
| 677 |
} catch (error) {
|
| 678 |
console.error('Error initializing Three.js:', error);
|
|
|
|
|
|
|
| 679 |
}
|
| 680 |
}
|
| 681 |
function addEnvironmentObjects() {
|
|
@@ -713,61 +748,65 @@ function addEnvironmentObjects() {
|
|
| 713 |
}
|
| 714 |
}
|
| 715 |
function loadPlayerCharacter() {
|
| 716 |
-
loader.
|
| 717 |
-
|
| 718 |
-
|
| 719 |
-
|
| 720 |
-
model.
|
| 721 |
-
|
| 722 |
-
|
| 723 |
-
|
| 724 |
-
child.
|
| 725 |
-
|
| 726 |
-
|
| 727 |
-
|
| 728 |
-
|
| 729 |
-
scene.add(model);
|
| 730 |
-
|
| 731 |
-
// Set up animations if available
|
| 732 |
-
const mixer = new THREE.AnimationMixer(model);
|
| 733 |
-
const animations = gltf.animations;
|
| 734 |
-
|
| 735 |
-
gameState.player = {
|
| 736 |
-
model: model,
|
| 737 |
-
speed: 0.08,
|
| 738 |
-
runSpeed: 0.15,
|
| 739 |
-
rotationSpeed: 0.08,
|
| 740 |
-
isMoving: false,
|
| 741 |
-
mixer: mixer,
|
| 742 |
-
animations: animations,
|
| 743 |
-
currentAnimation: null,
|
| 744 |
-
animationActions: {}
|
| 745 |
-
};
|
| 746 |
-
|
| 747 |
-
// Set up animation actions
|
| 748 |
-
if (animations && animations.length > 0) {
|
| 749 |
-
animations.forEach((clip) => {
|
| 750 |
-
gameState.player.animationActions[clip.name] = mixer.clipAction(clip);
|
| 751 |
});
|
| 752 |
|
| 753 |
-
|
| 754 |
-
|
| 755 |
-
|
| 756 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 757 |
}
|
| 758 |
-
|
| 759 |
-
|
| 760 |
-
|
| 761 |
-
|
| 762 |
-
|
| 763 |
-
|
| 764 |
-
|
| 765 |
-
//
|
| 766 |
loadPlayerCharacterFallback();
|
| 767 |
-
}
|
| 768 |
}
|
| 769 |
-
|
| 770 |
-
function loadPlayerCharacterFallback() {
|
| 771 |
const group = new THREE.Group();
|
| 772 |
|
| 773 |
// Body
|
|
|
|
| 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() {
|
| 394 |
if (audioContext) return;
|
| 395 |
|
|
|
|
| 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 |
|
|
|
|
| 616 |
// Clock for animations
|
| 617 |
clock = new THREE.Clock();
|
| 618 |
|
| 619 |
+
// Loader - check if GLTFLoader is available
|
| 620 |
+
if (typeof THREE.GLTFLoader !== 'undefined') {
|
| 621 |
+
loader = new THREE.GLTFLoader();
|
| 622 |
+
} else {
|
| 623 |
+
console.warn('GLTFLoader not available, using fallback geometry');
|
| 624 |
+
loader = null;
|
| 625 |
+
}
|
| 626 |
+
|
| 627 |
// Add environment map with error handling
|
| 628 |
const envMapLoader = new THREE.CubeTextureLoader();
|
| 629 |
envMapLoader.load([
|
|
|
|
| 661 |
mainLight.shadow.camera.top = 20;
|
| 662 |
mainLight.shadow.camera.bottom = -20;
|
| 663 |
scene.add(mainLight);
|
| 664 |
+
|
| 665 |
// Create ground
|
| 666 |
const groundGeometry = new THREE.PlaneGeometry(100, 100);
|
| 667 |
const groundMaterial = new THREE.MeshStandardMaterial({
|
|
|
|
| 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
|
|
|
|
| 709 |
});
|
| 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() {
|
|
|
|
| 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);
|
| 756 |
+
model.position.set(0, 0, 0);
|
| 757 |
+
// Enable shadows for all children
|
| 758 |
+
model.traverse((child) => {
|
| 759 |
+
if (child.isMesh) {
|
| 760 |
+
child.castShadow = true;
|
| 761 |
+
child.receiveShadow = true;
|
| 762 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 763 |
});
|
| 764 |
|
| 765 |
+
scene.add(model);
|
| 766 |
+
|
| 767 |
+
// Set up animations if available
|
| 768 |
+
const mixer = new THREE.AnimationMixer(model);
|
| 769 |
+
const animations = gltf.animations;
|
| 770 |
+
|
| 771 |
+
gameState.player = {
|
| 772 |
+
model: model,
|
| 773 |
+
speed: 0.08,
|
| 774 |
+
runSpeed: 0.15,
|
| 775 |
+
rotationSpeed: 0.08,
|
| 776 |
+
isMoving: false,
|
| 777 |
+
mixer: mixer,
|
| 778 |
+
animations: animations,
|
| 779 |
+
currentAnimation: null,
|
| 780 |
+
animationActions: {}
|
| 781 |
+
};
|
| 782 |
+
|
| 783 |
+
// Set up animation actions
|
| 784 |
+
if (animations && animations.length > 0) {
|
| 785 |
+
animations.forEach((clip) => {
|
| 786 |
+
gameState.player.animationActions[clip.name] = mixer.clipAction(clip);
|
| 787 |
+
});
|
| 788 |
+
|
| 789 |
+
// Play the first animation by default
|
| 790 |
+
if (animations[0]) {
|
| 791 |
+
gameState.player.animationActions[animations[0].name].play();
|
| 792 |
+
gameState.player.currentAnimation = animations[0].name;
|
| 793 |
+
}
|
| 794 |
+
} else {
|
| 795 |
+
// If no animations, create simple placeholder animations
|
| 796 |
+
createPlayerAnimations();
|
| 797 |
}
|
| 798 |
+
|
| 799 |
+
}, undefined, (error) => {
|
| 800 |
+
console.error('Error loading player model:', error);
|
| 801 |
+
// Fallback to placeholder
|
| 802 |
+
loadPlayerCharacterFallback();
|
| 803 |
+
});
|
| 804 |
+
} else {
|
| 805 |
+
// GLTFLoader not available, use fallback
|
| 806 |
loadPlayerCharacterFallback();
|
| 807 |
+
}
|
| 808 |
}
|
| 809 |
+
function loadPlayerCharacterFallback() {
|
|
|
|
| 810 |
const group = new THREE.Group();
|
| 811 |
|
| 812 |
// Body
|