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="vi"> <head> <meta charset="UTF-8"> <title>Minecraft Mobile: Rotation & Look</title> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"> <style> body { margin: 0; overflow: hidden; user-select: none; touch-action: none; background: #87CEEB; } canvas { display: block; } /* UI Layer */ #ui-layer { position: absolute; bottom: 20px; width: 100%; display: flex; justify-content: space-between; padding: 0 20px; box-sizing: border-box; pointer-events: none; } .btn { width: 65px; height: 65px; background: rgba(255,255,255,0.3); border-radius: 50%; display: flex; align-items: center; justify-content: center; color: white; font-weight: bold; font-family: sans-serif; pointer-events: auto; } #break-btn { background: rgba(255, 0, 0, 0.4); margin-bottom: 15px; } #joystick-container { width: 100px; height: 100px; background: rgba(255,255,255,0.2); border-radius: 50%; display: flex; align-items: center; justify-content: center; pointer-events: auto; } #joystick-handle { width: 50px; height: 50px; background: rgba(255,255,255,0.5); border-radius: 50%; } #right-controls { display: flex; flex-direction: column; align-items: center; } </style> </head> <body> <div id="ui-layer"> <div id="joystick-container"><div id="joystick-handle"></div></div> <div id="right-controls"> <div id="break-btn" class="btn">PHÁ</div> <div id="jump-btn" class="btn">NHẢY</div> </div> </div> <script type="module"> import * as THREE from 'https://cdn.skypack.dev/three@0.132.2'; const scene = new THREE.Scene(); scene.background = new THREE.Color(0x87CEEB); const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); const renderer = new THREE.WebGLRenderer({ antialias: false }); renderer.setSize(window.innerWidth, window.innerHeight); document.body.appendChild(renderer.domElement); const light = new THREE.AmbientLight(0xffffff, 0.8); scene.add(light); const dLight = new THREE.DirectionalLight(0xffffff, 0.4); dLight.position.set(10, 20, 10); scene.add(dLight); // --- NHÂN VẬT & XOAY --- const player = { mesh: new THREE.Group(), velocity: new THREE.Vector3(0, 0, 0), isGrounded: false, yaw: 0, // Xoay trái/phải pitch: 0, // Xoay lên/xuống lastInteracted: null }; const pBody = new THREE.Mesh(new THREE.BoxGeometry(0.6, 1.8, 0.6), new THREE.MeshLambertMaterial({color: 0x0000ff})); pBody.position.y = 0.9; player.mesh.add(pBody); player.mesh.position.set(0, 5, 0); scene.add(player.mesh); const blocks = []; const blockGeo = new THREE.BoxGeometry(1, 1, 1); const matGrass = new THREE.MeshLambertMaterial({ color: 0x44aa88 }); const matWood = new THREE.MeshLambertMaterial({ color: 0x5D4037 }); const matLeaves = new THREE.MeshLambertMaterial({ color: 0x2E7D32 }); function createBlock(x, y, z, type = 'grass') { const mat = type === 'wood' ? matWood : (type === 'leaves' ? matLeaves : matGrass); const cube = new THREE.Mesh(blockGeo, mat); cube.position.set(x, y, z); cube.userData.id = `${x},${y},${z}`; scene.add(cube); blocks.push(cube); } // --- CẢM ỨNG XOAY MÀN HÌNH --- let touchStartX = 0, touchStartY = 0; let isRotating = false; window.addEventListener('touchstart', (e) => { const touch = e.touches[e.touches.length - 1]; // Nếu chạm vào vùng trống (không phải joystick/nút) if (!e.target.closest('.btn') && !e.target.closest('#joystick-container')) { isRotating = true; touchStartX = touch.clientX; touchStartY = touch.clientY; } }); window.addEventListener('touchmove', (e) => { if (!isRotating) return; const touch = e.touches[e.touches.length - 1]; const dx = touch.clientX - touchStartX; const dy = touch.clientY - touchStartY; player.yaw -= dx * 0.005; // Tốc độ xoay ngang player.pitch -= dy * 0.005; // Tốc độ xoay dọc player.pitch = Math.max(-Math.PI/3, Math.min(Math.PI/3, player.pitch)); // Giới hạn ngước lên/xuống touchStartX = touch.clientX; touchStartY = touch.clientY; }); window.addEventListener('touchend', () => isRotating = false); // --- PHÁ & ĐẶT KHỐI --- const raycaster = new THREE.Raycaster(); const mouse = new THREE.Vector2(0, 0); // Tâm màn hình document.getElementById('break-btn').addEventListener('touchstart', () => { raycaster.setFromCamera(mouse, camera); const intersects = raycaster.intersectObjects(blocks); if (intersects.length > 0) { const target = intersects[0].object; scene.remove(target); blocks.splice(blocks.indexOf(target), 1); } }); // Chạm nhanh để đặt khối window.addEventListener('click', (e) => { if (e.target.closest('.btn') || e.target.closest('#joystick-container')) return; raycaster.setFromCamera(mouse, camera); const intersects = raycaster.intersectObjects(blocks); if (intersects.length > 0) { const b = intersects[0]; const pos = b.object.position.clone().add(b.face.normal); createBlock(pos.x, pos.y, pos.z); } }); // --- JOYSTICK & DI CHUYỂN --- let moveData = { x: 0, z: 0 }; const joyContainer = document.getElementById('joystick-container'); const joyHandle = document.getElementById('joystick-handle'); joyContainer.addEventListener('touchmove', (e) => { const rect = joyContainer.getBoundingClientRect(); const dx = e.touches[0].clientX - (rect.left + 50); const dy = e.touches[0].clientY - (rect.top + 50); const dist = Math.min(Math.sqrt(dx*dx + dy*dy), 50); const angle = Math.atan2(dy, dx); joyHandle.style.transform = `translate(${Math.cos(angle)*dist}px, ${Math.sin(angle)*dist}px)`; moveData.x = (Math.cos(angle) * dist) / 50; moveData.z = (Math.sin(angle) * dist) / 50; }); joyContainer.addEventListener('touchend', () => { joyHandle.style.transform = `translate(0,0)`; moveData = { x: 0, z: 0 }; }); document.getElementById('jump-btn').addEventListener('touchstart', () => { if (player.isGrounded) player.velocity.y = 0.15; }); // --- VÒNG LẶP CHÍNH --- function generateWorld() { const px = Math.round(player.mesh.position.x); const pz = Math.round(player.mesh.position.z); for (let x = px-7; x < px+7; x++) { for (let z = pz-7; z < pz+7; z++) { const id = `${x},${z}_g`; if (!blocks.find(b => b.userData.id === id)) { const y = Math.floor(Math.sin(x/6)*1.2); createBlock(x, y, z); blocks[blocks.length-1].userData.id = id; if(Math.random() > 0.99) { // Cây mọc hiếm hơn tí cho đỡ lag for(let i=1; i<=3; i++) createBlock(x, y+i, z, 'wood'); } } } } } function animate() { requestAnimationFrame(animate); // 1. Cập nhật vật lý rơi player.velocity.y -= 0.008; player.mesh.position.y += player.velocity.y; // 2. Di chuyển dựa trên hướng Camera (Yaw) const forward = new THREE.Vector3(Math.sin(player.yaw), 0, Math.cos(player.yaw)); const right = new THREE.Vector3().crossVectors(new THREE.Vector3(0,1,0), forward); player.mesh.position.addScaledVector(forward, -moveData.z * 0.12); player.mesh.position.addScaledVector(right, moveData.x * 0.12); // 3. Xử lý va chạm sàn player.isGrounded = false; blocks.forEach(b => { if (Math.abs(player.mesh.position.x - b.position.x) < 0.7 && Math.abs(player.mesh.position.z - b.position.z) < 0.7) { const floorY = b.position.y + 1.4; if (player.mesh.position.y < floorY && player.mesh.position.y > b.position.y - 0.5) { player.mesh.position.y = floorY; player.velocity.y = 0; player.isGrounded = true; } } }); // 4. Cập nhật Camera (Third Person Orbit) const camDist = 6; camera.position.x = player.mesh.position.x + Math.sin(player.yaw) * Math.cos(player.pitch) * camDist; camera.position.y = player.mesh.position.y + Math.sin(player.pitch) * camDist + 2.5; camera.position.z = player.mesh.position.z + Math.cos(player.yaw) * Math.cos(player.pitch) * camDist; camera.lookAt(player.mesh.position.x, player.mesh.position.y + 1.5, player.mesh.position.z); generateWorld(); renderer.render(scene, camera); } animate(); </script> </body> </html>
Landing Page
This ad does not have a landing page available
Network Timeline
Performance Summary

3

Requests

2

Domains

201KB

Transfer Size

1050KB

Content Size

319.0ms

Dom Content Loaded

116.0ms

First Paint

319.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...