复刻监控人1.0
by TurboKoala83186 lines6.5 KB🛠️ Three.js (3D graphics)
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>复刻监控人1.0</title>
<style>
body { margin: 0; overflow: hidden; background: #2a2a2a; font-family: sans-serif; }
#info {
position: absolute; top: 10px; left: 10px; color: #fff;
background: rgba(0,0,0,0.6); padding: 10px; border-radius: 8px;
font-size: 13px; z-index: 10; pointer-events: none;
}
#btn {
position: absolute; bottom: 20px; left: 50%; transform: translateX(-50%);
padding: 14px 28px; background: #4CAF50; color: #fff; border: none;
border-radius: 30px; font-size: 16px; z-index: 10; cursor: pointer;
font-weight: bold;
}
#btn:active { background: #388E3C; }
</style>
</head>
<body>
<div id="info">🖱️ 拖动旋转 | 双指缩放<br>点击下方按钮导出 .obj</div>
<button id="btn">📦 导出 OBJ 模型</button>
<script src="https://cdn.jsdelivr.net/npm/three@0.128.0/build/three.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/three@0.128.0/examples/js/controls/OrbitControls.js"></script>
<script src="https://cdn.jsdelivr.net/npm/three@0.128.0/examples/js/exporters/OBJExporter.js"></script>
<script>
// === 场景基础 ===
const scene = new THREE.Scene();
scene.background = new THREE.Color(0x2a2a2a);
const camera = new THREE.PerspectiveCamera(45, innerWidth/innerHeight, 0.1, 100);
camera.position.set(0, 1.8, 3.5);
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(innerWidth, innerHeight);
renderer.shadowMap.enabled = true;
document.body.appendChild(renderer.domElement);
const controls = new THREE.OrbitControls(camera, renderer.domElement);
controls.target.set(0, 1.2, 0);
controls.update();
// === 灯光 ===
scene.add(new THREE.AmbientLight(0xffffff, 0.65));
const dirLight = new THREE.DirectionalLight(0xffffff, 0.8);
dirLight.position.set(5, 8, 5);
dirLight.castShadow = true;
scene.add(dirLight);
// === 材质定义 (Roblox风格:纯色、硬边、塑料感) ===
const matBlack = new THREE.MeshStandardMaterial({ color: 0x1a1a1a, roughness: 0.8 }); // 西装黑
const matWhite = new THREE.MeshStandardMaterial({ color: 0xeeeeee, roughness: 0.4 }); // 摄像头白
const matDarkGrey = new THREE.MeshStandardMaterial({ color: 0x333333, roughness: 0.5 }); // 镜头外壳
const matLens = new THREE.MeshStandardMaterial({ color: 0x111111, roughness: 0.1, metalness: 0.8, emissive: 0x2244ff, emissiveIntensity: 0.2 }); // 镜头玻璃
const matShirt = new THREE.MeshStandardMaterial({ color: 0xffffff, roughness: 0.6 }); // 衬衫
const matTie = new THREE.MeshStandardMaterial({ color: 0x1a1a2e, roughness: 0.7 }); // 领带深蓝/黑
// === 角色组 ===
const cameraman = new THREE.Group();
// --- 1. 躯干 (加宽加厚,接近你的截图) ---
const body = new THREE.Mesh(new THREE.BoxGeometry(0.55, 0.75, 0.3), matBlack);
body.position.set(0, 1.0, 0);
body.castShadow = true;
cameraman.add(body);
// --- 2. 双腿 (典型的Roblox粗方块) ---
const legGeo = new THREE.BoxGeometry(0.22, 0.65, 0.22);
const legL = new THREE.Mesh(legGeo, matBlack);
legL.position.set(-0.14, 0.33, 0);
legL.castShadow = true;
cameraman.add(legL);
const legR = new THREE.Mesh(legGeo, matBlack);
legR.position.set(0.14, 0.33, 0);
legR.castShadow = true;
cameraman.add(legR);
// --- 3. 双臂 (粗壮的方块,稍微向外张开) ---
const armGeo = new THREE.BoxGeometry(0.18, 0.7, 0.18);
const armL = new THREE.Mesh(armGeo, matBlack);
armL.position.set(-0.38, 0.95, 0);
armL.rotation.z = 0.08;
armL.castShadow = true;
cameraman.add(armL);
const armR = new THREE.Mesh(armGeo, matBlack);
armR.position.set(0.38, 0.95, 0);
armR.rotation.z = -0.08;
armR.castShadow = true;
cameraman.add(armR);
// --- 4. 头部 (根据你的截图,是一个大白色方块,前方有突出的镜头) ---
const headGroup = new THREE.Group();
headGroup.position.set(0, 1.6, 0);
// 4.1 头部主方块 (稍微宽一点,像你的截图)
const headMain = new THREE.Mesh(new THREE.BoxGeometry(0.55, 0.4, 0.55), matWhite);
headMain.castShadow = true;
headGroup.add(headMain);
// 4.2 头部上方的一个小突起 (模仿你截图中不规则的摄像头外形)
const headTop = new THREE.Mesh(new THREE.BoxGeometry(0.3, 0.1, 0.3), matWhite);
headTop.position.set(0, 0.25, -0.1);
headGroup.add(headTop);
// 4.3 正面镜头筒 (圆柱体,突出在正面)
const lensHousing = new THREE.Mesh(new THREE.CylinderGeometry(0.1, 0.1, 0.15, 16), matDarkGrey);
lensHousing.position.set(0, -0.05, 0.3);
lensHousing.rotation.x = Math.PI / 2;
headGroup.add(lensHousing);
// 4.4 镜头内部 (发光玻璃)
const lensGlass = new THREE.Mesh(new THREE.CylinderGeometry(0.07, 0.07, 0.05, 16), matLens);
lensGlass.position.set(0, -0.05, 0.38);
lensGlass.rotation.x = Math.PI / 2;
headGroup.add(lensGlass);
// 4.5 屏幕/黑色面板 (正面下方)
const screenPanel = new THREE.Mesh(new THREE.BoxGeometry(0.2, 0.15, 0.05), matDarkGrey);
screenPanel.position.set(0, 0.1, 0.28);
headGroup.add(screenPanel);
cameraman.add(headGroup);
// --- 5. 衬衫领口与领带 ---
const collar = new THREE.Mesh(new THREE.BoxGeometry(0.3, 0.08, 0.05), matShirt);
collar.position.set(0, 1.38, 0.16);
cameraman.add(collar);
const tie = new THREE.Mesh(new THREE.BoxGeometry(0.06, 0.3, 0.02), matTie);
tie.position.set(0, 1.2, 0.16);
cameraman.add(tie);
// --- 6. 领带结 ---
const tieKnot = new THREE.Mesh(new THREE.BoxGeometry(0.08, 0.08, 0.04), matTie);
tieKnot.position.set(0, 1.33, 0.17);
cameraman.add(tieKnot);
// --- 7. 地面 ---
const ground = new THREE.Mesh(
new THREE.CircleGeometry(2.5, 32),
new THREE.MeshStandardMaterial({ color: 0x444444, roughness: 1 })
);
ground.rotation.x = -Math.PI / 2;
ground.position.y = 0;
ground.receiveShadow = true;
scene.add(ground);
scene.add(cameraman);
// === 导出 OBJ 功能 ===
document.getElementById('btn').addEventListener('click', () => {
const exporter = new THREE.OBJExporter();
const result = exporter.parse(cameraman);
const blob = new Blob([result], { type: 'text/plain' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = 'my_cameraman.obj';
a.click();
URL.revokeObjectURL(url);
});
// === 渲染循环 ===
function animate() {
requestAnimationFrame(animate);
controls.update();
renderer.render(scene, camera);
}
animate();
// === 窗口适配 ===
addEventListener('resize', () => {
camera.aspect = innerWidth / innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(innerWidth, innerHeight);
});
</script>
</body>
</html>Game Source: 复刻监控人1.0
Creator: TurboKoala83
Libraries: three
Complexity: moderate (186 lines, 6.5 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: 1-0-turbokoala83" to link back to the original. Then publish at arcadelab.ai/publish.