// Create a scene
const scene = new THREE.Scene();
// Set up a camera
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
// Create a renderer and attach it to the DOM
const renderer = new THREE.WebGLRenderer({ canvas: document.querySelector('#gameCanvas') });
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
const rgbeLoader = new THREE.RGBELoader();
rgbeLoader.load('sky_panorama.hdr', function (texture) {
texture.mapping = THREE.EquirectangularReflectionMapping;
// Apply HDR texture
scene.background = texture;
scene.environment = texture;
});
// Load textures
const textureLoader = new THREE.TextureLoader();
const groundTexture = textureLoader.load('grass.jpg');
const bumpTexture = textureLoader.load('bump.jpg');
// Repeat and Wrapping
groundTexture.wrapS = THREE.RepeatWrapping;
groundTexture.wrapT = THREE.RepeatWrapping;
groundTexture.repeat.set(10, 10);
bumpTexture.wrapS = THREE.RepeatWrapping;
bumpTexture.wrapT = THREE.RepeatWrapping;
bumpTexture.repeat.set(10, 10);
// Function to create ground segment
function createGroundSegment() {
const groundGeometry = new THREE.PlaneGeometry(100, 100, 32, 32);
// Modify UV mapping to repeat the texture manually
const uvAttribute = groundGeometry.attributes.uv;
for (let i = 0; i < uvAttribute.count; i++) {
const u = uvAttribute.getX(i) * 10; // Scale U coordinate
const v = uvAttribute.getY(i) * 10; // Scale V coordinate
uvAttribute.setXY(i, u, v); // Update UVs
}
// Create ground material and mesh
const groundMaterial = new THREE.MeshStandardMaterial({
map: groundTexture,
bumpMap: bumpTexture,
bumpScale: 0.1
});
const ground = new THREE.Mesh(groundGeometry, groundMaterial);
ground.rotation.x = -Math.PI / 2; // Rotate so it's horizontal
return ground;
}
// Create multiple ground segments to simulate an endless floor
const groundSegments = [];
const numberOfSegments = 3; // Number of segments to simulate endless ground
const segmentLength = 100;
for (let i = 0; i < numberOfSegments; i++) {
const ground = createGroundSegment();
ground.position.set(0, 0, -i * segmentLength);
scene.add(ground);
groundSegments.push(ground);
}
// Update ground segments in the game loop
function updateGround() {
groundSegments.forEach((ground) => {
// Move ground backwards to simulate player moving forward
ground.position.z += forwardSpeed;
// Check if the ground is behind the player, and reposition it in front
if (ground.position.z > player.position.z + segmentLength) {
ground.position.z -= segmentLength * numberOfSegments;
}
});
}
// Lighting setup
const light = new THREE.PointLight(0xffffff, 1, 100);
light.position.set(10, 10, 10);
scene.add(light);
const ambientLight = new THREE.AmbientLight(0x404040);
scene.add(ambientLight);
// Create the player (a sphere)
const playerGeometry = new THREE.SphereGeometry(0.5, 32, 32);
const playerMaterial = new THREE.MeshStandardMaterial({ color: 0xff0000 });
const player = new THREE.Mesh(playerGeometry, playerMaterial);
player.position.y = 0.5;
scene.add(player);
// Camera initial position and follow distance
const cameraOffset = new THREE.Vector3(0, 2, 5); // Behind and above the player
// Movement and jumping
let forwardSpeed = 0.05; // Forward speed
const moveSpeed = 0.1; // Lateral movement speed
const jumpHeight = 1;
let isJumping = false;
let jumpStartY = 0;
// Bounce-back control
let bounceBack = false;
let bounceBackTimer = 0;
const bounceBackDuration = 30; // Duration of the bounce back effect
// Create a bounding box for the player
let playerBoundingBox = new THREE.Box3().setFromObject(player);
const keys = {};
window.addEventListener('keydown', (event) => { keys[event.key] = true; });
window.addEventListener('keyup', (event) => { keys[event.key] = false; });
// Elevated platforms
const platforms = [];
function createPlatform(height, width, zPosition) {
const platformGeometry = new THREE.BoxGeometry(width, height, 10);
const platformMaterial = new THREE.MeshStandardMaterial({ color: 0x808080 });
const platform = new THREE.Mesh(platformGeometry, platformMaterial);
platform.position.set(0, height / 2, zPosition);
scene.add(platform);
platforms.push(platform);
}
// Move the player and handle collisions
function handlePlayerMovement() {
if (!bounceBack) {
// Move player forward continuously
player.position.z -= forwardSpeed;
// Update player bounding box
playerBoundingBox.setFromObject(player);
// Left and right movement
if (keys['ArrowLeft']) {
player.position.x -= moveSpeed;
}
if (keys['ArrowRight']) {
player.position.x += moveSpeed;
}
// Jumping
if (keys[' '] && !isJumping) {
isJumping = true;
jumpStartY = player.position.y;
}
if (isJumping) {
// Jump logic
if (player.position.y < jumpStartY + jumpHeight) {
player.position.y += moveSpeed;
} else {
isJumping = false; // Start falling after reaching the jump height
}
} else if (player.position.y > 0.5) {
// Falling logic
player.position.y -= moveSpeed;
if (player.position.y < 0.5) {
player.position.y = 0.5; // Keep player above ground
}
}
// Check for collisions with platforms
platforms.forEach((platform) => {
const platformBoundingBox = new THREE.Box3().setFromObject(platform);
if (playerBoundingBox.intersectsBox(platformBoundingBox)) {
// If the player is falling and collides with the top of the platform
if (player.position.y < platform.position.y + (platform.geometry.parameters.height / 2) &&
player.position.y > platform.position.y - (platform.geometry.parameters.height / 2)) {
player.position.y = platform.position.y + (platform.geometry.parameters.height / 2) + 0.5; // Set player on top of the platform
isJumping = false; // Reset jumping
}
}
});
} else {
// Bounce back the player
player.position.z += forwardSpeed * 2; // Reverse at double speed
// Countdown the bounce back timer
bounceBackTimer--;
if (bounceBackTimer <= 0) {
bounceBack = false; // Stop bouncing back after the timer
}
}
}
function updateCameraPosition() {
// Position the camera behind and above the player
const desiredPosition = player.position.clone().add(cameraOffset);
camera.position.lerp(desiredPosition, 0.1); // Smooth camera movement
// Make the camera look at the player
camera.lookAt(player.position);
}
// Obstacles
const obstacles = [];
const obstacleSpeed = forwardSpeed; // Obstacles move at the same speed as the player
function createObstacle() {
const obstacleGeometry = new THREE.BoxGeometry(1, 1, 1);
const obstacleMaterial = new THREE.MeshStandardMaterial({ color: 0x00ff00 });
const obstacle = new THREE.Mesh(obstacleGeometry, obstacleMaterial);
// Position obstacle randomly on the player's path
obstacle.position.x = (Math.random() - 0.5) * 10; // Random x position
obstacle.position.z = player.position.z - 50; // Place obstacle in front of the player
obstacle.position.y = 0.5; // Same height as player
// Create bounding box for obstacle
obstacle.userData.boundingBox = new THREE.Box3().setFromObject(obstacle);
scene.add(obstacle);
obstacles.push(obstacle);
}
// Function to handle obstacle movements and collisions
function updateObstacles() {
obstacles.forEach((obstacle) => {
obstacle.position.z += obstacleSpeed; // Move obstacle forward
// Check for collisions with the player
if (playerBoundingBox.intersectsBox(obstacle.userData.boundingBox)) {
bounceBack = true; // Trigger bounce back
bounceBackTimer = bounceBackDuration; // Reset bounce back timer
}
// Remove obstacles that go out of view
if (obstacle.position.z > player.position.z + 50) {
scene.remove(obstacle);
obstacles.splice(obstacles.indexOf(obstacle), 1);
}
});
}
// Main game loop
function animate() {
requestAnimationFrame(animate);
handlePlayerMovement();
updateGround();
updateCameraPosition();
updateObstacles();
// Render the scene
renderer.render(scene, camera);
}
// Spawn obstacles at intervals
setInterval(createObstacle, 2000); // Create a new obstacle every 2 seconds
// Start the animation loop
animate();
Uncaught TypeError: THREE.RGBELoader is not a constructor
at main.js:12:20
I can’t seem to get rid of this error even after moving my import statements to my html files , I have tried multiple things to no avail