🎮ArcadeLab

迷你世界 网页版

by BraveTurtle59
117 lines3.4 KB🛠️ Three.js (3D graphics)
▶ Play
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>迷你世界 网页版</title>
<style>
*{margin:0;padding:0;box-sizing:border-box;}
body{overflow:hidden;background:#87CEEB;font-family:Arial;}
#game{width:100vw;height:100vh;display:block;}
#tip{position:absolute;top:10px;left:10px;color:white;background:rgba(0,0,0,0.5);padding:8px;border-radius:6px;}
</style>
</head>
<body>
<div id="tip">WASD移动 | 鼠标视角 | 左键方块 | 右键拆除</div>
<canvas id="game"></canvas>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
<script>
// 初始化3D场景
const scene = new THREE.Scene();
scene.background = new THREE.Color(0x87, 0xCE, 0xEB);
const camera = new THREE.PerspectiveCamera(75, innerWidth/innerHeight, 0.1, 1000);
const renderer = new THREE.WebGLRenderer({canvas:document.getElementById("game")});
renderer.setSize(innerWidth, innerHeight);

// 光照
const light = new THREE.DirectionalLight(0xffffff, 1);
light.position.set(10,20,10);
scene.add(light);
scene.add(new THREE.AmbientLight(0xffffff,0.4));

// 草地地面
const groundMat = new THREE.MeshLambertMaterial({color:0x33aa33});
const blockMat = new THREE.MeshLambertMaterial({color:0xffdd77});
const blocks = [];

// 生成地形
for(let x=-20;x<20;x++){
  for(let z=-20;z<20;z++){
    const g = new THREE.Mesh(new THREE.BoxGeometry(1,1,1), groundMat);
    g.position.set(x,0,z);
    scene.add(g);
  }
}

camera.position.set(0,3,5);
let move={w:false,a:false,s:false,d:false};
let lock=false;

// 鼠标锁定
document.body.onclick=()=>{
  document.body.requestPointerLock();
  lock=true;
}
document.addEventListener("mousemove",e=>{
  if(!lock)return;
  camera.rotation.y -= e.movementX*0.002;
  camera.rotation.x -= e.movementY*0.002;
  camera.rotation.x = Math.max(-1.2, Math.min(1.2, camera.rotation.x));
})

// 键盘移动
document.addEventListener("keydown",e=>{
  if(e.key.toLowerCase() in move) move[e.key.toLowerCase()]=true;
})
document.addEventListener("keyup",e=>{
  if(e.key.toLowerCase() in move) move[e.key.toLowerCase()]=false;
})

// 方块放置&拆除
const raycaster = new THREE.Raycaster();
document.addEventListener("mousedown",e=>{
  raycaster.setFromCamera(new THREE.Vector2(0,0),camera);
  const hit = raycaster.intersectObjects(scene.children);
  if(!hit.length)return;
  if(e.button===0){
    // 左键放方块
    const b = new THREE.Mesh(new THREE.BoxGeometry(1,1,1), blockMat);
    b.position.copy(hit[0].point).add(hit[0].face.normal);
    b.position.x=Math.round(b.position.x);
    b.position.y=Math.round(b.position.y);
    b.position.z=Math.round(b.position.z);
    scene.add(b);
    blocks.push(b);
  }else if(e.button===2){
    // 右键拆方块
    const obj=hit[0].object;
    scene.remove(obj);
  }
})

// 循环更新
function loop(){
  const speed=0.15;
  const dir=new THREE.Vector3();
  camera.getWorldDirection(dir);
  dir.y=0;
  dir.normalize();
  const right=new THREE.Vector3().crossVectors(dir,new THREE.Vector3(0,1,0));

  if(move.w) camera.position.addScaledVector(dir,speed);
  if(move.s) camera.position.addScaledVector(dir,-speed);
  if(move.a) camera.position.addScaledVector(right,speed);
  if(move.d) camera.position.addScaledVector(right,-speed);

  renderer.render(scene,camera);
  requestAnimationFrame(loop);
}
loop();
window.onresize=()=>{
  camera.aspect=innerWidth/innerHeight;
  camera.updateProjectionMatrix();
  renderer.setSize(innerWidth,innerHeight);
}
</script>
</body>
</html>

Game Source: 迷你世界 网页版

Creator: BraveTurtle59

Libraries: three

Complexity: moderate (117 lines, 3.4 KB)

The full source code is displayed above on this page.

Remix Instructions

To remix this game, copy the source code above and modify it. Add a ARCADELAB header at the top with "remix_of: game-braveturtle59" to link back to the original. Then publish at arcadelab.ai/publish.