Monster's Creepy Feast
]]>
{
if (rabbit.isAlive) {
rabbit.update(deltaTime);
// Check collision with player
if (this.player.mesh.position.distanceTo(rabbit.mesh.position) < 1.2) { // Collision radius
this.eatRabbit(rabbit);
}
}
});
if (this.score === this.totalRabbits) {
this.winGame();
}
}
eatRabbit(rabbit) {
rabbit.getEaten();
this.score++;
this.updateScoreUI();
}
winGame() {
this.gameOver = true;
this.messageElement.textContent = "YUM! All rabbits eaten!";
}
updateScoreUI() {
this.scoreElement.textContent = `Rabbits Eaten: ${this.score} / ${this.totalRabbits}`;
}
}
]]>
{
switch (event.code) {
case 'KeyW': case 'ArrowUp': this.input.forward = 1; break;
case 'KeyS': case 'ArrowDown': this.input.forward = -1; break;
case 'KeyA': case 'ArrowLeft': this.input.turn = 1; break;
case 'KeyD': case 'ArrowRight': this.input.turn = -1; break;
}
});
document.addEventListener('keyup', (event) => {
switch (event.code) {
case 'KeyW': case 'ArrowUp': if (this.input.forward > 0) this.input.forward = 0; break;
case 'KeyS': case 'ArrowDown': if (this.input.forward < 0) this.input.forward = 0; break;
case 'KeyA': case 'ArrowLeft': if (this.input.turn > 0) this.input.turn = 0; break;
case 'KeyD': case 'ArrowRight': if (this.input.turn < 0) this.input.turn = 0; break;
}
});
}
update(deltaTime) {
// Rotation
this.mesh.rotateY(this.input.turn * PLAYER_ROTATION_SPEED * deltaTime);
// Movement
const forwardDirection = new THREE.Vector3(0, 0, -1);
forwardDirection.applyQuaternion(this.mesh.quaternion);
this.velocity.copy(forwardDirection).multiplyScalar(this.input.forward * PLAYER_SPEED * deltaTime);
this.mesh.position.add(this.velocity);
// Boundary checks
const halfRoom = this.roomSize / 2 - 0.5; // 0.5 is approx player radius
this.mesh.position.x = Math.max(-halfRoom, Math.min(halfRoom, this.mesh.position.x));
this.mesh.position.z = Math.max(-halfRoom, Math.min(halfRoom, this.mesh.position.z));
this.updateCamera();
}
updateCamera() {
const cameraPosition = this.cameraOffset.clone();
cameraPosition.applyQuaternion(this.mesh.quaternion); // Rotate offset with player
cameraPosition.add(this.mesh.position);
this.camera.position.lerp(cameraPosition, 0.1); // Smooth camera movement
this.camera.lookAt(this.mesh.position.x, this.mesh.position.y + 1, this.mesh.position.z); // Look slightly above player center
}
}
]]>
{
const wallGeometry = new THREE.BoxGeometry(roomSize, wallHeight, 0.2);
const wall = new THREE.Mesh(wallGeometry, wallMaterial);
wall.position.set(pos.x, wallHeight / 2, pos.z);
wall.rotation.y = pos.rotY;
wall.receiveShadow = true;
wall.castShadow = true;
scene.add(wall);
});
// Simple Furniture
const furnitureMaterial = new THREE.MeshStandardMaterial({ color: 0x3d2d1d, roughness: 0.8 }); // Darker wood
// Table
const tableTopGeo = new THREE.BoxGeometry(3, 0.2, 1.5);
const tableTop = new THREE.Mesh(tableTopGeo, furnitureMaterial);
tableTop.position.set(-roomSize/4, 0.8, -roomSize/4);
tableTop.castShadow = true;
tableTop.receiveShadow = true;
scene.add(tableTop);
const legGeo = new THREE.BoxGeometry(0.2, 0.8, 0.2);
[-1.4, 1.4].forEach(xOff => {
[-0.65, 0.65].forEach(zOff => {
const leg = new THREE.Mesh(legGeo, furnitureMaterial);
leg.position.set(tableTop.position.x + xOff, 0.4, tableTop.position.z + zOff);
leg.castShadow = true;
scene.add(leg);
});
});
// Bookshelf
const shelfGeo = new THREE.BoxGeometry(0.4, 3, 1.5);
const bookshelf = new THREE.Mesh(shelfGeo, furnitureMaterial);
bookshelf.position.set(roomSize/3, 1.5, roomSize/2 - 0.8);
bookshelf.castShadow = true;
bookshelf.receiveShadow = true;
scene.add(bookshelf);
for(let i=0; i<4; i++) {
const plankGeo = new THREE.BoxGeometry(1.4, 0.1, 0.35);
const plank = new THREE.Mesh(plankGeo, furnitureMaterial);
plank.position.set(bookshelf.position.x + 0.02, 0.5 + i*0.7, bookshelf.position.z);
plank.rotation.y = Math.PI/2;
scene.add(plank);
}
}
]]>