Meta Description" name="description" />

Share this result

Previews are deleted daily. Get a permanent share link sent to your inbox:
Script
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Advanced JS Minecraft</title> <style> body { margin: 0; overflow: hidden; font-family: sans-serif; } #crosshair { position: absolute; top: 50%; left: 50%; width: 10px; height: 10px; transform: translate(-50%, -50%); color: white; font-weight: bold; font-size: 20px; pointer-events: none; user-select: none; z-index: 10; } #ui-container { position: absolute; top: 10px; left: 10px; color: white; background: rgba(0,0,0,0.6); padding: 15px; border-radius: 8px; pointer-events: none; } #hotbar { position: absolute; bottom: 20px; left: 50%; transform: translateX(-50%); display: flex; background: rgba(0,0,0,0.6); padding: 8px; border-radius: 5px; gap: 5px; } .slot { width: 50px; height: 50px; border: 3px solid #555; display: flex; flex-direction: column; align-items: center; justify-content: center; color: white; font-size: 10px; font-weight: bold; text-align: center; border-radius: 4px; background-size: cover; } .slot.active { border-color: #fff; background-color: rgba(255,255,255,0.3); } </style> </head> <body> <div id="crosshair">+</div> <div id="ui-container"> <strong>Controls:</strong><br> Click screen to lock mouse<br> WASD = Move | Space = Jump<br> Left Click = Destroy | Right Click = Place<br> Keys 1 - 5 = Select Hotbar Slot </div> <div id="hotbar"> <div class="slot active" id="slot1" style="background-color: #557a2b;">Grass<br>[1]</div> <div class="slot" id="slot2" style="background-color: #777777;">Stone<br>[2]</div> <div class="slot" id="slot3" style="background-color: #d14915;">Lava<br>[3]</div> <div class="slot" id="slot4" style="background-color: #2c2d30;">Netherite<br>[4]</div> <div class="slot" id="slot5" style="background-color: #ffc0cb; color: black;">Spawn Animal<br>[5]</div> </div> <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/three@0.128.0/examples/js/controls/PointerLockControls.js"></script> <script> // 1. Scene Setup const scene = new THREE.Scene(); scene.background = new THREE.Color(0x87CEEB); scene.fog = new THREE.FogExp2(0x87CEEB, 0.03); const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); const renderer = new THREE.WebGLRenderer({ antialias: true }); renderer.setSize(window.innerWidth, window.innerHeight); document.body.appendChild(renderer.domElement); // Lights const ambientLight = new THREE.AmbientLight(0xffffff, 0.5); scene.add(ambientLight); const sunLight = new THREE.DirectionalLight(0xffffff, 0.7); sunLight.position.set(20, 40, 20); scene.add(sunLight); // 2. Inventory & Block Types System const BLOCK_TYPES = { 1: { name: 'Grass', color: '#557a2b', isMob: false }, 2: { name: 'Stone', color: '#777777', isMob: false }, 3: { name: 'Lava', color: '#d14915', isMob: false }, 4: { name: 'Netherite', color: '#2c2d30', isMob: false }, 5: { name: 'Animal', color: null, isMob: true } }; let activeSlot = 1; // Visual grid textures function createBlockMaterial(color) { const canvas = document.createElement('canvas'); canvas.width = 16; canvas.height = 16; const ctx = canvas.getContext('2d'); ctx.fillStyle = color; ctx.fillRect(0, 0, 16, 16); ctx.strokeStyle = 'rgba(0,0,0,0.2)'; ctx.lineWidth = 1; ctx.strokeRect(0, 0, 16, 16); return new THREE.MeshStandardMaterial({ map: new THREE.CanvasTexture(canvas), roughness: 0.8 }); } const materials = { 1: createBlockMaterial('#557a2b'), 2: createBlockMaterial('#777777'), 3: new THREE.MeshStandardMaterial({ color: 0xd14915, emissive: 0x5a1800, roughness: 0.2 }), // Glowing Lava 4: createBlockMaterial('#2c2d30') }; const geometry = new THREE.BoxGeometry(1, 1, 1); const blocks = []; const animals = []; // Build flat starter terrain map for (let x = 0; x < 20; x++) { for (let z = 0; z < 20; z++) { const mat = (x === 0 || x === 19 || z === 0 || z === 19) ? materials[2] : materials[1]; // stone border const block = new THREE.Mesh(geometry, mat); block.position.set(x, 0, z); scene.add(block); blocks.push(block); } } // 3. Animals (Mobs) System function spawnAnimal(x, y, z) { const isPig = Math.random() > 0.5; const animalGroup = new THREE.Group(); // Body const bodyMat = new THREE.MeshStandardMaterial({ color: isPig ? 0xffb6c1 : 0xffffff }); // Pink Pig or White Sheep const body = new THREE.Mesh(new THREE.BoxGeometry(0.6, 0.6, 0.9), bodyMat); body.position.y = 0.4; animalGroup.add(body); // Head const head = new THREE.Mesh(new THREE.BoxGeometry(0.4, 0.4, 0.4), bodyMat); head.position.set(0, 0.6, 0.5); animalGroup.add(head); animalGroup.position.set(x, y, z); scene.add(animalGroup); animals.push({ mesh: animalGroup, velocity: new THREE.Vector3(), directionTimer: 0, moveX: 0, moveZ: 0 }); } // Spawn a couple starter animals spawnAnimal(5, 1, 5); spawnAnimal(10, 1, 10); // 4. Controls & Movement Engine const controls = new THREE.PointerLockControls(camera, document.body); document.body.addEventListener('click', () => controls.lock()); let moveForward = false, moveBackward = false, moveLeft = false, moveRight = false; let playerVelocity = new THREE.Vector3(); let playerDirection = new THREE.Vector3(); let canJump = false; document.addEventListener('keydown', (e) => { if (/^[1-5]$/.test(e.key)) { document.getElementById(`slot${activeSlot}`).classList.remove('active'); activeSlot = parseInt(e.key); document.getElementById(`slot${activeSlot}`).classList.add('active'); } switch (e.code) { case 'KeyW': moveForward = true; break; case 'KeyS': moveBackward = true; break; case 'KeyA': moveLeft = true; break; case 'KeyD': moveRight = true; break; case 'Space': if (canJump) playerVelocity.y += 8; canJump = false; break; } }); document.addEventListener('keyup', (e) => { switch (e.code) { case 'KeyW': moveForward = false; break; case 'KeyS': moveBackward = false; break; case 'KeyA': moveLeft = false; break; case 'KeyD': moveRight = false; break; } }); camera.position.set(10, 3, 10); // 5. Build / Destroy Interaction const raycaster = new THREE.Raycaster(); const mouse = new THREE.Vector2(0, 0); document.addEventListener('pointerdown', (e) => { if (!controls.isLocked) return; raycaster.setFromCamera(mouse, camera); const intersects = raycaster.intersectObjects(blocks); if (intersects.length > 0 && intersects[0].distance < 7) { const intersect = intersects[0]; if (e.button === 0) { // Left Click: Destroy scene.remove(intersect.object); blocks.splice(blocks.indexOf(intersect.object), 1); } else if (e.button === 2) { // Right Click: Place Block OR Spawn Mob const spawnPos = intersect.object.position.clone().add(intersect.face.normal); const currentSelection = BLOCK_TYPES[activeSlot]; if (currentSelection.isMob) { spawnAnimal(spawnPos.x, spawnPos.y, spawnPos.z); } else { const newBlock = new THREE.Mesh(geometry, materials[activeSlot]); newBlock.position.copy(spawnPos); scene.add(newBlock); blocks.push(newBlock); } } } }); document.addEventListener('contextmenu', e => e.preventDefault()); // 6. Physics and Game Loop Animation const clock = new THREE.Clock(); const gravity = 20; function animate() { requestAnimationFrame(animate); const delta = Math.min(clock.getDelta(), 0.1); // cap delta to prevent clipping glitches if (controls.isLocked) { // Player Physics playerVelocity.x -= playerVelocity.x * 10.0 * delta; playerVelocity.z -= playerVelocity.z * 10.0 * delta; playerVelocity.y -= gravity * delta; playerDirection.z = Number(moveForward) - Number(moveBackward); playerDirection.x = Number(moveRight) - Number(moveLeft); playerDirection.normalize(); if (moveForward || moveBackward) playerVelocity.z -= playerDirection.z * 40.0 * delta; if (moveLeft || moveRight) playerVelocity.x -= playerDirection.x * 40.0 * delta; controls.moveRight(-playerVelocity.x * delta); controls.moveForward(-playerVelocity.z * delta); camera.position.y += playerVelocity.y * delta; // Ground Collision if (camera.position.y < 2) { playerVelocity.y = 0; camera.position.y = 2; canJump = true; } } // AI Animal Logic animals.forEach(animal => { animal.directionTimer -= delta; if (animal.directionTimer <= 0) { // Pick a random direction or idle animal.moveX = (Math.random() - 0.5) * 2; animal.moveZ = (Math.random() - 0.5) * 2; animal.directionTimer = Math.random() * 3 + 1; // Change minds every 1-4 seconds // Random chance to jump if(Math.random() > 0.6 && animal.mesh.position.y <= 0.1) { animal.velocity.y = 5; } } // Apply gravity to animal animal.velocity.y -= gravity * delta; animal.mesh.position.y += animal.velocity.y * delta; // Simple flat world boundaries for animals if (animal.mesh.position.y < 0) { animal.mesh.position.y = 0; animal.velocity.y = 0; } // Move animal smoothly animal.mesh.position.x += animal.moveX * delta; animal.mesh.position.z += animal.moveZ * delta; // Make animal face the direction it's walking if(Math.abs(animal.moveX) > 0.1 || Math.abs(animal.moveZ) > 0.1) { animal.mesh.rotation.y = Math.atan2(animal.moveX, animal.moveZ); } }); renderer.render(scene, camera); } animate(); window.addEventListener('resize', () => { camera.aspect = window.innerWidth / window.innerHeight; camera.updateProjectionMatrix(); renderer.setSize(window.innerWidth, window.innerHeight); }); </script> </body> </html>
Landing Page
This ad does not have a landing page available
Network Timeline
Performance Summary

3

Requests

3

Domains

133KB

Transfer Size

605KB

Content Size

3,212.0ms

Dom Content Loaded

112.0ms

First Paint

3,212.0ms

Load Time
Domain Breakdown
Transfer Size (bytes)
Loading...
Content Size (bytes)
Loading...
Header Size (bytes)
Loading...
Requests
Loading...
Timings (ms)
Loading...
Total Time
Loading...
Content Breakdown
Transfer Size (bytes)
Loading...
Content Size (bytes)
Loading...
Header Size (bytes)
Loading...
Requests
Loading...