Spaces:
Sleeping
Sleeping
<html> | |
<head> | |
<title>Basic Three.js 2.5D Scene</title> | |
<style> | |
body { margin: 0; } | |
canvas { display: block; } | |
</style> | |
</head> | |
<body> | |
<script type="importmap"> | |
{ | |
"imports": { | |
"three": "https://unpkg.com/[email protected]/build/three.module.js", | |
"three/addons/": "https://unpkg.com/[email protected]/examples/jsm/" | |
} | |
} | |
</script> | |
<script type="module"> | |
import * as THREE from 'three'; | |
let scene, camera, renderer, playerMesh; | |
let moveForward = false, moveBackward = false, moveLeft = false, moveRight = false; | |
const playerSpeed = 0.1; | |
function init() { | |
// --- Basic Setup --- | |
scene = new THREE.Scene(); | |
scene.background = new THREE.Color(0x87CEEB); // Sky blue background | |
// --- Camera (Orthographic for 2.5D feel) --- | |
const aspect = window.innerWidth / window.innerHeight; | |
const viewSize = 15; // How many units are visible vertically | |
camera = new THREE.OrthographicCamera( | |
-viewSize * aspect / 2, viewSize * aspect / 2, | |
viewSize / 2, -viewSize / 2, | |
1, 1000 | |
); | |
camera.position.set(5, 10, 5); // Positioned above and looking down | |
camera.lookAt(0, 0, 0); // Look at the center of the scene | |
scene.add(camera); | |
// --- Lighting --- | |
const ambientLight = new THREE.AmbientLight(0xffffff, 0.6); | |
scene.add(ambientLight); | |
const directionalLight = new THREE.DirectionalLight(0xffffff, 0.8); | |
directionalLight.position.set(5, 10, 7.5); | |
scene.add(directionalLight); | |
// --- Ground --- | |
const groundGeometry = new THREE.PlaneGeometry(20, 20); | |
const groundMaterial = new THREE.MeshLambertMaterial({ color: 0x228B22 }); // Forest green | |
const groundMesh = new THREE.Mesh(groundGeometry, groundMaterial); | |
groundMesh.rotation.x = -Math.PI / 2; // Rotate to lie flat | |
groundMesh.position.y = -0.5; // Slightly below origin | |
scene.add(groundMesh); | |
// --- Player Placeholder (Simple Cube) --- | |
// In a real game, you'd load a sprite/texture here | |
const playerGeometry = new THREE.BoxGeometry(0.8, 0.8, 0.8); | |
const playerMaterial = new THREE.MeshLambertMaterial({ color: 0xff0000 }); // Red | |
playerMesh = new THREE.Mesh(playerGeometry, playerMaterial); | |
playerMesh.position.y = 0; // Place on top of the ground level | |
scene.add(playerMesh); | |
// --- Renderer --- | |
renderer = new THREE.WebGLRenderer({ antialias: true }); | |
renderer.setSize(window.innerWidth, window.innerHeight); | |
document.body.appendChild(renderer.domElement); | |
// --- Event Listeners for Movement --- | |
document.addEventListener('keydown', onKeyDown); | |
document.addEventListener('keyup', onKeyUp); | |
window.addEventListener('resize', onWindowResize); // Handle window resizing | |
// --- Start Animation --- | |
animate(); | |
} | |
function onKeyDown(event) { | |
switch (event.code) { | |
case 'KeyW': | |
case 'ArrowUp': | |
moveForward = true; | |
break; | |
case 'KeyS': | |
case 'ArrowDown': | |
moveBackward = true; | |
break; | |
case 'KeyA': | |
case 'ArrowLeft': | |
moveLeft = true; | |
break; | |
case 'KeyD': | |
case 'ArrowRight': | |
moveRight = true; | |
break; | |
} | |
} | |
function onKeyUp(event) { | |
switch (event.code) { | |
case 'KeyW': | |
case 'ArrowUp': | |
moveForward = false; | |
break; | |
case 'KeyS': | |
case 'ArrowDown': | |
moveBackward = false; | |
break; | |
case 'KeyA': | |
case 'ArrowLeft': | |
moveLeft = false; | |
break; | |
case 'KeyD': | |
case 'ArrowRight': | |
moveRight = false; | |
break; | |
} | |
} | |
function updatePlayerPosition() { | |
if (!playerMesh) return; | |
const moveVector = new THREE.Vector3(); | |
if (moveForward) moveVector.z -= 1; | |
if (moveBackward) moveVector.z += 1; | |
if (moveLeft) moveVector.x -= 1; | |
if (moveRight) moveVector.x += 1; | |
// Normalize diagonal movement and apply speed | |
if (moveVector.lengthSq() > 0) { // Check if there's any movement | |
moveVector.normalize().multiplyScalar(playerSpeed); | |
playerMesh.position.add(moveVector); | |
} | |
// Keep camera centered on player (optional basic follow) | |
// camera.position.x = playerMesh.position.x; | |
// camera.position.z = playerMesh.position.z + 5; // Adjust Z offset as needed | |
// camera.lookAt(playerMesh.position); | |
} | |
function onWindowResize() { | |
const aspect = window.innerWidth / window.innerHeight; | |
const viewSize = 15; | |
camera.left = -viewSize * aspect / 2; | |
camera.right = viewSize * aspect / 2; | |
camera.top = viewSize / 2; | |
camera.bottom = -viewSize / 2; | |
camera.updateProjectionMatrix(); | |
renderer.setSize(window.innerWidth, window.innerHeight); | |
} | |
function animate() { | |
requestAnimationFrame(animate); // Loop the animation | |
updatePlayerPosition(); // Update player based on input | |
renderer.render(scene, camera); // Render the scene | |
} | |
// --- Start the app --- | |
init(); | |
</script> | |
</body> | |
</html> |