Daveroby13's picture
Can you finish the project to make the whole thing give me a let me be able to walk around and feel what it's like
80c0783 verified
```javascript
// SquirrelVision 3D Playground - Main Game Script
class SquirrelVisionPlayground {
constructor() {
this.scene = null;
this.camera = null;
this.renderer = null;
this.controls = null;
this.objects = [];
this.isPlaying = false;
this.moveForward = false;
this.moveBackward = false;
this.moveLeft = false;
this.moveRight = false;
this.canJump = false;
this.prevTime = performance.now();
this.velocity = new THREE.Vector3();
this.direction = new THREE.Vector3();
this.interactiveObjects = [];
this.init();
}
async init() {
// Update loading progress
this.updateLoadingProgress(10, 'Creating 3D scene...');
// Create scene
this.scene = new THREE.Scene();
this.scene.background = new THREE.Color(0x87CEEB); // Sky blue
// Create camera
this.camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
this.camera.position.set(0, 1.6, 0);
// Create renderer
this.renderer = new THREE.WebGLRenderer({ antialias: true });
this.renderer.setSize(window.innerWidth, window.innerHeight);
this.renderer.shadowMap.enabled = true;
this.renderer.shadowMap.type = THREE.PCFSoftShadowMap;
// Add renderer to DOM
document.getElementById('gameContainer').appendChild(this.renderer.domElement);
this.updateLoadingProgress(30, 'Setting up lighting...');
await this.setupLighting();
this.updateLoadingProgress(50, 'Creating world geometry...');
await this.createWorld();
this.updateLoadingProgress(70, 'Adding interactive objects...');
await this.addInteractiveObjects();
this.updateLoadingProgress(90, 'Setting up controls...');
this.setupControls();
this.updateLoadingProgress(100, 'Ready!');
// Show start screen after a brief delay
setTimeout(() => {
document.getElementById('loadingScreen').style.display = 'none';
document.getElementById('startScreen').style.display = 'flex';
}, 500);
// Start animation loop
this.animate();
// Handle window resize
window.addEventListener('resize', () => this.onWindowResize());
}
updateLoadingProgress(percent, text) {
document.getElementById('progressBar').style.width = percent + '%';
document.getElementById('loadingText').textContent = text;
}
async setupLighting() {
// Ambient light
const ambientLight = new THREE.AmbientLight(0x404040, 0.6);
this.scene.add(ambientLight);
// Directional light (sun)
const directionalLight = new THREE.DirectionalLight(0xffffff, 1);
directionalLight.position.set(50, 50, 50);
directionalLight.castShadow = true;
directionalLight.shadow.mapSize.width = 2048;
directionalLight.shadow.mapSize.height = 2048;
directionalLight.shadow.camera.near = 0.5;
directionalLight.shadow.camera.far = 500;
directionalLight.shadow.camera.left = -100;
directionalLight.shadow.camera.right = 100;
directionalLight.shadow.camera.top = 100;
directionalLight.shadow.camera.bottom = -100;
this.scene.add(directionalLight);
// Hemisphere light for more natural outdoor lighting
const hemisphereLight = new THREE.HemisphereLight(0x87CEEB, 0x8B4513, 0.4);
this.scene.add(hemisphereLight);
}
async createWorld() {
// Create ground
const groundGeometry = new THREE.PlaneGeometry(100, 100);
const groundMaterial = new THREE.MeshLambertMaterial({
color: 0x7CFC00, // Lawn green
side: THREE.DoubleSide
});
const ground = new THREE.Mesh(groundGeometry, groundMaterial);
ground.rotation.x = -Math.PI / 2;
ground.receiveShadow = true;
this.scene.add(ground);
// Add some grass texture variation
const grassTexture = new THREE.MeshLambertMaterial({
color: 0x32CD32, // Lime green
side: THREE.DoubleSide
});
for (let i = 0; i < 200; i++) {
const grassBlade = new THREE.Mesh(
new THREE.PlaneGeometry(0.1, 0.5),
grassTexture
);
grassBlade.position.set(
Math.random() * 80 - 40,
0.25,
Math.random() * 80 - 40
);
grassBlade.rotation.x = -Math.PI / 2;
grassBlade.rotation.z = Math.random() * Math.PI;
this.scene.add(grassBlade);
}
// Create trees
for (let i = 0; i < 15; i++) {
this.createTree(
Math.random() * 70 - 35,
Math.random() * 70 - 35
);
}
// Create buildings
this.createBuilding(-15, 0, -15, 8, 12, 8, 0x888888);
this.createBuilding(15, 0, 15, 6, 8, 6, 0x666666);
this.createBuilding(-15, 0, 15, 5, 6, 5, 0x777777);
// Create a central fountain
this.createFountain(0, 0, 0);
// Create some rocks
for (let i = 0; i < 10; i++) {
this.createRock(
Math.random() * 60 - 30,
Math.random() * 60 - 30
);
}
}
createTree(x, z) {
// Tree trunk
const trunkGeometry = new THREE.CylinderGeometry(0.3, 0.4, 4);
const trunkMaterial = new THREE.MeshLambertMaterial({ color: 0x8B4513 });
const trunk = new THREE.Mesh(trunkGeometry, trunkMaterial);
trunk.position.set(x, 2, z);
trunk.castShadow = true;
this.scene.add(trunk);
// Tree leaves
const leavesGeometry = new THREE.SphereGeometry(2);
const leavesMaterial = new THREE.MeshLambertMaterial({ color: 0x228B22 });
const leaves = new THREE.Mesh(leavesGeometry, leavesMaterial);
leaves.position.set(x, 5, z);
leaves.castShadow = true;
this.scene.add(leaves);
}
createBuilding(x, y, z, width, height, depth, color) {
const geometry = new THREE.BoxGeometry(width, height, depth);
const material = new THREE.MeshLambertMaterial({ color: color });
const building = new THREE.Mesh(geometry, material);
building.position.set(x, height / 2, z);
building.castShadow = true;
building.receiveShadow = true;
this.scene.add(building);
// Add windows
const windowMaterial = new THREE.MeshLambertMaterial({ color: 0x87CEEB });
for (let i = 0; i < 3; i++) {
for (let j = 0; j < 2; j++) {
const window = new THREE.Mesh(
new THREE.PlaneGeometry(0.8, 0.8),
windowMaterial
);
window.position.set(
x + (j - 0.5) * (width - 1),
y + 2 + i * 2.5,
z + depth / 2 + 0.1
);
window.rotation.y = Math.PI;
this.scene.add(window);
}
}
}
createFountain(x, y, z) {
// Fountain base
const baseGeometry = new THREE.CylinderGeometry(3, 3, 0.5, 32);
const baseMaterial = new THREE.MeshLambertMaterial({ color: 0xCCCCCC });
const base = new THREE.Mesh(baseGeometry, baseMaterial);
base.position.set(x, 0.25, z);
base.receiveShadow = true;
this.scene.add(base);
// Fountain center
const centerGeometry = new THREE.CylinderGeometry(1, 1.2, 2, 32);
const centerMaterial = new THREE.MeshLambertMaterial({ color: 0xDDDDDD });
const center = new THREE.Mesh(centerGeometry, centerMaterial);
center.position.set(x, 1.5, z);
center.castShadow = true;
this.scene.add(center);
// Water (animated)
const waterGeometry = new THREE.CylinderGeometry(1.2, 1.2, 0.2, 32);
const waterMaterial = new THREE.MeshLambertMaterial({
color: 0x4F94CD,
transparent: true,
opacity: 0.7
});
const water = new THREE.Mesh(waterGeometry, waterMaterial);
water.position.set(x, 1.1, z);
water.userData = { type: 'fountain', animate: true };
this.scene.add(water);
this.interactiveObjects.push(water);
}
createRock(x, z) {
const geometry = new THREE.SphereGeometry(0.5 + Math.random() * 0.5, 6, 6);
const material = new THREE.MeshLambertMaterial({ color: 0x696969 });
const rock = new THREE.Mesh(geometry, material);
rock.position.set(x, 0.5, z);
rock.rotation.set(
Math.random() * Math.PI,
Math.random() * Math.PI,
Math.random() * Math.PI
);
rock.castShadow = true;
this.scene.add(rock);
}
async addInteractiveObjects() {
// Create interactive squirrel NPC
this.createSquirrel(10, 0, 0);
// Create treasure chest
this.createTreasureChest(-10, 0, 10);
// Create signpost
this.createSignpost(15, 0, -15);
}
createSquirrel(x, y, z) {
// Squirrel body
const bodyGeometry = new THREE.SphereGeometry(0.4, 16, 16);
const bodyMaterial = new THREE.MeshLambertMaterial({ color: 0xFF8C00 });
const body = new THREE.Mesh(bodyGeometry, bodyMaterial);
body.position.set(x, y + 0.4, z);
// Squirrel head
const headGeometry = new THREE.SphereGeometry(0.3, 16, 16);
const head = new THREE.Mesh(headGeometry, bodyMaterial);
head.position.set(x, y + 0.8, z + 0.3);
// Squirrel tail
const tailGeometry = new THREE.SphereGeometry(0.25, 16, 16);
const tail = new THREE.Mesh(tailGeometry, bodyMaterial);
tail.position.set(x, y + 0.4, z - 0.5);
tail.scale.set(1.5, 0.8, 2);
const squirrel = new THREE.Group();
squirrel.add(body);
squirrel.add(head);
squirrel.add(tail);
squirrel.userData = {
type: 'squirrel',
interactive: true,
message: "Hello! I'm your friendly squirrel guide. Explore the playground and find hidden treasures!"
};
squirrel.castShadow = true;
this.scene.add(squirrel);
this.interactiveObjects.push(squirrel);
}
createTreasureChest(x, y, z) {
const chestGeometry = new THREE.BoxGeometry(1.5, 0.8, 1);
const chestMaterial = new THREE.MeshLambertMaterial({ color: 0xDAA520 });