{"id":1436,"date":"2025-11-11T04:27:34","date_gmt":"2025-11-10T20:27:34","guid":{"rendered":"https:\/\/www.admiralspee.site\/?page_id=1436"},"modified":"2026-01-15T00:33:30","modified_gmt":"2026-01-14T16:33:30","slug":"no_mans_sekai","status":"publish","type":"page","link":"https:\/\/www.admiralspee.site\/en\/no_mans_sekai","title":{"rendered":"WiFi\u6df1\u5904\u7684\u65e0\u4eba\u4e16\u754c"},"content":{"rendered":"<!-- Live2D \u770b\u677f\u5a18\u5bb9\u5668 -->\n<div id=\"live2d-wrapper\">\n  <div id=\"live2d-bg\"><\/div>\n  <canvas id=\"live2d-canvas\"><\/canvas>\n  <div id=\"live2d-dialog\"><\/div>\n<\/div>\n\n<!-- 1. PixiJS -->\n<script src=\"https:\/\/unpkg.com\/pixi.js@6\/dist\/browser\/pixi.min.js\"><\/script>\n\n<!-- 2. Live2D Cubism Core -->\n<script src=\"https:\/\/cubism.live2d.com\/sdk-web\/cubismcore\/live2dcubismcore.min.js\"><\/script>\n\n<!-- 3. pixi-live2d-display\uff08Cubism4 \u5c01\u88c5\uff09 -->\n<script src=\"https:\/\/unpkg.com\/pixi-live2d-display@0.4.0\/dist\/cubism4.min.js\"><\/script>\n\n<script>\n  (function () {\n    const wrapper   = document.getElementById('live2d-wrapper');\n    const canvas    = document.getElementById('live2d-canvas');\n    const dialogBox = document.getElementById('live2d-dialog');\n\n    \/\/ ======= \u97f3\u4e50\u914d\u7f6e\uff1a\u8fd9\u91cc\u6362\u6210\u4f60\u7684\u97f3\u4e50 URL =======\n    const MUSIC_URL = \"https:\/\/www.admiralspee.site\/wp-content\/uploads\/v2_clb01_21miku_t03\/\u30cf\u30ed\u30fc\u30bb\u30ab\u30a4.mp3\";\n    const bgm = new Audio(MUSIC_URL);\n    bgm.preload = \"auto\";\n\n    const bgLayer = document.getElementById('live2d-bg');\n\n    \/\/ \u97f3\u4e50\u81ea\u7136\u64ad\u5b8c\u65f6\uff0c\u8ba9\u80cc\u666f\u6e10\u9690\n    bgm.addEventListener('ended', () => {\n      if (bgLayer) {\n        bgLayer.classList.add('fade-out');\n      }\n    });\n\n    \/\/ \u2705 \u5173\u952e\u4fee\u6539\uff1a\u9650\u5236\u5206\u8fa8\u7387\uff0c\u907f\u514d\u624b\u673a\u4e0a\u8d85\u5927\u753b\u5e03\u5bfc\u81f4 WebGL \u5d29\u6e83\n    const RESOLUTION = Math.min(window.devicePixelRatio || 1, 2);\n\n    const app = new PIXI.Application({\n      view: canvas,\n      autoStart: true,\n      transparent: true,\n      autoDensity: true,           \/\/ \u4ecd\u7136\u81ea\u9002\u5e94 DPR\n      resolution: RESOLUTION,      \/\/ \u4f46\u6700\u591a\u653e\u5927\u5230 2 \u500d\n      antialias: true,\n    });\n\n    if (!PIXI.live2d || !PIXI.live2d.Live2DModel) {\n      console.error('pixi-live2d-display \u672a\u6b63\u786e\u52a0\u8f7d');\n      return;\n    }\n    const Live2DModel    = PIXI.live2d.Live2DModel;\n    const MotionPriority = PIXI.live2d.MotionPriority;\n\n    const MODEL_URL = \"\/wp-content\/uploads\/v2_clb01_21miku_t03\/v2_clb01_21miku_t03.model3.json\";\n\n    Live2DModel.from(MODEL_URL, { autoInteract: false }).then(model => {\n      app.stage.addChild(model);\n\n      \/\/ \u7981\u7528 idle \u81ea\u52a8\u5f85\u673a\u52a8\u4f5c\n      if (model.internalModel.motionManager && model.internalModel.motionManager.groups) {\n        model.internalModel.motionManager.groups.idle = '';\n      }\n\n      \n\n      function layoutModel() {\n        \/\/ \u7528\u5b9e\u9645 DOM \u5c3a\u5bf8\uff0c\u800c\u4e0d\u662f renderer \u5185\u90e8\u5c3a\u5bf8\n        const rect = wrapper.getBoundingClientRect();\n        const w = rect.width;\n        const h = rect.height;\n\n        const isMobile = window.innerWidth <= 768;   \/\/ \u4f60\u539f\u6765\u7684\u5224\u65ad\uff0c\u53ef\u4ee5\u7ee7\u7eed\u7528\n\n        if (isMobile) {\n          \/\/ \u2014\u2014 \u624b\u673a\uff1a\u4eba\u7269\u653e\u5c4f\u5e55\u6b63\u4e2d\uff0c\u7a0d\u5fae\u504f\u4e0b\u4e00\u70b9 \u2014\u2014 \n          model.anchor.set(0.5, 0.5);    \/\/ \u4ee5\u4eba\u7269\u4e2d\u5fc3\u4e3a\u951a\u70b9\n          model.scale.set(0.25);         \/\/ \u53ef\u4ee5\u81ea\u5df1\u5fae\u8c03\u5927\u5c0f\n\n          model.x = w * 0.5;\n          model.y = h * 0.5;            \/\/ 0.5 \u6b63\u4e2d\uff0c0.55 \u7a0d\u5fae\u504f\u4e0b\n        } else {\n          \/\/ \u2014\u2014 PC\uff1a\u7ad9\u5728\u5e95\u90e8\u4e2d\u592e\uff08\u6309\u4f60\u4e4b\u524d\u7684\u611f\u89c9\u6765\uff09\u2014\u2014\n          model.anchor.set(0.5, 0.35);    \/\/ \u811a\u9644\u8fd1\u4e3a\u951a\u70b9\n          model.scale.set(0.3);\n\n          model.x = w * 0.5;\n          model.y = h * 0.5;                   \/\/ \u8d34\u5e95\n        }\n      }\n\n      function resizeApp() {\n        const rect = wrapper.getBoundingClientRect();\n        app.renderer.resize(rect.width, rect.height);\n        layoutModel();\n      }\n\n\n      resizeApp();\n      ['resize', 'orientationchange', 'fullscreenchange', 'webkitfullscreenchange'].forEach(ev => {\n        window.addEventListener(ev, resizeApp);\n      });\n\n      \/\/ \u9f20\u6807\u63a7\u5236\u89c6\u7ebf\n      window.addEventListener('pointermove', (event) => {\n        const rect = canvas.getBoundingClientRect();\n        const x = event.clientX - rect.left;\n        const y = event.clientY - rect.top;\n        model.focus(x, y);\n      });\n\n      \/\/ ======= \u5de5\u5177\u51fd\u6570 =======\n      function delay(ms) {\n        return new Promise(resolve => setTimeout(resolve, ms));\n      }\n\n      function playBodyMotion(groupName, priority = MotionPriority.FORCE) {\n        const settings = model.internalModel.settings;\n        const motions  = settings.motions || settings.Motions || {};\n        const group    = motions[groupName];\n        if (!group || !group.length) {\n          console.warn('\u6ca1\u6709\u627e\u5230\u8eab\u4f53\u52a8\u4f5c\u7ec4:', groupName);\n          return;\n        }\n        return model.motion(groupName, 0, priority);\n      }\n\n      function playFaceMotion(groupName, priority = MotionPriority.FORCE) {\n        const settings = model.internalModel.settings;\n        const motions  = settings.motions || settings.Motions || {};\n        const group    = motions[groupName];\n        if (!group || !group.length) {\n          console.warn('\u6ca1\u6709\u627e\u5230\u9762\u90e8\u52a8\u4f5c\u7ec4:', groupName);\n          return;\n        }\n        return model.motion(groupName, 0, priority);\n      }\n\n      \/\/ ======= \u81ea\u5df1\u63a7\u5236 ParamEyeLOpen \/ ParamEyeROpen\uff1a\u53c2\u6570\u7ea7\u7728\u773c =======\n      const coreModel = model.internalModel.coreModel;\n      const EYE_L_ID = 'ParamEyeLOpen';\n      const EYE_R_ID = 'ParamEyeROpen';\n\n      \/\/ \u7728\u773c\u72b6\u6001\u673a\n      let blinkState = 'wait';   \/\/ 'wait' | 'closing' | 'opening'\n      let waitTimer = 0;\n      let phaseTimer = 0;\n      let nextBlinkTime = 2 + Math.random() * 3;   \/\/ \u4e0b\u4e00\u6b21\u7728\u773c\u95f4\u9694\uff08\u79d2\uff09\n      const blinkPhaseDuration = 0.08;             \/\/ \u95ed\u773c \/ \u7741\u773c\u5404\u81ea\u65f6\u957f\uff08\u79d2\uff09\n\n      \/\/ \u6bcf\u6b21\u7728\u773c\u524d\u8bb0\u5f55\u5f53\u65f6\u7684\u57fa\u7840\u773c\u775b\u5f00\u5408\uff08\u652f\u6301\u534a\u7741\u773c\u7684\u8868\u60c5\uff09\n      let baseEyeL = 1.0;\n      let baseEyeR = 1.0;\n\n      app.ticker.add(() => {\n        if (!coreModel) return;\n\n        \/\/ \u7528\u771f\u5b9e\u65f6\u95f4\u66f4\u7a33\uff1a\u6bcf\u5e27\u6beb\u79d2 \/ 1000\n        const dt = app.ticker.deltaMS \/ 1000;\n\n        if (blinkState === 'wait') {\n          \/\/ \u7b49\u5f85\u4e0b\u4e00\u6b21\u7728\u773c\n          waitTimer += dt;\n          if (waitTimer >= nextBlinkTime) {\n            waitTimer = 0;\n            blinkState = 'closing';\n            phaseTimer = 0;\n\n            \/\/ \u6bcf\u6b21\u7728\u773c\u524d\uff0c\u8bb0\u5f55\u5f53\u524d\u773c\u775b\u57fa\u7840\u503c\uff08\u53ef\u80fd\u4e0d\u662f 1\uff09\n            baseEyeL = coreModel.getParameterValueById(EYE_L_ID);\n            baseEyeR = coreModel.getParameterValueById(EYE_R_ID);\n          }\n        } else if (blinkState === 'closing') {\n          \/\/ \u4ece baseEye -> 0 \u7684\u95ed\u773c\u9636\u6bb5\n          phaseTimer += dt;\n          let t = phaseTimer \/ blinkPhaseDuration;\n          if (t > 1) t = 1;\n\n          const vL = baseEyeL * (1 - t);\n          const vR = baseEyeR * (1 - t);\n          coreModel.setParameterValueById(EYE_L_ID, vL);\n          coreModel.setParameterValueById(EYE_R_ID, vR);\n\n          if (t >= 1) {\n            blinkState = 'opening';\n            phaseTimer = 0;\n          }\n        } else if (blinkState === 'opening') {\n          \/\/ \u4ece 0 -> baseEye \u7684\u7741\u773c\u9636\u6bb5\n          phaseTimer += dt;\n          let t = phaseTimer \/ blinkPhaseDuration;\n          if (t > 1) t = 1;\n\n          const vL = baseEyeL * t;\n          const vR = baseEyeR * t;\n          coreModel.setParameterValueById(EYE_L_ID, vL);\n          coreModel.setParameterValueById(EYE_R_ID, vR);\n\n          if (t >= 1) {\n            blinkState = 'wait';\n            waitTimer = 0;\n            nextBlinkTime = 2 + Math.random() * 3;   \/\/ \u4e0b\u4e00\u6b21\u7728\u773c\u95f4\u9694\u518d\u968f\u673a\n          }\n        }\n      });\n\n\n      \/\/ ======= \u521d\u59cb\u52a8\u4f5c\uff1a\u5148\u8868\u60c5\u540e\u8eab\u4f53 =======\n      (async () => {\n        playBodyMotion('w-adult12-glad');\n        await delay(1000);\n        playFaceMotion('face_band_closeeye_03');\n\n      })();\n\n      \/\/ ======= \u652f\u6301\u6beb\u79d2 + \u201c\u65e0\u65f6\u95f4\u6233\u7eed\u884c\u201d\u7684 LRC \u53f0\u8bcd\u7cfb\u7edf =======\n      const lrcText = `\n[00:00.59]\u304d\u3063\u3068\u5c4a\u304f\u306f\u305a\u3000\u304d\u3063\u3068\u898b\u3048\u308b\u306f\u305a \n\u4e00\u5b9a\u80fd\u4f20\u8fbe\u7ed9\u4f60 \u4e00\u5b9a\u80fd\u628a\u4f60\u770b\u89c1\n[00:09.93]\u305d\u3093\u306a\u4f1a\u3063\u3066\u307f\u305f\u3044\u672a\u6765\u3092\u3000\u50d5\u306f\u3072\u3068\u308a\u304d\u308a\u306e\u30bb\u30ab\u30a4\u3067 \n\u90a3\u822c\u6211\u4eec\u60f3\u8ffd\u9010\u7684\u672a\u6765 \u6709\u6211\u5728\u8fd9\u5b64\u8eab\u4e00\u4eba\u7684\u4e16\u754c\n[00:15.65]\u305a\u3063\u3068\u305d\u3046\u6b4c\u3046\u305f\u3063\u3066\u3044\u305f \n\u4e00\u76f4\u8fd9\u6837\u6b4c\u5531\u7740\u5b83\u4eec\n[00:20.57]\n[00:28.06]\u4eca\u805e\u3053\u3048\u305f\u3088\u3000\u307b\u3089\u5c11\u3057\u3060\u3051 \n\u73b0\u5728\u6211\u542c\u5230\u4e86 \u4f60\u770b\u6211\u80fd\u591f\u7a0d\u5fae\n[00:34.24]\u541b\u3092\u611f\u3058\u305f\u3088\u3000\u30e1\u30ed\u30c7\u30a3\u30fc\u304c\u30ea\u30f3\u30af\u3059\u308b \n\u611f\u53d7\u5230\u4f60\u4e86\u554a \u65cb\u5f8b\u4ea4\u7ec7\u5c06\u6211\u4eec\u8fde\u7ed3\n[00:41.01]\u4eca\u7e4b\u304c\u308b\u3088\u3000\u4eca\u91cd\u306a\u308b\u3088 \n\u6b64\u523b\u60c5\u611f\u76f8\u8fde \u6b64\u523b\u5fc3\u613f\u4ea4\u6c47\n[00:46.95]\u4f1d\u3048\u305f\u304b\u3063\u305f\u3053\u3068\u3000\u5c71\u307b\u3069\u3042\u308b\u3093\u3060\u3051\u3069\u3069\u3046\u3057\u3088\u3046 \n\u60f3\u8981\u4f20\u8fbe\u7684\u5fc3\u610f \u5806\u5f97\u50cf\u5c71\u4e00\u6837 \u8be5\u600e\u4e48\u529e\u5462\n[00:55.09]\n[00:57.94]\u898b\u305f\u3053\u3068\u3082\u306a\u3044\u9854\u3067\u3000\u541b\u306f\u541b\u3092\u30c0\u30e1\u3068\u8a00\u3046\u3051\u3069 \n\u4f60\u9762\u9732\u6211\u6240\u672a\u89c1\u7684\u795e\u60c5 \u5766\u8a00\u81ea\u5df1\u767e\u65e0\u4e00\u7528\n[01:03.11]\u672a\u6765\u306b\u3044\u308b\u7406\u60f3\u306e\u541b\u3092\u3000\u4eca\u306e\u541b\u306b\u62bc\u3057\u4ed8\u3051\u904e\u304e\u306a\u3044\u3067 \n\u4f46\u6211\u613f\u4f60\u4e0d\u5fc5\u8fc7\u4e8e\u6267\u7740 \u53bb\u5f3a\u6c42\u672a\u6765\u90a3\u4e2a\u5b8c\u7f8e\u7684\u4f60\n[01:10.84]\u898b\u305f\u3053\u3068\u3082\u306a\u3044\u666f\u8272\u3000\u898b\u305b\u5408\u3046\u3044\u3064\u304b\u304c\u6765\u308b\u307e\u3067 \n\u672a\u66fe\u89c1\u8fc7\u7684\u5149\u666f \u76f4\u81f3\u5c06\u5176\u4e92\u76f8\u5206\u4eab\u7684\u90a3\u5929\u5230\u6765\n[01:15.78]\u3064\u3089\u3044\u3053\u3068\u3000\u6ce3\u304d\u305f\u304f\u306a\u308b\u3053\u3068\u3000\u305f\u307e\u306b\u306f\u9810\u3051\u5408\u304a\u3046 \n\u5c31\u628a\u5f7c\u6b64\u5fc3\u4e2d\u7684\u8f9b\u9178\u4e0e\u70ed\u6cea \u65f6\u4e0d\u65f6\u4e5f\u5bc4\u6258\u7ed9\u5bf9\u65b9\u5427\n[01:21.82]\n[01:21.95]\u30cf\u30ed\u30fc\u3001\u30bb\u30ab\u30a4\u3000\u50d5\u306e\u58f0\u306f\u3061\u3083\u3093\u3068\u5c4a\u3044\u3066\u308b\u304b\u3044 \nHello,SEKAI \u6211\u7684\u58f0\u97f3\u662f\u5426\u6e05\u6670\u660e\u6717\u5730\u4f20\u5230\u4f60\u8033\u8fb9\u5462\n[01:28.55]\u601d\u3063\u305f\u3088\u308a\u3082\u5927\u4e08\u592b\u3000\u541b\u306f\u3072\u3068\u308a\u306a\u3093\u304b\u3058\u3083\u306a\u3044 \n\u65e0\u9700\u4e3a\u6211\u5982\u6b64\u62c5\u5fc3 \u4f60\u6709\u6211\u4eec\u4e00\u8def\u76f8\u4f34\n[01:34.68]\u30cf\u30ed\u30fc\u3001\u30bb\u30ab\u30a4\u3000\u541b\u306e\u58f0\u3082\u3061\u3083\u3093\u3068\u5c4a\u3044\u3066\u308b\u3088 \nHello,SEKAI \u4f60\u7684\u58f0\u97f3\u6709\u597d\u597d\u5730\u6df1\u5165\u6211\u5fc3\n[01:41.12]\u601d\u3063\u305f\u3088\u308a\u3082\u6700\u9ad8\u3060\u3000\u50d5\u3082\u3072\u3068\u308a\u306a\u3093\u304b\u3058\u3083\u306a\u3044 \n\u90a3\u4efd\u6b4c\u58f0\u8fdc\u8d85\u671f\u5f85 \u6211\u4e5f\u4e0d\u518d\u5b64\u8eab\u4e00\u4eba\n[01:47.02]\n[01:47.02]\u884c\u304f\u3088\u30b8\u30e3\u30f3\u30d7\u3000\u8df3\u306d\u308b\u30c0\u30f3\u30b9 \n\u6765\u5427 jump \u8df3\u8d77\u6765 dance\n[01:50.22]\u3044\u3089\u306a\u3044\u4e0d\u5b89\u306a\u3093\u3066\u8e0f\u3093\u3058\u3083\u3063\u3066\u3053\u3046 \n\u8e0f\u8fc7\u591a\u4f59\u7684\u5fe7\u8651\u575a\u5b9a\u524d\u8fdb\u5427\n[01:53.85]\u3042\u3042\u3067\u3082\u3053\u3046\u3067\u3082\u306a\u3044\u3082\u3000\u305d\u3093\u306a\u306e\u3069\u3046\u3067\u3082\u3044\u3044\u3088 \n\u8fd9\u6837\u4e0d\u884c\u90a3\u6837\u4e5f\u4e0d\u884c \u8fd9\u4e9b\u4e8b\u60c5\u90fd\u65e0\u6240\u8c13\u5566\n[01:56.97]\u3084\u308a\u305f\u3044\u3088\u3046\u306b\u3084\u308d\u3046\u3000\u30cf\u30ed\u30fc\u30cf\u30ed\u30fc \n\u968f\u5fc3\u6240\u6b32\u5730\u653e\u624b\u505a\u5427 Hello Hello\n[01:59.67]\n[01:59.67]\u3082\u3046\u4e00\u56de\u30b8\u30e3\u30f3\u30d7\u3000\u56de\u308b\u30c0\u30f3\u30b9 \n\u518d\u4e00\u6b21 jump! \u53c8\u4e00\u5708dance\n[02:02.83]\u884c\u304d\u305f\u3044\u672a\u6765\u3000\u304d\u3063\u3068\u3082\u3046\u3059\u3050\u3060\u3088 \n\u60f3\u8981\u53bb\u4eb2\u5386\u7684\u672a\u6765 \u60f3\u5fc5\u5c31\u8fd1\u5728\u54ab\u5c3a\u5427\n[02:06.45]\u3042\u3042\u3067\u3082\u3053\u3046\u3067\u3082\u306a\u3044\u3082\u3000\u305d\u3093\u306a\u306e\u3069\u3046\u3067\u3082\u3044\u3044\u3088 \n\u8fd9\u6837\u4e0d\u884c\u90a3\u6837\u4e5f\u4e0d\u884c \u8fd9\u4e9b\u4e8b\u60c5\u90fd\u65e0\u6240\u8c13\u5566\n[02:09.57]\u3084\u308a\u305f\u3044\u3088\u3046\u306b\u3084\u308d\u3046 \n\u968f\u5fc3\u6240\u6b32\u5730\u653e\u624b\u505a\u5427\n[02:12.52]\n[02:12.61]\u98db\u3073\u8fbc\u3093\u3067\u3044\u3053\u3046\u3000\u50d5\u3089\u306e\u30bb\u30ab\u30a4\u304c \n\u4f60\u6211\u4e00\u9f50\u7eb5\u8eab\u8dc3\u5165 \u6211\u4eec\u8eab\u5904\u7684\u4e16\u754c\n[02:15.88]\u6b63\u89e3\u304b\u4e0d\u6b63\u89e3\u304b\u308f\u304b\u3089\u306a\u304f\u3066\u3082 \n\u5176\u4e2d\u7684\u5bf9\u4e0e\u9519\u5373\u4fbf\u6211\u4eec\u8fd8\u672a\u7406\u6e05\n[02:18.73]\u50d5\u306b\u3042\u308b\u60f3\u3044\u3082\u3000\u541b\u306b\u3042\u308b\u9858\u3044\u3082 \n\u53ef\u6211\u6240\u5177\u5907\u7684\u611f\u60c5 \u4f60\u6240\u5177\u5907\u7684\u5fc3\u613f\n[02:21.82]\u304d\u3063\u3068\u6d88\u3048\u306a\u3044\u3093\u3060\u3088\u3000\u305a\u3063\u3068\u30bb\u30ab\u30a4\u306f\u7d42\u308f\u3089\u306a\u3044\u3088 \n\u4e00\u5b9a\u4e0d\u4f1a\u6d88\u5931\u65e0\u8e2a \u4e16\u754c\u4e5f\u5c06\u6c38\u4e0d\u8c22\u5e55\n[02:25.60]\n[02:25.81]\u4eca\u7e4b\u304c\u308b\u3088\u3000\u4eca\u91cd\u306a\u308b\u3088 \n\u6b64\u523b\u60c5\u611f\u76f8\u8fde \u6b64\u523b\u5fc3\u613f\u4ea4\u6c47\n[02:32.14]\u307b\u3089\u805e\u3053\u3048\u308b\u3088\u3000\u307b\u3089\u4f1d\u308f\u308b\u3088\u50d5\u3089 \n\u770b\u5427 \u6211\u4eec\u542c\u89c1\u4e86\u54e6 \u770b\u5427 \u6211\u4eec\u7684\u5fc3\u58f0\u4f20\u9012\u51fa\u53bb\u4e86\u54e6\n[02:38.51]\n      `;\n\n      function parseLRC(text) {\n        const lines   = text.split('\\n');\n        const result  = [];\n        let lastEntry = null;\n\n        for (let raw of lines) {\n          const line = raw.replace(\/\\r\/g, '');\n          if (!line.trim()) continue;  \/\/ \u7a7a\u884c\u76f4\u63a5\u8df3\u8fc7\n\n          const match = line.match(\/\\[(\\d{2}):(\\d{2})(?:\\.(\\d{1,3}))?]\/);\n          if (match) {\n            const min = parseInt(match[1], 10);\n            const sec = parseInt(match[2], 10);\n            const ms  = match[3] ? parseInt(match[3].padEnd(3, '0'), 10) : 0;\n            const content = line\n              .replace(\/\\[\\d{2}:\\d{2}(?:\\.\\d{1,3})?]\/, '')\n              .trim();  \/\/ \u5141\u8bb8\u4e3a\u7a7a \u2192 \u7528\u6765\u5173\u6c14\u6ce1\n\n            const entry = {\n              time: min * 60 + sec + ms \/ 1000,\n              text: content\n            };\n            result.push(entry);\n            lastEntry = entry;\n          } else {\n            \/\/ \u65e0\u65f6\u95f4\u6807\u7b7e\u4f46\u6709\u6587\u5b57\uff1a\u4f5c\u4e3a\u4e0a\u4e00\u53e5\u7684\u201c\u7eed\u884c\u201d\n            if (lastEntry) {\n              if (lastEntry.text) {\n                lastEntry.text += '\\n' + line.trim();\n              } else {\n                lastEntry.text = line.trim();\n              }\n            }\n          }\n        }\n\n        return result.sort((a, b) => a.time - b.time);\n      }\n\n      const scriptData   = parseLRC(lrcText);\n      let currentIndex   = -1;\n      let finishedOnce   = false;\n      let lyricsStarted  = false;\n      let dialogTimer    = null;\n      let startTime      = 0;   \/\/ \u53f0\u8bcd\u5f00\u59cb\u7684\u65f6\u95f4\u6233\uff08\u6beb\u79d2\uff09\n\n      \/\/ ======= \u53f0\u8bcd\u5237\u65b0\u51fd\u6570\uff08\u73b0\u5728\u8ddf startLyrics \u5728\u540c\u4e00\u4f5c\u7528\u57df\uff09=======\n      function updateDialog() {\n        if (!scriptData.length) return;\n\n        const elapsed = (Date.now() - startTime) \/ 1000; \/\/ \u79d2\n        let idx = currentIndex;\n\n        for (let i = scriptData.length - 1; i >= 0; i--) {\n          if (elapsed >= scriptData[i].time) {\n            idx = i;\n            break;\n          }\n        }\n\n        if (idx !== currentIndex && idx >= 0) {\n          currentIndex = idx;\n          const line = scriptData[idx];\n\n          if (line.text && line.text.length > 0) {\n            dialogBox.textContent = line.text;\n            dialogBox.classList.add('show');\n          } else {\n            dialogBox.textContent = \"\";\n            dialogBox.classList.remove('show');\n          }\n        }\n\n        const lastTime = scriptData[scriptData.length - 1].time;\n        if (!finishedOnce && elapsed >= lastTime) {\n          finishedOnce = true;\n\n          (async () => {\n            playFaceMotion('face_band_smile_08');\n            await delay(300);\n            playBodyMotion('w-adult01-shakehand');\n            await delay(4000);\n            playBodyMotion('w-normal01-glad');\n          })();\n\n          if (dialogTimer) {\n            clearInterval(dialogTimer);\n            dialogTimer = null;\n          }\n        }\n      }\n\n      \/\/ ======= \u97f3\u4e50 + \u53f0\u8bcd\u542f\u52a8\u51fd\u6570\uff08\u73b0\u5728\u4e5f\u5728\u540c\u4e00\u4f5c\u7528\u57df\u91cc\uff09=======\n      function startLyrics() {\n        if (lyricsStarted) return;\n        lyricsStarted = true;\n        startTime     = Date.now();\n        dialogTimer   = setInterval(updateDialog, 100);\n      }\n\n      function startBgmAndLyrics() {\n        bgm.play().then(() => {\n          \/\/ \u81ea\u52a8\u64ad\u653e\u6210\u529f\uff1a\u7acb\u523b\u542f\u52a8\u53f0\u8bcd\n          startLyrics();\n        }).catch(err => {\n          console.warn(\"\u97f3\u4e50\u81ea\u52a8\u64ad\u653e\u88ab\u6d4f\u89c8\u5668\u963b\u6b62\uff0c\u5c06\u5728\u7528\u6237\u70b9\u51fb\u9875\u9762\u540e\u5f00\u59cb\u64ad\u653e\u548c\u53f0\u8bcd\u3002\", err);\n          const resume = () => {\n            bgm.play().then(() => {\n              startLyrics();\n            }).catch(() => {});\n            document.removeEventListener('click', resume);\n          };\n          document.addEventListener('click', resume, { once: true });\n        });\n      }\n\n      \/\/ \u6a21\u578b\u52a0\u8f7d\u5b8c\u6210\u540e\u518d\u5c1d\u8bd5\u542f\u52a8\u97f3\u4e50 + \u53f0\u8bcd\n      startBgmAndLyrics();\n    }).catch(err => {\n      console.error(\"Live2D \u6a21\u578b\u52a0\u8f7d\u5931\u8d25\uff1a\", err);\n    });\n  })();\n<\/script>\n\n<style>\n  #live2d-wrapper {\n    position: fixed;\n    inset: 0;\n    z-index: 9999;\n    pointer-events: none;\n    overflow: hidden;\n  }\n\n#live2d-bg {\n  position: absolute;\n  inset: 0;\n  background-image: url(\"https:\/\/www.admiralspee.site\/wp-content\/uploads\/v2_clb01_21miku_t03\/bg_area_25.webp\"); \/* \u6362\u6210\u4f60\u7684\u56fe\u7247\u5730\u5740 *\/\n  background-size: cover;      \/* \u586b\u6ee1\u5c4f\u5e55 *\/\n  background-position: center; \/* \u5c45\u4e2d\u88c1\u5207 *\/\n  background-repeat: no-repeat;\n  opacity: 1;\n  transition: opacity 1.5s ease;  \/* \u6e10\u9690\u65f6\u95f4\u53ef\u6539 *\/\n  z-index: 0;\n  pointer-events: none;\n}\n\n\/* \u6e10\u9690\u7ed3\u675f\u72b6\u6001 *\/\n#live2d-bg.fade-out {\n  opacity: 0;\n}\n\n#live2d-canvas {\n  position: absolute;\n  inset: 0;\n  width: 100%;\n  height: 100%;\n  display: block;\n  pointer-events: none;\n  z-index: 1;\n}\n\n  #live2d-dialog {\n    position: absolute;\n    bottom: 200px;\n    right: 50%;\n    transform: translateX(50%);\n    max-width: 350px;\n    padding: 8px 10px;\n    background: rgba(0, 0, 0, 0.65);\n    color: #fff;\n    font-size: 16px;\n    border-radius: 12px;\n    line-height: 1.4;\n    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.4);\n    opacity: 0;\n    transition: opacity 0.3s;\n    pointer-events: none;\n    white-space: pre-line; \/* \u652f\u6301 \\n \u6362\u884c *\/\n    z-index: 2; \/* \u5728\u6700\u4e0a\u5c42 *\/\n  }\n\n  #live2d-dialog.show {\n    opacity: 1;\n  }\n<\/style>\n\n\n\n<p class=\"has-text-align-center\">Live2D<\/p>\n\n\n\n<p class=\"has-text-align-center\">[\u6765\u81ea\u7a97\u6249\u7684\u300c\u4e16\u754c\u300d] \u521d\u97f3\u672a\u6765 &#8211; \u4e16\u5609\/Crypton Future Media<\/p>\n\n\n\n<p class=\"has-text-align-center\">\u97f3\u4e50<\/p>\n\n\n\n<p class=\"has-text-align-center\">\u30cf\u30ed\u30fc\u30bb\u30ab\u30a4 &#8211; \u521d\u97f3\u672a\u6765\/DECO*27<\/p>\n\n\n\n<p class=\"has-text-align-center\">\u80cc\u666f<\/p>\n\n\n\n<p class=\"has-text-align-center\">\u7a97\u6249\u7684\u300c\u4e16\u754c\u300d &#8211; \u4e16\u5609<\/p>\n\n\n\n<p class=\"has-text-align-center\">\u6b4c\u8bcd<\/p>\n\n\n\n<p class=\"has-text-align-center\">\u65e5\u6587\u6b4c\u8bcd &#8211; DECO*27<\/p>\n\n\n\n<p class=\"has-text-align-center\">\u4e2d\u6587\u7ffb\u8bd1 &#8211; TME<\/p>\n\n\n\n<hr class=\"wp-block-separator has-text-color has-cyan-bluish-gray-color has-alpha-channel-opacity has-cyan-bluish-gray-background-color has-background is-style-dots\"\/>\n\n\n\n<p class=\"has-text-align-center\">\u613f\u4f60\u7684\u5fc3\u613f\u4e16\u754c\u4e2d\u4e5f\u6709\u4e00\u4e2a\u521d\u97f3\u672a\u6765\u3002<\/p>","protected":false},"excerpt":{"rendered":"<p>Live2D [\u6765\u81ea\u7a97\u6249\u7684\u300c\u4e16\u754c\u300d] \u521d\u97f3\u672a\u6765 &#8211; \u4e16\u5609\/Crypton Future Media [&hellip;]<\/p>","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-1436","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/www.admiralspee.site\/en\/wp-json\/wp\/v2\/pages\/1436","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.admiralspee.site\/en\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.admiralspee.site\/en\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.admiralspee.site\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.admiralspee.site\/en\/wp-json\/wp\/v2\/comments?post=1436"}],"version-history":[{"count":89,"href":"https:\/\/www.admiralspee.site\/en\/wp-json\/wp\/v2\/pages\/1436\/revisions"}],"predecessor-version":[{"id":1653,"href":"https:\/\/www.admiralspee.site\/en\/wp-json\/wp\/v2\/pages\/1436\/revisions\/1653"}],"wp:attachment":[{"href":"https:\/\/www.admiralspee.site\/en\/wp-json\/wp\/v2\/media?parent=1436"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}