<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>3D FPS 射线落地 绝不穿模 (已修复)</title>
    <style>
        * {margin:0;padding:0;box-sizing:border-box;}
        body {overflow:hidden;background:#000;cursor:none;font-family: Arial, sans-serif;}
        canvas {display:block;}

        .crosshair {
            position: fixed;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            color: #fff;
            font-size: 24px;
            pointer-events: none;
            z-index: 100;
            text-shadow: 0 0 2px #000;
        }
        .aim-scope {
            position: fixed;
            inset: 0;
            background: radial-gradient(transparent 40%, rgba(0,0,0,0.75) 75%);
            opacity: 0;
            pointer-events: none;
            transition: opacity 0.2s;
            z-index: 98;
        }
        .gun {
            position: fixed;
            bottom: 0;
            right: 50%;
            transform: translateX(50%);
            width: 300px;
            height: 160px;
            background: linear-gradient(135deg, #222 30%, #444 100%);
            border-radius: 8px 8px 0 0;
            pointer-events: none;
            z-index: 99;
            box-shadow: 0 -5px 15px rgba(0,0,0,0.5);
        }
        
        /* UI界面 */
        .ui-container {
            position: fixed;
            top: 20px;
            left: 20px;
            z-index: 101;
            background: rgba(0, 0, 0, 0.6);
            padding: 15px;
            border-radius: 8px;
            color: white;
            font-size: 16px;
            border: 1px solid rgba(255, 255, 255, 0.2);
        }
        
        .health-bar {
            width: 200px;
            height: 20px;
            background: #333;
            border-radius: 10px;
            overflow: hidden;
            margin-top: 5px;
            border: 1px solid #555;
        }
        
        .health-fill {
            height: 100%;
            background: linear-gradient(90deg, #ff3300, #ff9900);
            width: 100%;
            transition: width 0.3s ease;
        }
        
        .ammo-display {
            margin-top: 10px;
            font-size: 18px;
        }
        
        .kill-counter {
            margin-top: 10px;
            font-size: 18px;
        }
        
        .damage-number {
            position: fixed;
            color: #ff5555;
            font-size: 20px;
            font-weight: bold;
            pointer-events: none;
            z-index: 102;
            animation: floatUp 1s forwards;
        }
        
        @keyframes floatUp {
            0% { transform: translateY(0); opacity: 1; }
            100% { transform: translateY(-50px); opacity: 0; }
        }
        
        .game-title {
            position: fixed;
            top: 20px;
            left: 50%;
            transform: translateX(-50%);
            color: white;
            font-size: 24px;
            z-index: 101;
            text-shadow: 0 0 10px rgba(255, 255, 255, 0.8);
            background: rgba(0, 0, 0, 0.5);
            padding: 10px 20px;
            border-radius: 5px;
        }
    </style>
</head>
<body>
    <div class="game-title">3D FPS 游戏</div>
    <div class="crosshair">+</div>
    <div class="aim-scope" id="aimScope"></div>
    <div class="gun"></div>
    
    <div class="ui-container">
        <div>生命值</div>
        <div class="health-bar">
            <div class="health-fill" id="healthFill"></div>
        </div>
        <div class="ammo-display">弹药: ∞</div>
        <div class="kill-counter">击杀: <span id="killCount">0</span></div>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/three@0.158.0/build/three.min.js"></script>
    <script>
        let scene, camera, renderer;
        let player = { 
            speed: 0.15,
            yVel: 0,
            gravity: -0.015,
            jumpPower: 0.32,
            isGrounded: true,
            groundY: 0,
            health: 100
        };
        let keys = {};
        let enemies = [];
        let bullets = [];
        let colliders = [];
        let pitch = 0, yaw = 0;
        let killCount = 0;

        let isAiming = false;
        const sensNormal = 0.002;
        const sensAim = 0.0008;
        let mouseSens = sensNormal;
        const aimScope = document.getElementById('aimScope');
        const healthFill = document.getElementById('healthFill');
        const killCountDisplay = document.getElementById('killCount');

        // 射线落地检测
        let raycaster = new THREE.Raycaster();
        const downDir = new THREE.Vector3(0, -1, 0);

        // 粒子系统
        let particleSystem;
        let particles;

        // 创建简单的纹理图案
        function createTexture(color, patternType = 'none') {
            const canvas = document.createElement('canvas');
            canvas.width = 32;
            canvas.height = 32;
            const ctx = canvas.getContext('2d');
            
            // 填充基础颜色
            ctx.fillStyle = '#' + color.getHexString();
            ctx.fillRect(0, 0, 32, 32);
            
            // 根据类型添加简单图案
            switch(patternType) {
                case 'grass':
                    ctx.fillStyle = '#3a5f3a';
                    for(let i = 0; i < 64; i++) {
                        const x = Math.random() * 32;
                        const y = Math.random() * 32;
                        ctx.fillRect(x, y, 2, 2);
                    }
                    break;
                case 'stone':
                    ctx.fillStyle = '#666666';
                    for(let i = 0; i < 32; i++) {
                        const x = Math.floor(Math.random() * 32);
                        const y = Math.floor(Math.random() * 32);
                        ctx.fillRect(x, y, 3, 3);
                    }
                    break;
                case 'dirt':
                    ctx.fillStyle = '#5d4037';
                    for(let i = 0; i < 40; i++) {
                        const x = Math.random() * 32;
                        const y = Math.random() * 32;
                        ctx.fillRect(x, y, 2, 2);
                    }
                    break;
                case 'skin':
                    // 简单的皮肤纹理
                    ctx.fillStyle = '#ffcc99';
                    ctx.fillRect(0, 0, 16, 16);
                    ctx.fillRect(16, 0, 16, 16);
                    ctx.fillRect(0, 16, 16, 16);
                    ctx.fillRect(16, 16, 16, 16);
                    
                    // 添加一些细节
                    ctx.fillStyle = '#ffaa66';
                    for(let i = 0; i < 10; i++) {
                        const x = Math.random() * 32;
                        const y = Math.random() * 32;
                        ctx.fillRect(x, y, 1, 1);
                    }
                    break;
                case 'cloth':
                    // 简单的布料纹理
                    ctx.strokeStyle = '#ffffff';
                    ctx.lineWidth = 1;
                    for(let i = 0; i < 32; i += 4) {
                        ctx.beginPath();
                        ctx.moveTo(0, i);
                        ctx.lineTo(32, i);
                        ctx.stroke();
                    }
                    for(let i = 0; i < 32; i += 4) {
                        ctx.beginPath();
                        ctx.moveTo(i, 0);
                        ctx.lineTo(i, 32);
                        ctx.stroke();
                    }
                    break;
            }
            
            const texture = new THREE.CanvasTexture(canvas);
            texture.magFilter = THREE.NearestFilter;
            texture.minFilter = THREE.NearestFilter;
            return texture;
        }

        // 创建粒子系统
        function createParticleSystem() {
            const particleCount = 1000;
            particles = new Float32Array(particleCount * 3);
            
            for(let i = 0; i < particleCount * 3; i += 3) {
                particles[i] = (Math.random() - 0.5) * 2;     // x
                particles[i+1] = (Math.random() - 0.5) * 2;   // y
                particles[i+2] = (Math.random() - 0.5) * 2;   // z
            }
            
            const geometry = new THREE.BufferGeometry();
            geometry.setAttribute('position', new THREE.BufferAttribute(particles, 3));
            
            const material = new THREE.PointsMaterial({
                color: 0x87ceeb,
                size: 0.1,
                transparent: true,
                opacity: 0.6
            });
            
            particleSystem = new THREE.Points(geometry, material);
            particleSystem.position.y = -10;
            scene.add(particleSystem);
        }

        function init() {
            scene = new THREE.Scene();
            scene.background = new THREE.Color(0x87ceeb);
            scene.fog = new THREE.Fog(0x87ceeb, 30, 120);

            camera = new THREE.PerspectiveCamera(75, innerWidth/innerHeight, 0.1, 1000);
            camera.position.set(0, 2, 0);

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

            // 更好的光照
            const ambientLight = new THREE.AmbientLight(0x404040, 0.6);
            const directionalLight = new THREE.DirectionalLight(0xffffff, 1.2);
            directionalLight.position.set(50, 80, 30);
            directionalLight.castShadow = true;
            directionalLight.shadow.mapSize.width = 2048;
            directionalLight.shadow.mapSize.height = 2048;
            directionalLight.shadow.camera.near = 0.5;
            directionalLight.shadow.camera.far = 200;
            directionalLight.shadow.camera.left = -50;
            directionalLight.shadow.camera.right = 50;
            directionalLight.shadow.camera.top = 50;
            directionalLight.shadow.camera.bottom = -50;
            
            scene.add(ambientLight, directionalLight);

            createTerrain();
            createParticleSystem();
            spawnEnemies(6);
            bindEvents();
            animate();
        }

        function createTerrain() {
            // 地面纹理
            const groundTexture = createTexture(new THREE.Color(0x4a7c4a), 'grass');
            const groundMat = new THREE.MeshLambertMaterial({map: groundTexture});
            const ground = new THREE.Mesh(new THREE.PlaneGeometry(150,150), groundMat);
            ground.rotation.x = -Math.PI/2;
            ground.receiveShadow = true;
            scene.add(ground);
            colliders.push(ground);

            // 山丘纹理
            for(let i=0;i<25;i++){
                let w = 6 + Math.random()*12;
                let h = 1.5 + Math.random()*3;
                let d = 6 + Math.random()*12;
                
                const dirtTexture = createTexture(new THREE.Color(0x5a7c4a), 'dirt');
                let hill = new THREE.Mesh(
                    new THREE.BoxGeometry(w,h,d),
                    new THREE.MeshLambertMaterial({map: dirtTexture})
                );
                hill.position.set((Math.random()-0.5)*90, h/2, (Math.random()-0.5)*90);
                hill.castShadow = hill.receiveShadow = true;
                scene.add(hill);
                colliders.push(hill);
            }

            // 围墙纹理
            for(let i=0;i<18;i++){
                const stoneTexture = createTexture(new THREE.Color(0x777777), 'stone');
                let wall = new THREE.Mesh(
                    new THREE.BoxGeometry(4,3.5,1.2),
                    new THREE.MeshLambertMaterial({map: stoneTexture})
                );
                wall.position.set((Math.random()-0.5)*85, 1.75, (Math.random()-0.5)*85);
                wall.castShadow = true;
                scene.add(wall);
                colliders.push(wall);
            }
            
            // 添加一些装饰性树木
            for(let i = 0; i < 15; i++) {
                // 树干
                const trunk = new THREE.Mesh(
                    new THREE.CylinderGeometry(0.2, 0.3, 2, 8),
                    new THREE.MeshLambertMaterial({color: 0x8B4513})
                );
                trunk.position.set((Math.random()-0.5)*80, 1, (Math.random()-0.5)*80);
                trunk.castShadow = true;
                scene.add(trunk);
                
                // 树冠
                const leaves = new THREE.Mesh(
                    new THREE.SphereGeometry(1.5, 8, 8),
                    new THREE.MeshLambertMaterial({color: 0x2E8B57})
                );
                leaves.position.set(trunk.position.x, 2.5, trunk.position.z);
                leaves.castShadow = true;
                scene.add(leaves);
            }
        }

        // 创建我的世界风格的方块人模型(带纹理)
        function createMinecraftCharacter(color = 0xff3333) {
            const group = new THREE.Group();
            
            // 皮肤纹理
            const skinTexture = createTexture(new THREE.Color(color), 'skin');
            const detailTexture = createTexture(new THREE.Color(0x222222), 'cloth');
            
            // 身体 (2x3x1)
            const body = new THREE.Mesh(
                new THREE.BoxGeometry(0.5, 1.5, 0.5),
                new THREE.MeshLambertMaterial({map: skinTexture})
            );
            body.position.y = 1.0; // 身体位于腰部
            body.castShadow = true;
            group.add(body);
            
            // 头部 (1x1x1)
            const head = new THREE.Mesh(
                new THREE.BoxGeometry(0.75, 0.75, 0.75),
                new THREE.MeshLambertMaterial({map: skinTexture})
            );
            head.position.y = 2.0; // 头部位于身体上方
            head.castShadow = true;
            group.add(head);
            
            // 帽子细节 (可选)
            const hat = new THREE.Mesh(
                new THREE.BoxGeometry(0.78, 0.78, 0.78),
                new THREE.MeshLambertMaterial({map: detailTexture})
            );
            hat.position.y = 2.0;
            hat.castShadow = true;
            group.add(hat);
            
            // 左臂 (0.5x1.5x0.5)
            const leftArm = new THREE.Mesh(
                new THREE.BoxGeometry(0.25, 0.75, 0.25),
                new THREE.MeshLambertMaterial({map: skinTexture})
            );
            leftArm.position.set(0.5, 1.0, 0);
            leftArm.castShadow = true;
            group.add(leftArm);
            
            // 右臂 (0.5x1.5x0.5)
            const rightArm = new THREE.Mesh(
                new THREE.BoxGeometry(0.25, 0.75, 0.25),
                new THREE.MeshLambertMaterial({map: skinTexture})
            );
            rightArm.position.set(-0.5, 1.0, 0);
            rightArm.castShadow = true;
            group.add(rightArm);
            
            // 左腿 (0.5x1.5x0.5)
            const leftLeg = new THREE.Mesh(
                new THREE.BoxGeometry(0.25, 0.75, 0.25),
                new THREE.MeshLambertMaterial({map: skinTexture})
            );
            leftLeg.position.set(0.2, 0.25, 0);
            leftLeg.castShadow = true;
            group.add(leftLeg);
            
            // 右腿 (0.5x1.5x0.5)
            const rightLeg = new THREE.Mesh(
                new THREE.BoxGeometry(0.25, 0.75, 0.25),
                new THREE.MeshLambertMaterial({map: skinTexture})
            );
            rightLeg.position.set(-0.2, 0.25, 0);
            rightLeg.castShadow = true;
            group.add(rightLeg);
            
            return group;
        }

        function spawnEnemies(count) {
            // 随机颜色列表
            const colors = [
                0xff5555, // 红色
                0x5555ff, // 蓝色
                0x55ff55, // 绿色
                0xffff55, // 黄色
                0xff55ff, // 紫色
                0x55ffff, // 青色
                0xffaa00, // 橙色
                0xaa00ff  // 紫罗兰
            ];
            
            for(let i=0;i<count;i++){
                // 随机选择一个颜色
                const randomColor = colors[Math.floor(Math.random() * colors.length)];
                
                // 使用新的方块人模型
                let enemyGroup = createMinecraftCharacter(randomColor);
                
                // 设置位置(避免生成在障碍物上)
                let validPosition = false;
                let attempts = 0;
                while(!validPosition && attempts < 50) {
                    enemyGroup.position.set((Math.random()-0.5)*70, 0, (Math.random()-0.5)*70);
                    
                    // 检查是否与其他物体重叠
                    validPosition = true;
                    for(const obj of colliders) {
                        if(obj.userData.isEnemyCollider) continue; // 跳过其他敌人碰撞框
                        
                        const box = new THREE.Box3().setFromObject(obj);
                        const sph = new THREE.Sphere(enemyGroup.position, 0.8);
                        if(box.intersectsSphere(sph)) {
                            validPosition = false;
                            break;
                        }
                    }
                    attempts++;
                }
                
                // 添加生命值属性
                enemyGroup.hp = 100;
                
                // 添加移动相关属性
                enemyGroup.moveSpeed = 0.02 + Math.random() * 0.03; // 随机移动速度
                enemyGroup.targetPosition = new THREE.Vector3(
                    (Math.random()-0.5)*70, 
                    0, 
                    (Math.random()-0.5)*70
                );
                
                // 添加到场景和敌人数组
                enemies.push(enemyGroup);
                scene.add(enemyGroup);
                
                // 为碰撞检测添加包围盒(用于性能优化)
                const boundingBox = new THREE.Mesh(
                    new THREE.BoxGeometry(1.0, 2.5, 1.0), // 包围盒略大于实际模型
                    new THREE.MeshBasicMaterial({visible: false}) // 不可见
                );
                boundingBox.position.copy(enemyGroup.position);
                boundingBox.position.y += 1.25; // 垂直中心
                boundingBox.userData = { isEnemyCollider: true, parent: enemyGroup }; // 标记为敌人碰撞框并关联敌人
                scene.add(boundingBox);
                colliders.push(boundingBox);
            }
        }

        // 检查敌人移动碰撞
        function checkEnemyCollision(position, excludeEnemy = null) {
            const enemyRadius = 0.8;
            const testPos = new THREE.Vector3(position.x, position.y, position.z);
            
            // 检查与其他敌人碰撞
            for(const enemy of enemies) {
                if(enemy === excludeEnemy) continue;
                
                const distance = testPos.distanceTo(enemy.position);
                if(distance < enemyRadius * 2) {
                    return true;
                }
            }
            
            // 检查与地形碰撞
            for(const obj of colliders) {
                // 跳过敌人自己的碰撞框
                if(obj.userData.parent === excludeEnemy) continue;
                
                const box = new THREE.Box3().setFromObject(obj);
                const sph = new THREE.Sphere(testPos, enemyRadius);
                if(box.intersectsSphere(sph)) {
                    return true;
                }
            }
            
            return false;
        }

        // 更新敌人移动
        function updateEnemies() {
            for(const enemy of enemies) {
                // 计算到目标位置的方向
                const direction = new THREE.Vector3();
                direction.subVectors(enemy.targetPosition, enemy.position).normalize();
                
                // 计算下一个位置
                const nextPosition = enemy.position.clone().add(direction.multiplyScalar(enemy.moveSpeed));
                
                // 检查碰撞
                if(!checkEnemyCollision(nextPosition, enemy)) {
                    // 没有碰撞,移动敌人
                    enemy.position.copy(nextPosition);
                    
                    // 更新碰撞框位置
                    const collider = colliders.find(c => c.userData.parent === enemy);
                    if(collider) {
                        collider.position.copy(enemy.position);
                        collider.position.y = enemy.position.y + 1.25;
                    }
                } else {
                    // 发生碰撞,设置新目标
                    enemy.targetPosition.set(
                        (Math.random()-0.5)*70,
                        0,
                        (Math.random()-0.5)*70
                    );
                }
                
                // 检查是否到达目标位置,如果是则设置新目标
                if(enemy.position.distanceTo(enemy.targetPosition) < 2) {
                    enemy.targetPosition.set(
                        (Math.random()-0.5)*70,
                        0,
                        (Math.random()-0.5)*70
                    );
                }
            }
        }

        // 向下射线检测地面
        function rayGroundCheck() {
            raycaster.setFromCamera(new THREE.Vector2(0, 0), camera);
            const intersects = raycaster.intersectObjects(colliders, false);
            if(intersects.length > 0) {
                // 排除敌人碰撞框
                const groundIntersects = intersects.filter(intersect => 
                    !intersect.object.userData.isEnemyCollider
                );
                if(groundIntersects.length > 0) {
                    return groundIntersects[0].point.y;
                }
            }
            return -999;
        }

        // 水平碰撞
        function checkMoveCollision(x,z){
            const playerRad = 0.8;
            const testPos = new THREE.Vector3(x, camera.position.y, z);
            for(let obj of colliders){
                // 排除敌人碰撞框
                if(obj.userData.isEnemyCollider) continue;
                
                const box = new THREE.Box3().setFromObject(obj);
                const sph = new THREE.Sphere(testPos, playerRad);
                if(box.intersectsSphere(sph)) return true;
            }
            return false;
        }

        function bindEvents() {
            document.addEventListener('keydown', e=>{
                keys[e.code] = true;
                if(e.code==='Space' && player.isGrounded){
                    player.yVel = player.jumpPower;
                    player.isGrounded = false;
                }
            });
            document.addEventListener('keyup', e=>keys[e.code]=false);

            document.addEventListener('mousemove', e=>{
                yaw -= e.movementX * mouseSens;
                pitch -= e.movementY * mouseSens;
                pitch = Math.max(-Math.PI/3.5, Math.min(Math.PI/3.5, pitch));
                camera.rotation.order = 'YXZ';
                camera.rotation.y = yaw;
                camera.rotation.x = pitch;
            });

            document.addEventListener('mousedown', e=>{
                if(e.button === 0) {
                    shoot();
                }
                if(e.button === 2){
                    e.preventDefault();
                    isAiming = true;
                    mouseSens = sensAim;
                    aimScope.style.opacity = 1;
                    camera.fov = 55;
                    camera.updateProjectionMatrix();
                }
            });

            document.addEventListener('mouseup', e=>{
                if(e.button === 2){
                    isAiming = false;
                    mouseSens = sensNormal;
                    aimScope.style.opacity = 0;
                    camera.fov = 75;
                    camera.updateProjectionMatrix();
                }
            });

            document.addEventListener('contextmenu', e=>e.preventDefault());
            document.body.addEventListener('click', ()=>document.body.requestPointerLock());
            window.onresize = ()=>{
                camera.aspect = innerWidth/innerHeight;
                camera.updateProjectionMatrix();
                renderer.setSize(innerWidth, innerHeight);
            };
        }

        function shoot() {
            let bullet = new THREE.Mesh(
                new THREE.SphereGeometry(0.12,6,6),
                new THREE.MeshBasicMaterial({color:0xffff00})
            );
            bullet.position.copy(camera.position);
            let dir = new THREE.Vector3();
            camera.getWorldDirection(dir);
            bullet.userData.dir = dir;
            bullet.userData.spd = 1.5;
            bullets.push(bullet);
            scene.add(bullet);
        }

        function movePlayer() {
            let dir = new THREE.Vector3();
            camera.getWorldDirection(dir);
            dir.y = 0;
            dir.normalize();

            let right = new THREE.Vector3().crossVectors(dir, new THREE.Vector3(0,1,0)).normalize();
            let moveVec = new THREE.Vector3(0,0,0);

            if(keys.KeyW) moveVec.add(dir.clone().multiplyScalar(player.speed));
            if(keys.KeyS) moveVec.add(dir.clone().multiplyScalar(-player.speed));
            if(keys.KeyA) moveVec.add(right.clone().multiplyScalar(-player.speed));
            if(keys.KeyD) moveVec.add(right.clone().multiplyScalar(player.speed));

            // 水平移动碰撞阻挡
            let nextX = camera.position.x + moveVec.x;
            let nextZ = camera.position.z + moveVec.z;
            if(!checkMoveCollision(nextX, nextZ)){
                camera.position.x = nextX;
                camera.position.z = nextZ;
            }

            // 重力应用
            if (!player.isGrounded || player.yVel !== 0) {
                player.yVel += player.gravity;
            }
            
            // 更新位置
            camera.position.y += player.yVel;

            // 射线检测脚下地面高度
            const groundY = rayGroundCheck();
            const standHeight = groundY + 2.05;

            // 检测是否接近地面且正在下降
            const isFalling = player.yVel < 0;
            const isCloseToGround = camera.position.y <= standHeight;
            
            if(isCloseToGround && isFalling) {
                // 确保角色恰好站在地面上
                camera.position.y = standHeight;
                
                // 设置为接地状态并停止垂直速度
                player.yVel = 0;
                player.isGrounded = true;
                player.groundY = groundY;
            } else if (!isCloseToGround) {
                // 如果离开地面,标记为非接地状态
                player.isGrounded = false;
            }

            camera.position.x = THREE.MathUtils.clamp(camera.position.x, -70,70);
            camera.position.z = THREE.MathUtils.clamp(camera.position.z, -70,70);
        }

        function updateBullets(){
            for(let i=bullets.length-1;i>=0;i--){
                let b = bullets[i];
                b.position.addScaledVector(b.userData.dir, b.userData.spd);

                for(let j=enemies.length-1;j>=0;j--){
                    let e = enemies[j];
                    // 检查子弹是否击中敌人(使用碰撞框位置)
                    const collider = colliders.find(c => c.userData.parent === e);
                    if(collider && b.position.distanceTo(collider.position) < 1.0){
                        e.hp -= 50;
                        console.log(`击中敌人! 剩余血量: ${e.hp}`); // 调试信息
                        
                        // 创建伤害数字效果
                        createDamageNumber(b.position, 50);
                        
                        scene.remove(b); 
                        bullets.splice(i,1);
                        
                        // 检查敌人是否死亡
                        if(e.hp <= 0){
                            console.log("敌人被击杀!"); // 调试信息
                            
                            // 移除敌人及其碰撞框
                            scene.remove(e);
                            enemies.splice(j,1);
                            
                            // 找到对应的碰撞框并移除
                            for(let k=colliders.length-1; k>=0; k--) {
                                if(colliders[k].userData.parent === e) {
                                    scene.remove(colliders[k]);
                                    colliders.splice(k,1);
                                    break;
                                }
                            }
                            
                            // 更新击杀计数
                            killCount++;
                            killCountDisplay.textContent = killCount;
                            
                            // 生成新敌人
                            spawnEnemies(1);
                        }
                        break;
                    }
                }
            }
        }
        
        // 创建伤害数字效果
        function createDamageNumber(position, damage) {
            const damageElement = document.createElement('div');
            damageElement.className = 'damage-number';
            damageElement.textContent = '-' + damage;
            damageElement.style.left = (innerWidth/2 + (Math.random() - 0.5) * 100) + 'px';
            damageElement.style.top = (innerHeight/2 + (Math.random() - 0.5) * 100) + 'px';
            document.body.appendChild(damageElement);
            
            // 移除元素
            setTimeout(() => {
                document.body.removeChild(damageElement);
            }, 1000);
        }

        function animate(){
            requestAnimationFrame(animate);
            
            // 更新粒子系统
            if(particleSystem) {
                particleSystem.rotation.y += 0.001;
                particleSystem.position.y += 0.01;
                if(particleSystem.position.y > 10) {
                    particleSystem.position.y = -10;
                }
            }
            
            movePlayer();
            updateEnemies(); // 更新敌人移动
            updateBullets();
            
            // 更新UI
            healthFill.style.width = player.health + '%';
            
            renderer.render(scene, camera);
        }

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