<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>HTML5 Minecraft 复刻版</title>
    <style>
        * { margin: 0; padding: 0; box-sizing: border-box; }
        body { overflow: hidden; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; }
        #gameCanvas { width: 100vw; height: 100vh; display: block; }
        #hud { position: fixed; bottom: 20px; left: 50%; transform: translateX(-50%); display: flex; gap: 8px; z-index: 100; }
        .hotbar-slot { width: 48px; height: 48px; border: 2px solid #666; background: rgba(0,0,0,0.5); border-radius: 4px; }
        .hotbar-slot.active { border-color: #fff; }
        #crosshair { position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 20px; height: 20px; border: 1px solid #fff; z-index: 100; }
        #loading { position: fixed; top: 0; left: 0; width: 100vw; height: 100vh; background: #111; display: flex; flex-direction: column; justify-content: center; align-items: center; color: #fff; z-index: 999; }
        .progress-bar { width: 300px; height: 20px; border: 1px solid #666; margin-top: 20px; border-radius: 10px; overflow: hidden; }
        .progress { height: 100%; background: #4CAF50; width: 0%; transition: width 0.3s ease; }
    </style>
</head>
<body>
    <div id="loading">
        <h1>HTML5 Minecraft</h1>
        <p>加载中... 请稍候</p>
        <div class="progress-bar">
            <div class="progress" id="progress"></div>
        </div>
    </div>

    <canvas id="gameCanvas"></canvas>
    <div id="crosshair"></div>
    <div id="hud"></div>

    <!-- 引入核心库 -->
    <script src="https://cdn.babylonjs.com/babylon.js"></script>
    <script src="https://cdn.babylonjs.com/loaders/babylonjs.loaders.min.js"></script>
    <script src="https://cdn.babylonjs.com/ammo.js"></script>
    <script src="https://cdn.babylonjs.com/postProcesses/babylonjs.postProcess.min.js"></script>

    <script>
        // 全局变量
        let engine, scene, camera, physicsEngine;
        let world = { chunks: new Map(), loadedChunks: new Set() };
        let player, currentBlockType = 0;
        const BLOCK_TYPES = [
            { name: 'grass', color: new BABYLON.Color3(0.3, 0.7, 0.2), roughness: 0.8, metalness: 0.1 },
            { name: 'dirt', color: new BABYLON.Color3(0.6, 0.4, 0.2), roughness: 0.9, metalness: 0.05 },
            { name: 'stone', color: new BABYLON.Color3(0.5, 0.5, 0.5), roughness: 0.85, metalness: 0.1 },
            { name: 'wood', color: new BABYLON.Color3(0.8, 0.5, 0.2), roughness: 0.7, metalness: 0.05 },
            { name: 'leaves', color: new BABYLON.Color3(0.2, 0.6, 0.1), roughness: 0.9, metalness: 0.05, alpha: 0.8 }
        ];

        // 初始化游戏
        async function initGame() {
            updateProgress(10, "初始化引擎...");
            
            // 1. 创建引擎
            const canvas = document.getElementById('gameCanvas');
            engine = new BABYLON.Engine(canvas, true, { preserveDrawingBuffer: true, stencilBuffer: true });
            
            // 2. 创建场景
            scene = new BABYLON.Scene(engine);
            scene.clearColor = new BABYLON.Color3(0.6, 0.8, 1.0); // 天空色
            scene.gravity = new BABYLON.Vector3(0, -9.8, 0);
            scene.collisionsEnabled = true;

            // 3. 初始化物理引擎
            await initPhysics();
            updateProgress(30, "加载物理引擎...");

            // 4. 创建相机(第一人称)
            createCamera();
            
            // 5. 创建光源
            createLights();
            updateProgress(40, "设置光影效果...");

            // 6. 初始化世界
            await initWorld();
            updateProgress(60, "生成世界...");

            // 7. 创建玩家
            createPlayer();
            updateProgress(70, "创建玩家...");

            // 8. 设置UI
            setupUI();
            updateProgress(80, "初始化界面...");

            // 9. 注册事件监听
            registerEvents();
            updateProgress(90, "配置控制...");

            // 10. 初始化离线存储
            await initOfflineStorage();
            updateProgress(100, "准备就绪!");

            // 隐藏加载界面
            setTimeout(() => document.getElementById('loading').style.display = 'none', 500);

            // 渲染循环
            engine.runRenderLoop(() => {
                scene.render();
                updatePlayerPosition();
                loadNearbyChunks();
            });

            // 窗口大小调整
            window.addEventListener('resize', () => engine.resize());
        }

        // 初始化物理引擎
        async function initPhysics() {
            await Ammo().then((AmmoLib) => {
                Ammo = AmmoLib;
                physicsEngine = new BABYLON.AmmoJSPlugin(true, Ammo);
                scene.enablePhysics(scene.gravity, physicsEngine);
            });
        }

        // 创建相机
        function createCamera() {
            camera = new BABYLON.FreeCamera("camera", new BABYLON.Vector3(0, 64, 0), scene);
            camera.attachControl(canvas, true);
            camera.inputs.attached.mouse.angularSensibility = 8000;
            camera.speed = 0.2;
            camera.angularSpeed = 0.01;
            camera.minZ = 0.1;
            camera.maxZ = 200;

            // 限制相机俯仰角度
            camera.lowerRadiusLimit = null;
            camera.upperRadiusLimit = null;
            camera.lowerHeightLimit = 1.5;
            camera.upperHeightLimit = 256;

            // 启用碰撞检测
            camera.checkCollisions = true;
            camera.ellipsoid = new BABYLON.Vector3(0.5, 1.5, 0.5);
        }

        // 创建光源和光影效果
        function createLights() {
            // 环境光
            const ambientLight = new BABYLON.HemisphericLight("ambient", new BABYLON.Vector3(0, 1, 0), scene);
            ambientLight.intensity = 0.6;

            // 方向光(太阳)
            const directionalLight = new BABYLON.DirectionalLight("sun", new BABYLON.Vector3(-1, -2, -1), scene);
            directionalLight.intensity = 0.8;
            directionalLight.position = new BABYLON.Vector3(100, 200, 100);

            // 启用阴影
            directionalLight.shadowEnabled = true;
            directionalLight.shadow.mapSize.width = 2048;
            directionalLight.shadow.mapSize.height = 2048;
            directionalLight.shadow.camera.orthoLeft = -100;
            directionalLight.shadow.camera.orthoRight = 100;
            directionalLight.shadow.camera.orthoTop = 100;
            directionalLight.shadow.camera.orthoBottom = -100;

            // PBR环境贴图
            const hdrTexture = BABYLON.CubeTexture.CreateFromPrefilteredData("https://assets.babylonjs.com/environments/environmentSpecular.env", scene);
            scene.environmentTexture = hdrTexture;
            scene.environmentIntensity = 0.5;

            // 后期处理(辉光效果)
            const bloom = new BABYLON.UnrealBloomPass(new BABYLON.Vector2(engine.getRenderWidth(), engine.getRenderHeight()), 1.2, 0.5, 0.85);
            const composer = new BABYLON.EffectComposer(engine);
            composer.addPass(new BABYLON.RenderPass(scene, camera));
            composer.addPass(bloom);
            
            engine.runRenderLoop(() => {
                composer.render();
            });
        }

        // 初始化世界(区块生成)
        function initWorld() {
            // 简单的Perlin噪声实现(简化版)
            const noise = {
                perm: new Uint8Array([151,160,137,91,90,15,131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,23,190,6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33,88,237,149,56,87,174,20,125,136,171,168,68,175,74,165,71,134,139,48,27,166,77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41,55,46,245,40,244,102,143,54,65,25,63,161,1,216,80,73,209,76,132,187,208,89,18,169,200,196,135,130,116,188,159,86,164,100,109,198,173,186,3,64,52,217,226,250,124,123,5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42,223,183,170,213,119,248,152,2,44,154,163,70,221,153,101,155,167,43,172,9,129,22,39,253,19,98,108,110,79,113,224,232,178,185,112,104,218,246,97,228,251,34,242,193,238,210,144,12,191,179,162,241,81,51,145,235,249,14,239,107,49,192,214,31,181,199,106,157,184,84,204,176,115,121,50,44,109,138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180]),
                fade(t) { return t*t*t*(t*(t*6-15)+10); },
                lerp(a,b,t) { return a + t*(b-a); },
                grad(hash, x,y,z) {
                    const h = hash & 15;
                    const u = h<8 ? x : y;
                    const v = h<4 ? y : h===12||h===14 ? x : z;
                    return ((h&1) === 0 ? u : -u) + ((h&2) === 0 ? v : -v);
                },
                noise3d(x,y,z) {
                    const p = new Uint8Array(512);
                    for(let i=0;i<512;i++) p[i] = this.perm[i&255];
                    
                    const X = Math.floor(x) & 255;
                    const Y = Math.floor(y) & 255;
                    const Z = Math.floor(z) & 255;
                    
                    x -= Math.floor(x); y -= Math.floor(y); z -= Math.floor(z);
                    const u = this.fade(x); const v = this.fade(y); const w = this.fade(z);
                    
                    const A = p[X]+Y; const AA = p[A]+Z; const AB = p[A+1]+Z;
                    const B = p[X+1]+Y; const BA = p[B]+Z; const BB = p[B+1]+Z;
                    
                    return this.lerp(w,
                        this.lerp(v, this.lerp(u, this.grad(p[AA],x,y,z), this.grad(p[BA],x-1,y,z)),
                                   this.lerp(u, this.grad(p[AB],x,y-1,z), this.grad(p[BB],x-1,y-1,z))),
                        this.lerp(v, this.lerp(u, this.grad(p[AA+1],x,y,z-1), this.grad(p[BA+1],x-1,y,z