🎮ArcadeLab

3D 红衣军士兵 - Three.js

by TurboKoala83
175 lines6.9 KB🛠️ Three.js (3D graphics)
▶ Play
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>3D 红衣军士兵 - Three.js</title>
    <style>
        body { margin: 0; overflow: hidden; background-color: #87CEEB; }
        canvas { display: block; }
    </style>
</head>
<body>
    <!-- 引入 Three.js 核心库 -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>

    <script>
        // 1. 初始化场景、相机、渲染器
        const scene = new THREE.Scene();
        scene.background = new THREE.Color(0x87CEEB); // 天空蓝
        scene.fog = new THREE.Fog(0x87CEEB, 10, 50); // 雾效

        const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
        camera.position.set(0, 1.6, 3); // 模拟人眼高度,站在士兵前方
        camera.lookAt(0, 1.2, 0);

        const renderer = new THREE.WebGLRenderer({ antialias: true });
        renderer.setSize(window.innerWidth, window.innerHeight);
        renderer.shadowMap.enabled = true;
        document.body.appendChild(renderer.domElement);

        // 2. 光照设置
        const ambientLight = new THREE.AmbientLight(0xffffff, 0.6);
        scene.add(ambientLight);

        const dirLight = new THREE.DirectionalLight(0xffffff, 0.8);
        dirLight.position.set(5, 10, 5);
        dirLight.castShadow = true;
        scene.add(dirLight);

        // 3. 创建地面 (草地)
        const groundGeometry = new THREE.PlaneGeometry(50, 50);
        const groundMaterial = new THREE.MeshStandardMaterial({ color: 0x4d7c37, roughness: 0.8 });
        const ground = new THREE.Mesh(groundGeometry, groundMaterial);
        ground.rotation.x = -Math.PI / 2;
        ground.receiveShadow = true;
        scene.add(ground);

        // 添加一些草块增加层次感
        for(let i = 0; i < 50; i++) {
            const grassGeo = new THREE.BoxGeometry(0.1, Math.random() * 0.5 + 0.2, 0.1);
            const grassMat = new THREE.MeshStandardMaterial({ color: 0x5a8f43 });
            const grass = new THREE.Mesh(grassGeo, grassMat);
            grass.position.set((Math.random() - 0.5) * 20, 0.1, (Math.random() - 0.5) * 20);
            grass.castShadow = true;
            scene.add(grass);
        }

        // 4. 拼装红衣军士兵 (低多边形版)
        const soldierGroup = new THREE.Group();
        soldierGroup.position.set(0, 0, 0);

        // 颜色定义
        const redCoat = new THREE.MeshStandardMaterial({ color: 0xcc0000, roughness: 0.6 });
        const whitePants = new THREE.MeshStandardMaterial({ color: 0xdddddd, roughness: 0.7 });
        const blackBoots = new THREE.MeshStandardMaterial({ color: 0x222222, roughness: 0.9 });
        const skinColor = new THREE.MeshStandardMaterial({ color: 0xffcc99, roughness: 0.5 });
        const blackHat = new THREE.MeshStandardMaterial({ color: 0x111111, roughness: 0.8 });
        const gunWood = new THREE.MeshStandardMaterial({ color: 0x5c3a21 });
        const gunMetal = new THREE.MeshStandardMaterial({ color: 0xaaaaaa, metalness: 0.8, roughness: 0.2 });

        // 躯干 (红色军装)
        const torso = new THREE.Mesh(new THREE.BoxGeometry(0.6, 0.8, 0.3), redCoat);
        torso.position.y = 1.1;
        torso.castShadow = true;
        soldierGroup.add(torso);

        // 头部
        const head = new THREE.Mesh(new THREE.SphereGeometry(0.22, 16, 16), skinColor);
        head.position.y = 1.68;
        head.castShadow = true;
        soldierGroup.add(head);

        // 三角帽 (用扁圆柱体模拟)
        const hat = new THREE.Mesh(new THREE.CylinderGeometry(0.3, 0.35, 0.15, 3), blackHat);
        hat.position.y = 1.85;
        hat.rotation.y = Math.PI / 6;
        hat.castShadow = true;
        soldierGroup.add(hat);

        // 腿部 (白色军裤)
        const leftLeg = new THREE.Mesh(new THREE.BoxGeometry(0.18, 0.7, 0.18), whitePants);
        leftLeg.position.set(-0.15, 0.6, 0);
        leftLeg.castShadow = true;
        soldierGroup.add(leftLeg);

        const rightLeg = new THREE.Mesh(new THREE.BoxGeometry(0.18, 0.7, 0.18), whitePants);
        rightLeg.position.set(0.15, 0.6, 0);
        rightLeg.castShadow = true;
        soldierGroup.add(rightLeg);

        // 鞋子 (黑色)
        const leftBoot = new THREE.Mesh(new THREE.BoxGeometry(0.2, 0.2, 0.3), blackBoots);
        leftBoot.position.set(-0.15, 0.1, 0.05);
        leftBoot.castShadow = true;
        soldierGroup.add(leftBoot);

        const rightBoot = new THREE.Mesh(new THREE.BoxGeometry(0.2, 0.2, 0.3), blackBoots);
        rightBoot.position.set(0.15, 0.1, 0.05);
        rightBoot.castShadow = true;
        soldierGroup.add(rightBoot);

        // 手臂 (红色袖子)
        const leftArm = new THREE.Mesh(new THREE.BoxGeometry(0.15, 0.6, 0.15), redCoat);
        leftArm.position.set(-0.38, 1.1, 0.1);
        leftArm.rotation.x = -0.5;
        leftArm.castShadow = true;
        soldierGroup.add(leftArm);

        const rightArm = new THREE.Mesh(new THREE.BoxGeometry(0.15, 0.6, 0.15), redCoat);
        rightArm.position.set(0.38, 1.1, 0.1);
        rightArm.rotation.x = -0.5;
        rightArm.castShadow = true;
        soldierGroup.add(rightArm);

        // 枪械 (木质枪身 + 金属枪管)
        const gunBody = new THREE.Mesh(new THREE.BoxGeometry(0.08, 0.1, 1.2), gunWood);
        gunBody.position.set(0, 1.15, 0.5);
        gunBody.rotation.x = -0.1;
        gunBody.castShadow = true;
        soldierGroup.add(gunBody);

        const gunBarrel = new THREE.Mesh(new THREE.CylinderGeometry(0.03, 0.03, 0.9, 8), gunMetal);
        gunBarrel.rotation.x = Math.PI / 2;
        gunBarrel.position.set(0, 1.18, 0.8);
        gunBarrel.castShadow = true;
        soldierGroup.add(gunBarrel);

        scene.add(soldierGroup);

        // 5. 第一人称视角的枪械 (前景)
        const fpgun = new THREE.Group();
        const fpBarrel = new THREE.Mesh(new THREE.CylinderGeometry(0.04, 0.04, 1.5, 8), gunWood);
        fpBarrel.rotation.x = Math.PI / 2;
        fpBarrel.position.set(0.2, -0.2, -0.8);
        fpgun.add(fpBarrel);
        
        const fpStock = new THREE.Mesh(new THREE.BoxGeometry(0.1, 0.1, 0.4), gunWood);
        fpStock.position.set(0.2, -0.2, 0.1);
        fpgun.add(fpStock);
        
        camera.add(fpgun);
        scene.add(camera);

        // 6. 动画循环
        function animate() {
            requestAnimationFrame(animate);
            
            // 轻微的待机动画
            const time = Date.now() * 0.002;
            soldierGroup.position.y = Math.sin(time) * 0.02;

            renderer.render(scene, camera);
        }

        // 7. 响应窗口大小变化
        window.addEventListener('resize', () => {
            camera.aspect = window.innerWidth / window.innerHeight;
            camera.updateProjectionMatrix();
            renderer.setSize(window.innerWidth, window.innerHeight);
        });

        animate();
    </script>
</body>
</html>

Game Source: 3D 红衣军士兵 - Three.js

Creator: TurboKoala83

Libraries: three

Complexity: moderate (175 lines, 6.9 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: 3d-three-js-turbokoala83" to link back to the original. Then publish at arcadelab.ai/publish.