Meta Description" name="description" />
<!DOCTYPE html>
<html>
<head>
<title>Mobile Minecraft Clone</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; }
#ui { position: absolute; bottom: 20px; left: 20px; color: white; font-family: sans-serif; pointer-events: none; }
canvas { display: block; }
</style>
</head>
<body>
<div id="ui">Chạm màn hình để đặt khối</div>
<!-- Load thư viện Three.js từ CDN -->
<script type="module">
import * as THREE from 'https://cdn.skypack.dev/three@0.132.2';
// 1. Khởi tạo cảnh (Scene)
const scene = new THREE.Scene();
scene.background = new THREE.Color(0x87CEEB); // Màu trời
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);
// 2. Ánh sáng
const light = new THREE.DirectionalLight(0xffffff, 1);
light.position.set(5, 10, 7.5);
scene.add(light);
scene.add(new THREE.AmbientLight(0x404040));
// 3. Tạo khối vuông (Voxel)
const geometry = new THREE.BoxGeometry(1, 1, 1);
const material = new THREE.MeshLambertMaterial({ color: 0x44aa88 });
// Tạo mặt đất 10x10
for(let x = -5; x < 5; x++) {
for(let z = -5; z < 5; z++) {
const cube = new THREE.Mesh(geometry, material);
cube.position.set(x, 0, z);
scene.add(cube);
}
}
camera.position.set(0, 5, 10);
camera.lookAt(0, 0, 0);
// 4. Xử lý cảm ứng (Chạm để đặt khối)
const raycaster = new THREE.Raycaster();
const mouse = new THREE.Vector2();
window.addEventListener('touchstart', (event) => {
// Lấy tọa độ chạm
mouse.x = (event.touches[0].clientX / window.innerWidth) * 2 - 1;
mouse.y = -(event.touches[0].clientY / window.innerHeight) * 2 + 1;
raycaster.setFromCamera(mouse, camera);
const intersects = raycaster.intersectObjects(scene.children);
if (intersects.length > 0) {
const intersect = intersects[0];
const newCube = new THREE.Mesh(geometry, new THREE.MeshLambertMaterial({ color: Math.random() * 0xffffff }));
// Đặt khối mới dựa trên vị trí mặt được chạm (normal)
newCube.position.copy(intersect.object.position).add(intersect.face.normal);
scene.add(newCube);
}
});
// 5. Vòng lặp Render (Để camera xoay nhẹ cho sinh động)
function animate() {
requestAnimationFrame(animate);
scene.rotation.y += 0.005;
renderer.render(scene, camera);
}
animate();
// Xử lý khi xoay ngang/dọc điện thoại
window.addEventListener('resize', () => {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
});
</script>
</body>
</html>3
2
195KB
1044KB
388.0ms
180.0ms
388.0ms