{"id":26241,"date":"2025-12-21T15:43:32","date_gmt":"2025-12-21T06:43:32","guid":{"rendered":"http:\/\/www.tyosuke20xx.com\/blog\/?p=26241"},"modified":"2025-12-21T15:43:35","modified_gmt":"2025-12-21T06:43:35","slug":"elder-social-vr-html","status":"publish","type":"post","link":"http:\/\/www.tyosuke20xx.com\/blog\/?p=26241","title":{"rendered":"ELDER Social VR.html"},"content":{"rendered":"\n<pre class=\"wp-block-code\"><code>&lt;!DOCTYPE html>\n&lt;html lang=\"ja\">\n&lt;head>\n  &lt;meta charset=\"UTF-8\" \/>\n  &lt;meta name=\"viewport\" content=\"width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no\" \/>\n  &lt;title>ELDER Social VR - \u8d85\u5b8c\u5168\u7248\uff08\u30af\u30e9\u30a4\u30a2\u30f3\u30c8\u306e\u307f\uff09&lt;\/title>\n  &lt;script src=\"https:\/\/aframe.io\/releases\/1.4.2\/aframe.min.js\">&lt;\/script>\n\n  &lt;style>\n    :root{\n      --bg: rgba(10,12,14,.82);\n      --glass: rgba(255,255,255,.06);\n      --stroke: rgba(255,255,255,.13);\n      --accent: rgba(120,240,255,.95);\n      --accent2: rgba(120,160,255,.95);\n    }\n    html,body{ margin:0; padding:0; height:100%; overflow:hidden; background:#000; font-family: \"Yu Gothic\", system-ui, -apple-system, Segoe UI, sans-serif; }\n    a-scene{ position:fixed; inset:0; z-index:0; }\n    canvas{ position:fixed !important; inset:0; z-index:0; }\n\n    \/* ===== HUD (DOM UI) ===== *\/\n    #hud{\n      position: fixed; inset: 0;\n      display:flex; align-items:flex-start; justify-content:center;\n      pointer-events:none;\n      z-index: 999999;\n    }\n    #panel{\n      margin-top: 18px;\n      width: min(560px, calc(100vw - 26px));\n      background: linear-gradient(180deg, rgba(255,255,255,.06), rgba(0,0,0,.28));\n      border: 1px solid var(--stroke);\n      border-radius: 18px;\n      box-shadow: 0 18px 60px rgba(0,0,0,.45), 0 0 0 1px rgba(0,0,0,.2) inset;\n      backdrop-filter: blur(10px);\n      color:#fff;\n      padding: 16px;\n      pointer-events:auto;\n      touch-action: manipulation;\n      user-select:none;\n      position: relative;\n    }\n    #panel, #panel *{ pointer-events:auto; }\n\n    \/* UI\u96a0\u3059\u30dc\u30bf\u30f3 *\/\n    #btnHideUI{\n      position:absolute;\n      top: 12px;\n      right: 12px;\n      width: auto;\n      padding: 10px 12px;\n      border-radius: 12px;\n      font-weight: 900;\n      font-size: 12px;\n      letter-spacing: .2px;\n      background: rgba(0,0,0,.35);\n      border: 1px solid rgba(255,255,255,.16);\n      cursor: pointer;\n      display:flex;\n      align-items:center;\n      gap:8px;\n      -webkit-tap-highlight-color: transparent;\n    }\n    #btnHideUI:hover{ border-color: rgba(120,240,255,.35); }\n    #btnHideUI:active{ transform: scale(.99); }\n\n    \/* HUD\u3092\u9589\u3058\u305f\u5f8c\u306b\u51fa\u3059\u5c0f\u30dc\u30bf\u30f3 *\/\n    #floatingShowUI{\n      position: fixed;\n      right: 14px;\n      bottom: 14px;\n      z-index: 9999999;\n      display: none;\n      pointer-events:auto;\n      background: rgba(10,12,14,.72);\n      border: 1px solid rgba(255,255,255,.18);\n      backdrop-filter: blur(10px);\n      color:#fff;\n      border-radius: 999px;\n      padding: 12px 14px;\n      font-weight: 900;\n      cursor:pointer;\n      box-shadow: 0 10px 40px rgba(0,0,0,.4);\n      -webkit-tap-highlight-color: transparent;\n    }\n    #floatingShowUI:hover{ border-color: rgba(120,240,255,.35); }\n    #floatingShowUI:active{ transform: scale(.99); }\n\n    .top{\n      display:flex; align-items:center; justify-content:space-between;\n      gap: 10px;\n      margin-bottom: 12px;\n      padding-right: 86px; \/* \u96a0\u3059\u30dc\u30bf\u30f3\u5206\u30b9\u30da\u30fc\u30b9 *\/\n    }\n    .brand{\n      font-weight: 900;\n      letter-spacing: .5px;\n      font-size: 22px;\n    }\n    .pill{\n      display:inline-flex; align-items:center; gap:8px;\n      background: rgba(255,255,255,.06);\n      border: 1px solid rgba(255,255,255,.14);\n      padding: 8px 12px;\n      border-radius: 999px;\n      font-size: 12px;\n      opacity:.95;\n    }\n\n    .grid{\n      display:grid;\n      grid-template-columns: 1fr 1fr;\n      gap: 10px;\n    }\n    .btn{\n      display:flex; align-items:center; justify-content:center;\n      gap: 10px;\n      padding: 14px 12px;\n      border-radius: 14px;\n      background: linear-gradient(180deg, rgba(255,255,255,.08), rgba(0,0,0,.25));\n      border: 1px solid rgba(255,255,255,.14);\n      color:#fff;\n      font-weight: 900;\n      letter-spacing: .4px;\n      cursor:pointer;\n      transform: translateZ(0);\n      transition: transform .08s, border-color .18s, background .18s;\n      touch-action: manipulation;\n      -webkit-tap-highlight-color: transparent;\n    }\n    .btn:hover{ border-color: rgba(120,240,255,.35); }\n    .btn:active{ transform: scale(.99); }\n    .btn.primary{ border-color: rgba(120,240,255,.28); box-shadow: 0 0 0 1px rgba(120,240,255,.10) inset; }\n    .btn.danger{ border-color: rgba(255,120,160,.25); }\n\n    .section{\n      margin-top: 12px;\n      background: rgba(0,0,0,.22);\n      border: 1px solid rgba(255,255,255,.10);\n      border-radius: 16px;\n      padding: 12px;\n    }\n    .sectionTitle{\n      font-weight: 900;\n      opacity:.92;\n      margin-bottom: 8px;\n      display:flex; align-items:center; justify-content:space-between;\n      gap: 10px;\n    }\n    .statGrid{\n      display:grid;\n      grid-template-columns: 1fr 1fr;\n      gap: 10px;\n    }\n    .card{\n      background: rgba(255,255,255,.04);\n      border: 1px solid rgba(255,255,255,.10);\n      border-radius: 14px;\n      padding: 10px;\n    }\n    .label{ opacity:.82; font-size: 12px; }\n    .big{ font-size: 20px; font-weight: 900; margin-top: 4px; }\n    .bar{\n      margin-top: 8px;\n      height: 10px;\n      background: rgba(255,255,255,.08);\n      border-radius: 999px;\n      overflow:hidden;\n      border: 1px solid rgba(0,0,0,.22);\n    }\n    .bar > div{ height:100%; width:50%; background: linear-gradient(90deg, var(--accent), var(--accent2)); }\n\n    .log{\n      margin-top: 10px;\n      max-height: 140px;\n      overflow:auto;\n      padding: 10px;\n      border-radius: 14px;\n      border: 1px solid rgba(255,255,255,.12);\n      background: rgba(0,0,0,.28);\n      font-size: 12px;\n      line-height: 1.35;\n    }\n\n    \/* \u30e2\u30fc\u30c0\u30eb *\/\n    #modalBack{\n      position: fixed; inset:0;\n      display:none;\n      align-items:center; justify-content:center;\n      background: rgba(0,0,0,.55);\n      z-index: 9999999;\n      pointer-events:auto;\n    }\n    #modal{\n      width: min(620px, calc(100vw - 26px));\n      background: rgba(10,12,14,.92);\n      border: 1px solid rgba(255,255,255,.14);\n      border-radius: 18px;\n      box-shadow: 0 18px 70px rgba(0,0,0,.55);\n      color:#fff;\n      padding: 14px;\n    }\n    #modal h3{\n      margin: 0 0 10px 0;\n      font-size: 18px;\n      letter-spacing: .3px;\n    }\n    .modalBody{ opacity:.92; font-size: 14px; line-height: 1.5; white-space: pre-wrap; }\n    .modalBtns{ display:flex; gap: 10px; margin-top: 12px; flex-wrap:wrap; }\n    .modalBtns .btn{ flex: 1 1 140px; }\n\n    \/* VR\u4e2d\u306fDOM HUD\u3092\u96a0\u3059 *\/\n    body.vr #hud{ display:none !important; }\n    body.vr #floatingShowUI{ display:none !important; }\n  &lt;\/style>\n&lt;\/head>\n\n&lt;body>\n  &lt;!-- HUD -->\n  &lt;div id=\"hud\">\n    &lt;div id=\"panel\">\n      &lt;div id=\"btnHideUI\" title=\"UI\u3092\u96a0\u3059\uff08ESC\u3067\u623b\u305b\u308b\uff09\">\u2715 UI\u3092\u96a0\u3059&lt;\/div>\n\n      &lt;div class=\"top\">\n        &lt;div class=\"brand\">ELDER Social VR&lt;\/div>\n        &lt;div class=\"pill\">\u73fe\u5728\u5730: &lt;b id=\"fieldTag\">\u8857&lt;\/b>&lt;\/div>\n      &lt;\/div>\n\n      &lt;div class=\"grid\" style=\"margin-bottom:10px;\">\n        &lt;div class=\"btn primary\" id=\"btnTown\">\ud83c\udfd8\ufe0f \u8857&lt;\/div>\n        &lt;div class=\"btn primary\" id=\"btnCastle\">\ud83c\udff0 \u57ce&lt;\/div>\n        &lt;div class=\"btn primary\" id=\"btnCave\">\ud83d\udd73\ufe0f \u6d1e\u7a9f&lt;\/div>\n        &lt;div class=\"btn primary\" id=\"btnRuins\">\ud83c\udfdb\ufe0f \u907a\u8de1&lt;\/div>\n      &lt;\/div>\n\n      &lt;div class=\"grid\" style=\"margin-bottom:10px;\">\n        &lt;div class=\"btn\" id=\"btnEnterVR\">\ud83d\udd76\ufe0f Enter VR&lt;\/div>\n        &lt;div class=\"btn danger\" id=\"btnExit\">\u23cf Exit&lt;\/div>\n        &lt;div class=\"btn\" id=\"btnWave\">\ud83d\udc4b Wave&lt;\/div>\n        &lt;div class=\"btn\" id=\"btnCheer\">\ud83c\udf89 Cheer&lt;\/div>\n      &lt;\/div>\n\n      &lt;div class=\"section\">\n        &lt;div class=\"sectionTitle\">\n          &lt;span>\u30ec\u30d9\u30eb \/ EXP&lt;\/span>\n          &lt;span class=\"pill\">\u540d\u524d: &lt;b id=\"playerNameLabel\">YOU&lt;\/b>&lt;\/span>\n        &lt;\/div>\n        &lt;div class=\"statGrid\">\n          &lt;div class=\"card\">\n            &lt;div class=\"label\">Lv \/ EXP&lt;\/div>\n            &lt;div class=\"big\">Lv.&lt;span id=\"level\">1&lt;\/span> &lt;span style=\"opacity:.8;font-size:12px;\">EXP&lt;\/span> &lt;span id=\"expText\">0&lt;\/span>\/&lt;span id=\"expNeedText\">100&lt;\/span>&lt;\/div>\n            &lt;div class=\"bar\">&lt;div id=\"expBar\" style=\"width:0%\">&lt;\/div>&lt;\/div>\n          &lt;\/div>\n          &lt;div class=\"card\">\n            &lt;div class=\"label\">\u30b4\u30fc\u30eb\u30c9&lt;\/div>\n            &lt;div class=\"big\">&lt;span id=\"goldText\">0&lt;\/span> G&lt;\/div>\n            &lt;div class=\"label\" style=\"margin-top:6px;\">\u8857\u306e\u5546\u4eba\u3067\u8cb7\u3044\u7269\u3067\u304d\u308b&lt;\/div>\n          &lt;\/div>\n        &lt;\/div>\n\n        &lt;div class=\"statGrid\" style=\"margin-top:10px;\">\n          &lt;div class=\"card\">\n            &lt;div class=\"label\">HP&lt;\/div>\n            &lt;div class=\"big\" id=\"hpText\">100&lt;\/div>\n            &lt;div class=\"bar\">&lt;div id=\"hpBar\" style=\"width:100%\">&lt;\/div>&lt;\/div>\n          &lt;\/div>\n          &lt;div class=\"card\">\n            &lt;div class=\"label\">\u9b54\u529b&lt;\/div>\n            &lt;div class=\"big\" id=\"manaText\">100&lt;\/div>\n            &lt;div class=\"bar\">&lt;div id=\"manaBar\" style=\"width:100%\">&lt;\/div>&lt;\/div>\n          &lt;\/div>\n        &lt;\/div>\n      &lt;\/div>\n\n      &lt;div class=\"grid\" style=\"margin-top:10px;\">\n        &lt;div class=\"btn\" id=\"btnTalk\">\ud83d\udcac \u8a71\u3059&lt;\/div>\n        &lt;div class=\"btn\" id=\"btnQuest\">\ud83d\udcdc \u30af\u30a8\u30b9\u30c8&lt;\/div>\n        &lt;div class=\"btn\" id=\"btnShop\">\ud83d\uded2 \u30b7\u30e7\u30c3\u30d7&lt;\/div>\n        &lt;div class=\"btn\" id=\"btnRest\">\ud83d\udecf \u4f11\u61a9&lt;\/div>\n        &lt;div class=\"btn\" id=\"btnSave\">\ud83d\udcbe \u30bb\u30fc\u30d6&lt;\/div>\n        &lt;div class=\"btn\" id=\"btnLoad\">\ud83d\udcc2 \u30ed\u30fc\u30c9&lt;\/div>\n      &lt;\/div>\n\n      &lt;div class=\"log\" id=\"log\">&lt;\/div>\n      &lt;div style=\"opacity:.7;font-size:11px;margin-top:8px;line-height:1.35;\">\n        \u64cd\u4f5c: WASD\u79fb\u52d5 \/ Shift\u30c0\u30c3\u30b7\u30e5 \/ Space\u30b8\u30e3\u30f3\u30d7 \/ \u30de\u30a6\u30b9\u8996\u70b9\uff08\u30af\u30ea\u30c3\u30af\u3067\u30dd\u30a4\u30f3\u30bf\u30ed\u30c3\u30af\uff09&lt;br\/>\n        VR: Enter VR \u2192 \u30b3\u30f3\u30c8\u30ed\u30fc\u30e9\u306e\u30ec\u30fc\u30b6\u30fc\u30673D UI\u3092\u62bc\u305b\u308b\uff08DOM UI\u306f\u975e\u8868\u793a\uff09&lt;br\/>\n        UI: \u53f3\u4e0a\u300cUI\u3092\u96a0\u3059\u300dor ESC\u3067\u5207\u66ff\n      &lt;\/div>\n    &lt;\/div>\n  &lt;\/div>\n\n  &lt;!-- HUD\u3092\u96a0\u3057\u305f\u5f8c\u306b\u51fa\u3059\u30dc\u30bf\u30f3 -->\n  &lt;div id=\"floatingShowUI\">\u2261 UI\u3092\u8868\u793a&lt;\/div>\n\n  &lt;!-- Modal -->\n  &lt;div id=\"modalBack\">\n    &lt;div id=\"modal\">\n      &lt;h3 id=\"modalTitle\">TITLE&lt;\/h3>\n      &lt;div class=\"modalBody\" id=\"modalBody\">&lt;\/div>\n      &lt;div class=\"modalBtns\" id=\"modalBtns\">&lt;\/div>\n    &lt;\/div>\n  &lt;\/div>\n\n  &lt;!-- A-Frame -->\n  &lt;a-scene\n    id=\"scene\"\n    renderer=\"colorManagement:true; physicallyCorrectLights:true\"\n    shadow=\"type:pcfsoft\"\n    webxr=\"optionalFeatures: local-floor, bounded-floor, hand-tracking\"\n  >\n    &lt;a-assets>\n      &lt;!-- BGM\uff08\u30a8\u30ea\u30a2\u3067\u5207\u66ff\uff09 -->\n      &lt;audio id=\"bgmTown\"   src=\"https:\/\/www.free-stock-music.com\/music\/scott-buckley\/mp3\/scott-buckley-beautiful-oblivion.mp3\" crossorigin=\"anonymous\">&lt;\/audio>\n      &lt;audio id=\"bgmCastle\" src=\"https:\/\/www.free-stock-music.com\/music\/scott-buckley\/mp3\/scott-buckley-the-endurance.mp3\" crossorigin=\"anonymous\">&lt;\/audio>\n      &lt;audio id=\"bgmCave\"   src=\"https:\/\/www.free-stock-music.com\/music\/scott-buckley\/mp3\/scott-buckley-in-search-of-solitude.mp3\" crossorigin=\"anonymous\">&lt;\/audio>\n      &lt;audio id=\"bgmRuins\"  src=\"https:\/\/www.free-stock-music.com\/music\/wombat-noises-audio\/mp3\/wombat-noises-audio-the-ruins-of-atlantis.mp3\" crossorigin=\"anonymous\">&lt;\/audio>\n    &lt;\/a-assets>\n\n    &lt;!-- \u7a7a -->\n    &lt;a-sky id=\"sky\" color=\"#061018\">&lt;\/a-sky>\n\n    &lt;!-- \u5149 -->\n    &lt;a-light type=\"ambient\" intensity=\"0.9\" color=\"#dff8ff\">&lt;\/a-light>\n    &lt;a-light id=\"sun\" type=\"directional\" intensity=\"1.35\" position=\"30 40 10\"\n             castShadow=\"true\" shadow-mapWidth=\"2048\" shadow-mapHeight=\"2048\">&lt;\/a-light>\n\n    &lt;!-- \u6d77 -->\n    &lt;a-entity id=\"ocean\" position=\"0 0 0\">\n      &lt;a-cylinder position=\"0 -1.4 0\" radius=\"140\" height=\"2.2\" open-ended=\"true\"\n                  material=\"color:#0a2a3a; metalness:0.05; roughness:0.35; opacity:0.95; transparent:true\">&lt;\/a-cylinder>\n      &lt;a-ring position=\"0 -0.2 0\" radius-inner=\"65\" radius-outer=\"140\"\n              rotation=\"-90 0 0\"\n              material=\"color:#0b3143; opacity:0.88; transparent:true\">&lt;\/a-ring>\n    &lt;\/a-entity>\n\n    &lt;!-- \u5cf6\uff083\u6bb5\uff09 -->\n    &lt;a-entity id=\"island\">\n      &lt;a-cylinder position=\"0 -0.1 0\" radius=\"62\" height=\"1\"\n                  material=\"color:#cbb48b; roughness:0.95; metalness:0.0\">&lt;\/a-cylinder>\n      &lt;a-cylinder position=\"0 0.05 0\" radius=\"50\" height=\"1\"\n                  material=\"color:#2f6a3f; roughness:0.95; metalness:0.0\">&lt;\/a-cylinder>\n      &lt;a-cylinder position=\"0 0.35 0\" radius=\"34\" height=\"1.2\"\n                  material=\"color:#2a5f3a; roughness:0.95\">&lt;\/a-cylinder>\n      &lt;a-ring position=\"0 0.42 0\" radius-inner=\"14\" radius-outer=\"17\" rotation=\"-90 0 0\"\n              material=\"color:#3b2f23; roughness:1\">&lt;\/a-ring>\n      &lt;a-ring position=\"0 0.42 0\" radius-inner=\"26\" radius-outer=\"29\" rotation=\"-90 0 0\"\n              material=\"color:#3b2f23; roughness:1; opacity:0.85; transparent:true\">&lt;\/a-ring>\n    &lt;\/a-entity>\n\n    &lt;!-- BGM -->\n    &lt;a-entity id=\"bgm\" sound=\"src:#bgmTown; autoplay:false; loop:true; volume:0.65; positional:false\">&lt;\/a-entity>\n\n    &lt;!-- \u30d7\u30ec\u30a4\u30e4\u30fc\uff08\u203by\u306f\u57fa\u6e960.55\u3067\u7f6e\u304f\u3002\u8d77\u52d5\u6642\u306bJS\u3067\u201c\u5730\u9762\u306b\u30b9\u30ca\u30c3\u30d7\u201d\u3057\u3066\u57cb\u307e\u308a\u30bc\u30ed\uff09 -->\n    &lt;a-entity id=\"playerRig\" position=\"0 0.55 18\">\n      &lt;!-- \u304b\u3063\u3053\u3044\u3044\u52c7\u8005\uff08\u7c21\u6613\u30cf\u30a4\u30c7\u30a3\u30c6\u30fc\u30eb\uff09 -->\n      &lt;a-entity id=\"hero\" position=\"0 0 0\"\n                animation__idle=\"property: rotation; dir: alternate; dur: 1800; loop: true; to: 0 1.2 0\"\n                animation__breath=\"property: scale; dir: alternate; dur: 1200; loop: true; to: 1.01 1.02 1.01\">\n\n        &lt;!-- \u5f71 -->\n        &lt;a-circle radius=\"0.75\" rotation=\"-90 0 0\" position=\"0 0.02 0\"\n                  material=\"color:#000; opacity:0.25; transparent:true\">&lt;\/a-circle>\n\n        &lt;!-- \u30de\u30f3\u30c8 -->\n        &lt;a-entity id=\"cape\" position=\"0 1.22 0.16\" rotation=\"10 0 0\"\n                  animation__cape=\"property: rotation; dir: alternate; dur: 900; loop: true; to: 12 1 0\">\n          &lt;a-plane width=\"0.95\" height=\"1.35\" position=\"0 -0.58 -0.20\"\n                   material=\"color:#0b1020; opacity:0.96; transparent:true; side:double\">&lt;\/a-plane>\n          &lt;a-plane width=\"0.55\" height=\"1.15\" position=\"-0.28 -0.62 -0.21\" rotation=\"0 8 0\"\n                   material=\"color:#0a0f1c; opacity:0.90; transparent:true; side:double\">&lt;\/a-plane>\n          &lt;a-plane width=\"0.55\" height=\"1.15\" position=\"0.28 -0.62 -0.21\" rotation=\"0 -8 0\"\n                   material=\"color:#0a0f1c; opacity:0.90; transparent:true; side:double\">&lt;\/a-plane>\n        &lt;\/a-entity>\n\n        &lt;!-- \u30d6\u30fc\u30c4 -->\n        &lt;a-box position=\"-0.17 0.16 0\" width=\"0.22\" height=\"0.34\" depth=\"0.30\"\n               material=\"color:#1a1418; roughness:1\">&lt;\/a-box>\n        &lt;a-box position=\"0.17 0.16 0\" width=\"0.22\" height=\"0.34\" depth=\"0.30\"\n               material=\"color:#1a1418; roughness:1\">&lt;\/a-box>\n        &lt;a-box position=\"-0.17 0.06 -0.14\" width=\"0.24\" height=\"0.12\" depth=\"0.22\"\n               material=\"color:#0f0c10; roughness:1\">&lt;\/a-box>\n        &lt;a-box position=\"0.17 0.06 -0.14\" width=\"0.24\" height=\"0.12\" depth=\"0.22\"\n               material=\"color:#0f0c10; roughness:1\">&lt;\/a-box>\n\n        &lt;!-- \u811a\uff08\u93a7\uff09 -->\n        &lt;a-box position=\"-0.17 0.56 0\" width=\"0.26\" height=\"0.54\" depth=\"0.32\"\n               material=\"color:#2b3140; metalness:0.25; roughness:0.55\">&lt;\/a-box>\n        &lt;a-box position=\"0.17 0.56 0\" width=\"0.26\" height=\"0.54\" depth=\"0.32\"\n               material=\"color:#2b3140; metalness:0.25; roughness:0.55\">&lt;\/a-box>\n\n        &lt;!-- \u819d\u30eb\u30fc\u30f3 -->\n        &lt;a-box position=\"-0.17 0.44 -0.18\" width=\"0.26\" height=\"0.14\" depth=\"0.14\"\n               material=\"color:#78f0ff; emissive:#2dd; emissiveIntensity:0.20; metalness:0.3; roughness:0.35; opacity:0.55; transparent:true\">&lt;\/a-box>\n        &lt;a-box position=\"0.17 0.44 -0.18\" width=\"0.26\" height=\"0.14\" depth=\"0.14\"\n               material=\"color:#78f0ff; emissive:#2dd; emissiveIntensity:0.20; metalness:0.3; roughness:0.35; opacity:0.55; transparent:true\">&lt;\/a-box>\n\n        &lt;!-- \u8170 -->\n        &lt;a-box position=\"0 0.92 0.00\" width=\"0.72\" height=\"0.14\" depth=\"0.40\"\n               material=\"color:#15151a; roughness:1\">&lt;\/a-box>\n        &lt;a-box position=\"0 0.92 0.23\" width=\"0.16\" height=\"0.12\" depth=\"0.06\"\n               material=\"color:#ad7b2e; roughness:0.75; metalness:0.25\">&lt;\/a-box>\n\n        &lt;!-- \u8170\u5e03 -->\n        &lt;a-plane width=\"0.42\" height=\"0.58\" position=\"0 0.64 0.20\"\n                 material=\"color:#152a52; opacity:0.92; transparent:true; side:double\">&lt;\/a-plane>\n        &lt;a-plane width=\"0.35\" height=\"0.36\" position=\"0 0.54 -0.22\" rotation=\"0 180 0\"\n                 material=\"color:#0f1733; opacity:0.85; transparent:true; side:double\">&lt;\/a-plane>\n\n        &lt;!-- \u80f8\u93a7 -->\n        &lt;a-box position=\"0 1.22 0\" width=\"0.74\" height=\"0.82\" depth=\"0.42\"\n               material=\"color:#3b6b8e; metalness:0.38; roughness:0.22\">&lt;\/a-box>\n\n        &lt;!-- \u30b3\u30a2 -->\n        &lt;a-box position=\"0 1.22 0.24\" width=\"0.60\" height=\"0.66\" depth=\"0.06\"\n               material=\"color:#78f0ff; emissive:#2dd; emissiveIntensity:0.30; metalness:0.25; roughness:0.18; opacity:0.55; transparent:true\">&lt;\/a-box>\n        &lt;a-ring position=\"0 1.22 0.27\" radius-inner=\"0.12\" radius-outer=\"0.20\"\n                material=\"color:#78f0ff; emissive:#2dd; emissiveIntensity:0.35; opacity:0.45; transparent:true\">&lt;\/a-ring>\n\n        &lt;!-- \u80a9\u5f53\u3066 -->\n        &lt;a-sphere position=\"-0.50 1.54 0.02\" radius=\"0.22\"\n                  material=\"color:#2f4f6a; metalness:0.35; roughness:0.22\">&lt;\/a-sphere>\n        &lt;a-sphere position=\"0.50 1.54 0.02\" radius=\"0.22\"\n                  material=\"color:#2f4f6a; metalness:0.35; roughness:0.22\">&lt;\/a-sphere>\n        &lt;a-cone position=\"-0.58 1.58 0.02\" radius-bottom=\"0.10\" height=\"0.22\" rotation=\"0 0 25\"\n                material=\"color:#cbd3da; metalness:0.55; roughness:0.25\">&lt;\/a-cone>\n        &lt;a-cone position=\"0.58 1.58 0.02\" radius-bottom=\"0.10\" height=\"0.22\" rotation=\"0 0 -25\"\n                material=\"color:#cbd3da; metalness:0.55; roughness:0.25\">&lt;\/a-cone>\n\n        &lt;!-- \u8155 -->\n        &lt;a-box position=\"-0.62 1.18 0.02\" width=\"0.20\" height=\"0.68\" depth=\"0.24\"\n               material=\"color:#2b3140; metalness:0.25; roughness:0.55\">&lt;\/a-box>\n        &lt;a-box position=\"0.62 1.18 0.02\" width=\"0.20\" height=\"0.68\" depth=\"0.24\"\n               material=\"color:#2b3140; metalness:0.25; roughness:0.55\">&lt;\/a-box>\n        &lt;a-sphere position=\"-0.62 0.84 0.02\" radius=\"0.10\" material=\"color:#1a1418; roughness:1\">&lt;\/a-sphere>\n        &lt;a-sphere position=\"0.62 0.84 0.02\" radius=\"0.10\" material=\"color:#1a1418; roughness:1\">&lt;\/a-sphere>\n\n        &lt;!-- \u895f -->\n        &lt;a-torus radius=\"0.24\" tube=\"0.06\" position=\"0 1.58 0.02\" rotation=\"90 0 0\"\n                 material=\"color:#0b1020; roughness:1; opacity:0.96; transparent:true\">&lt;\/a-torus>\n\n        &lt;!-- \u982d -->\n        &lt;a-entity id=\"headGroup\" position=\"0 1.78 0\">\n          &lt;a-sphere id=\"heroHead\" position=\"0 0 0\" radius=\"0.22\" material=\"color:#f4d7bd; roughness:0.95\">&lt;\/a-sphere>\n          &lt;a-sphere position=\"0 0.05 -0.02\" radius=\"0.24\" material=\"color:#1b1b1f; roughness:0.9; metalness:0.15\">&lt;\/a-sphere>\n          &lt;a-box position=\"0 -0.02 -0.18\" width=\"0.32\" height=\"0.18\" depth=\"0.10\"\n                 material=\"color:#0f0f12; roughness:1\">&lt;\/a-box>\n          &lt;a-box position=\"0 0.00 -0.24\" width=\"0.36\" height=\"0.10\" depth=\"0.06\"\n                 material=\"color:#78f0ff; emissive:#2dd; emissiveIntensity:0.40; opacity:0.55; transparent:true\">&lt;\/a-box>\n          &lt;a-cone position=\"-0.16 0.20 -0.02\" radius-bottom=\"0.06\" height=\"0.18\" rotation=\"0 0 25\"\n                  material=\"color:#cbd3da; metalness:0.55; roughness:0.25\">&lt;\/a-cone>\n          &lt;a-cone position=\"0.16 0.20 -0.02\" radius-bottom=\"0.06\" height=\"0.18\" rotation=\"0 0 -25\"\n                  material=\"color:#cbd3da; metalness:0.55; roughness:0.25\">&lt;\/a-cone>\n        &lt;\/a-entity>\n\n        &lt;!-- \u5263 -->\n        &lt;a-entity id=\"sword\" position=\"0.40 1.02 0.10\" rotation=\"0 0 18\">\n          &lt;a-box width=\"0.05\" height=\"0.86\" depth=\"0.06\" position=\"0 0.42 0\"\n                 material=\"color:#cbd3da; metalness:0.78; roughness:0.18\">&lt;\/a-box>\n          &lt;a-box width=\"0.02\" height=\"0.84\" depth=\"0.02\" position=\"0 0.42 -0.03\"\n                 material=\"color:#ffffff; opacity:0.18; transparent:true\">&lt;\/a-box>\n          &lt;a-box width=\"0.20\" height=\"0.05\" depth=\"0.12\" position=\"0 0.04 0\"\n                 material=\"color:#ad7b2e; metalness:0.35; roughness:0.55\">&lt;\/a-box>\n          &lt;a-torus radius=\"0.09\" tube=\"0.012\" position=\"0 0.04 0.07\" rotation=\"90 0 0\"\n                   material=\"color:#78f0ff; emissive:#2dd; emissiveIntensity:0.30; opacity:0.45; transparent:true\">&lt;\/a-torus>\n          &lt;a-box width=\"0.07\" height=\"0.18\" depth=\"0.07\" position=\"0 -0.08 0\"\n                 material=\"color:#2b1c12; roughness:1\">&lt;\/a-box>\n          &lt;a-sphere radius=\"0.03\" position=\"0 -0.18 0\"\n                    material=\"color:#78f0ff; emissive:#2dd; emissiveIntensity:0.35; opacity:0.6; transparent:true\">&lt;\/a-sphere>\n        &lt;\/a-entity>\n\n        &lt;!-- \u76fe -->\n        &lt;a-entity id=\"shield\" position=\"-0.70 1.06 -0.06\" rotation=\"0 0 12\">\n          &lt;a-cylinder radius=\"0.24\" height=\"0.09\" rotation=\"90 0 0\"\n                      material=\"color:#3a5f7a; metalness:0.28; roughness:0.32\">&lt;\/a-cylinder>\n          &lt;a-ring radius-inner=\"0.13\" radius-outer=\"0.24\" rotation=\"90 0 0\"\n                  material=\"color:#78f0ff; emissive:#2dd; emissiveIntensity:0.25; opacity:0.45; transparent:true\">&lt;\/a-ring>\n          &lt;a-circle radius=\"0.07\" rotation=\"90 0 0\" position=\"0 0 0.05\"\n                    material=\"color:#ad7b2e; metalness:0.35; roughness:0.55\">&lt;\/a-circle>\n        &lt;\/a-entity>\n\n        &lt;!-- \u540d\u524d -->\n        &lt;a-text id=\"name3d\" value=\"YOU\" position=\"0 2.35 0\" align=\"center\" width=\"4\" color=\"#ffffff\"\n                shader=\"msdf\" font=\"https:\/\/cdn.aframe.io\/fonts\/Roboto-msdf.json\">&lt;\/a-text>\n      &lt;\/a-entity>\n\n      &lt;a-camera id=\"cam\"\n        position=\"0 1.75 3.4\"\n        look-controls=\"pointerLockEnabled: false\"\n        wasd-controls-enabled=\"false\"\n        fov=\"72\"\n      >&lt;\/a-camera>\n\n      &lt;a-entity id=\"rightHand\" laser-controls=\"hand:right\" raycaster=\"objects: .vrbtn\" line=\"opacity:0.75\">&lt;\/a-entity>\n      &lt;a-entity id=\"leftHand\"  laser-controls=\"hand:left\"  raycaster=\"objects: .vrbtn\" line=\"opacity:0.75\">&lt;\/a-entity>\n      &lt;a-entity id=\"mouseCursor\" cursor=\"rayOrigin: mouse\" raycaster=\"objects: .vrbtn\">&lt;\/a-entity>\n\n      &lt;!-- VR UI -->\n      &lt;a-entity id=\"vrUI\" position=\"0 1.55 -1.25\" visible=\"false\">\n        &lt;a-plane width=\"1.55\" height=\"0.92\" material=\"color:#0b0f14; opacity:0.78; transparent:true\">&lt;\/a-plane>\n        &lt;a-text value=\"VRUI\" position=\"0 0.40 0.01\" align=\"center\" width=\"2.6\" color=\"#7ff\"\n                shader=\"msdf\" font=\"https:\/\/cdn.aframe.io\/fonts\/Roboto-msdf.json\">&lt;\/a-text>\n\n        &lt;a-entity position=\"0 0.12 0.02\">\n          &lt;a-plane class=\"vrbtn\" vr-btn=\"action:fieldTown\"  position=\"-0.48 0.12 0\" width=\"0.48\" height=\"0.16\" material=\"color:#13202b; opacity:0.95\">&lt;\/a-plane>\n          &lt;a-text value=\"\u8857\" position=\"-0.48 0.12 0.02\" align=\"center\" width=\"1.6\" color=\"#fff\" shader=\"msdf\" font=\"https:\/\/cdn.aframe.io\/fonts\/Roboto-msdf.json\">&lt;\/a-text>\n\n          &lt;a-plane class=\"vrbtn\" vr-btn=\"action:fieldCastle\" position=\"0.48 0.12 0\" width=\"0.48\" height=\"0.16\" material=\"color:#13202b; opacity:0.95\">&lt;\/a-plane>\n          &lt;a-text value=\"\u57ce\" position=\"0.48 0.12 0.02\" align=\"center\" width=\"1.6\" color=\"#fff\" shader=\"msdf\" font=\"https:\/\/cdn.aframe.io\/fonts\/Roboto-msdf.json\">&lt;\/a-text>\n\n          &lt;a-plane class=\"vrbtn\" vr-btn=\"action:fieldCave\" position=\"-0.48 -0.08 0\" width=\"0.48\" height=\"0.16\" material=\"color:#13202b; opacity:0.95\">&lt;\/a-plane>\n          &lt;a-text value=\"\u6d1e\u7a9f\" position=\"-0.48 -0.08 0.02\" align=\"center\" width=\"1.6\" color=\"#fff\" shader=\"msdf\" font=\"https:\/\/cdn.aframe.io\/fonts\/Roboto-msdf.json\">&lt;\/a-text>\n\n          &lt;a-plane class=\"vrbtn\" vr-btn=\"action:fieldRuins\" position=\"0.48 -0.08 0\" width=\"0.48\" height=\"0.16\" material=\"color:#13202b; opacity:0.95\">&lt;\/a-plane>\n          &lt;a-text value=\"\u907a\u8de1\" position=\"0.48 -0.08 0.02\" align=\"center\" width=\"1.6\" color=\"#fff\" shader=\"msdf\" font=\"https:\/\/cdn.aframe.io\/fonts\/Roboto-msdf.json\">&lt;\/a-text>\n\n          &lt;a-plane class=\"vrbtn\" vr-btn=\"action:talk\" position=\"-0.48 -0.30 0\" width=\"0.48\" height=\"0.16\" material=\"color:#10261e; opacity:0.95\">&lt;\/a-plane>\n          &lt;a-text value=\"\u8a71\u3059\" position=\"-0.48 -0.30 0.02\" align=\"center\" width=\"1.6\" color=\"#fff\" shader=\"msdf\" font=\"https:\/\/cdn.aframe.io\/fonts\/Roboto-msdf.json\">&lt;\/a-text>\n\n          &lt;a-plane class=\"vrbtn\" vr-btn=\"action:quest\" position=\"0.48 -0.30 0\" width=\"0.48\" height=\"0.16\" material=\"color:#2a2110; opacity:0.95\">&lt;\/a-plane>\n          &lt;a-text value=\"\u30af\u30a8\u30b9\u30c8\" position=\"0.48 -0.30 0.02\" align=\"center\" width=\"1.6\" color=\"#fff\" shader=\"msdf\" font=\"https:\/\/cdn.aframe.io\/fonts\/Roboto-msdf.json\">&lt;\/a-text>\n        &lt;\/a-entity>\n\n        &lt;a-text value=\"\u30b9\u30c6\u30a3\u30c3\u30af\u79fb\u52d5 \/ \u30c8\u30ea\u30ac\u30fc\u3067\u62bc\u3059\" position=\"0 -0.43 0.01\" align=\"center\" width=\"2.8\" color=\"#bfefff\"\n                shader=\"msdf\" font=\"https:\/\/cdn.aframe.io\/fonts\/Roboto-msdf.json\">&lt;\/a-text>\n      &lt;\/a-entity>\n    &lt;\/a-entity>\n\n    &lt;!-- NPC\uff08\u2605snap \u3067\u201c\u305d\u306e\u5834\u6240\u306e\u5730\u9762\u201d\u306b\u81ea\u52d5\u88dc\u6b63 \u2192 \u57cb\u307e\u308a\u30bc\u30ed\uff09 -->\n    &lt;a-entity id=\"npcGroup\">\n      &lt;a-entity id=\"npcGuide\" class=\"npc snap\" position=\"-6 1.15 10\" rotation=\"0 25 0\">\n        &lt;a-cylinder radius=\"0.35\" height=\"1.2\" material=\"color:#203a4a; roughness:0.9\">&lt;\/a-cylinder>\n        &lt;a-sphere radius=\"0.22\" position=\"0 0.86 0\" material=\"color:#f2d7bf; roughness:0.95\">&lt;\/a-sphere>\n        &lt;a-cone radius-bottom=\"0.28\" height=\"0.35\" position=\"0 1.12 0\" material=\"color:#0a0f18; roughness:1\">&lt;\/a-cone>\n        &lt;a-text value=\"Guide\" position=\"0 1.45 0\" align=\"center\" width=\"4\" color=\"#fff\" shader=\"msdf\" font=\"https:\/\/cdn.aframe.io\/fonts\/Roboto-msdf.json\">&lt;\/a-text>\n      &lt;\/a-entity>\n\n      &lt;a-entity id=\"npcKnight\" class=\"npc snap\" position=\"10 1.15 0\" rotation=\"0 -120 0\" visible=\"false\">\n        &lt;a-cylinder radius=\"0.36\" height=\"1.2\" material=\"color:#3a4652; metalness:0.25; roughness:0.35\">&lt;\/a-cylinder>\n        &lt;a-sphere radius=\"0.22\" position=\"0 0.86 0\" material=\"color:#f2d7bf; roughness:0.95\">&lt;\/a-sphere>\n        &lt;a-box width=\"0.48\" height=\"0.16\" depth=\"0.06\" position=\"0 0.58 0.2\" material=\"color:#78f0ff; opacity:0.5; transparent:true\">&lt;\/a-box>\n        &lt;a-text value=\"Castle Knight\" position=\"0 1.45 0\" align=\"center\" width=\"4\" color=\"#fff\" shader=\"msdf\" font=\"https:\/\/cdn.aframe.io\/fonts\/Roboto-msdf.json\">&lt;\/a-text>\n      &lt;\/a-entity>\n\n      &lt;a-entity id=\"npcMiner\" class=\"npc snap\" position=\"-10 1.15 -8\" rotation=\"0 60 0\" visible=\"false\">\n        &lt;a-cylinder radius=\"0.35\" height=\"1.2\" material=\"color:#3b2f23; roughness:0.95\">&lt;\/a-cylinder>\n        &lt;a-sphere radius=\"0.22\" position=\"0 0.86 0\" material=\"color:#f2d7bf; roughness:0.95\">&lt;\/a-sphere>\n        &lt;a-sphere radius=\"0.18\" position=\"0 1.06 0\" material=\"color:#2d2d2f; roughness:1\">&lt;\/a-sphere>\n        &lt;a-text value=\"Miner\" position=\"0 1.45 0\" align=\"center\" width=\"4\" color=\"#fff\" shader=\"msdf\" font=\"https:\/\/cdn.aframe.io\/fonts\/Roboto-msdf.json\">&lt;\/a-text>\n      &lt;\/a-entity>\n\n      &lt;a-entity id=\"npcSage\" class=\"npc snap\" position=\"6 1.15 -12\" rotation=\"0 -30 0\" visible=\"false\">\n        &lt;a-cylinder radius=\"0.35\" height=\"1.2\" material=\"color:#2a1f2f; roughness:0.95\">&lt;\/a-cylinder>\n        &lt;a-sphere radius=\"0.22\" position=\"0 0.86 0\" material=\"color:#f2d7bf; roughness:0.95\">&lt;\/a-sphere>\n        &lt;a-torus radius=\"0.34\" tube=\"0.05\" position=\"0 0.95 0\" rotation=\"90 0 0\" material=\"color:#7ff; opacity:0.35; transparent:true\">&lt;\/a-torus>\n        &lt;a-text value=\"Ruins Sage\" position=\"0 1.45 0\" align=\"center\" width=\"4\" color=\"#fff\" shader=\"msdf\" font=\"https:\/\/cdn.aframe.io\/fonts\/Roboto-msdf.json\">&lt;\/a-text>\n      &lt;\/a-entity>\n    &lt;\/a-entity>\n\n    &lt;!-- Enemy -->\n    &lt;a-entity id=\"enemy\" position=\"0 1.10 -2\" visible=\"true\">\n      &lt;a-entity id=\"enemyModel\">\n        &lt;a-sphere radius=\"0.55\" material=\"color:#8a1b2d; metalness:0.15; roughness:0.45; emissive:#200;\">&lt;\/a-sphere>\n        &lt;a-sphere radius=\"0.22\" position=\"0 0.52 0.06\" material=\"color:#2a0b10; roughness:0.9\">&lt;\/a-sphere>\n        &lt;a-cone radius-bottom=\"0.16\" height=\"0.35\" position=\"-0.22 0.78 0.02\" rotation=\"20 0 40\" material=\"color:#ddd; roughness:0.7\">&lt;\/a-cone>\n        &lt;a-cone radius-bottom=\"0.16\" height=\"0.35\" position=\"0.22 0.78 0.02\" rotation=\"20 0 -40\" material=\"color:#ddd; roughness:0.7\">&lt;\/a-cone>\n        &lt;a-sphere radius=\"0.06\" position=\"-0.14 0.55 -0.46\" material=\"color:#fff; emissive:#f0f; emissiveIntensity:0.9\">&lt;\/a-sphere>\n        &lt;a-sphere radius=\"0.06\" position=\"0.14 0.55 -0.46\" material=\"color:#fff; emissive:#f0f; emissiveIntensity:0.9\">&lt;\/a-sphere>\n        &lt;a-ring radius-inner=\"0.62\" radius-outer=\"0.74\" rotation=\"-90 0 0\" position=\"0 -0.35 0\"\n                material=\"color:#7ff; opacity:0.14; transparent:true\">&lt;\/a-ring>\n      &lt;\/a-entity>\n      &lt;a-text id=\"enemyName3D\" value=\"Enemy\" position=\"0 1.25 0\" align=\"center\" width=\"4\" color=\"#fff\"\n              shader=\"msdf\" font=\"https:\/\/cdn.aframe.io\/fonts\/Roboto-msdf.json\">&lt;\/a-text>\n    &lt;\/a-entity>\n\n    &lt;!-- Fields -->\n    &lt;a-entity id=\"field-town\" visible=\"true\">\n      &lt;!-- \u5674\u6c34\uff08snap\u3067\u5730\u9762\u88dc\u6b63\uff09 -->\n      &lt;a-entity id=\"fountain\" class=\"snap\" position=\"0 0 0\">\n        &lt;a-cylinder radius=\"2.1\" height=\"0.35\" position=\"0 0.725 0\"\n                    material=\"color:#55606a; roughness:0.55; metalness:0.1\">&lt;\/a-cylinder>\n        &lt;a-cylinder radius=\"1.35\" height=\"0.42\" position=\"0 1.11 0\"\n                    material=\"color:#3f4a54; roughness:0.55; metalness:0.12\">&lt;\/a-cylinder>\n        &lt;a-cylinder radius=\"0.25\" height=\"1.0\" position=\"0 1.82 0\"\n                    material=\"color:#6b7782; roughness:0.5\">&lt;\/a-cylinder>\n        &lt;a-sphere radius=\"0.26\" position=\"0 2.42 0\"\n                  material=\"color:#7ff; opacity:0.5; transparent:true; emissive:#2dd; emissiveIntensity:0.25\">&lt;\/a-sphere>\n        &lt;a-torus radius=\"0.95\" tube=\"0.06\" position=\"0 0.90 0\" rotation=\"90 0 0\"\n                 material=\"color:#7ff; opacity:0.25; transparent:true\">&lt;\/a-torus>\n      &lt;\/a-entity>\n\n      &lt;!-- \u5bb6\uff08\u5404\u5bb6\u3092snap\u3067\u5730\u9762\u88dc\u6b63\uff09 -->\n      &lt;a-entity id=\"houses\">\n        &lt;a-entity class=\"snap\" position=\"-10 1.70 6\" rotation=\"0 35 0\">\n          &lt;a-box width=\"4\" height=\"2.3\" depth=\"3.2\" material=\"color:#bda982; roughness:0.9\">&lt;\/a-box>\n          &lt;a-cone radius-bottom=\"2.8\" height=\"1.4\" position=\"0 1.85 0\" material=\"color:#5a2c1b; roughness:1\">&lt;\/a-cone>\n          &lt;a-plane width=\"1.2\" height=\"0.7\" position=\"0 0.6 1.61\" material=\"color:#1b2a35; opacity:0.55; transparent:true\">&lt;\/a-plane>\n        &lt;\/a-entity>\n\n        &lt;a-entity class=\"snap\" position=\"10 1.60 8\" rotation=\"0 -20 0\">\n          &lt;a-box width=\"3.2\" height=\"2.1\" depth=\"3.0\" material=\"color:#c2b08a; roughness:0.9\">&lt;\/a-box>\n          &lt;a-cone radius-bottom=\"2.2\" height=\"1.3\" position=\"0 1.7 0\" material=\"color:#6a3a22; roughness:1\">&lt;\/a-cone>\n          &lt;a-plane width=\"1.0\" height=\"0.65\" position=\"0.2 0.5 1.51\" material=\"color:#1b2a35; opacity:0.55; transparent:true\">&lt;\/a-plane>\n        &lt;\/a-entity>\n\n        &lt;a-entity class=\"snap\" position=\"-14 1.55 -6\" rotation=\"0 70 0\">\n          &lt;a-box width=\"3.6\" height=\"2.0\" depth=\"2.6\" material=\"color:#b8a27a; roughness:0.9\">&lt;\/a-box>\n          &lt;a-cone radius-bottom=\"2.4\" height=\"1.2\" position=\"0 1.6 0\" material=\"color:#4f2a1a; roughness:1\">&lt;\/a-cone>\n        &lt;\/a-entity>\n\n        &lt;a-entity class=\"snap\" position=\"13 1.65 -6\" rotation=\"0 -55 0\">\n          &lt;a-box width=\"4.2\" height=\"2.2\" depth=\"3.2\" material=\"color:#b5a07a; roughness:0.95\">&lt;\/a-box>\n          &lt;a-cone radius-bottom=\"2.9\" height=\"1.3\" position=\"0 1.75 0\" material=\"color:#2b1c12; roughness:1\">&lt;\/a-cone>\n          &lt;a-plane width=\"2.2\" height=\"0.7\" position=\"0 0.6 1.61\" material=\"color:#0b0f14; opacity:0.65; transparent:true\">&lt;\/a-plane>\n          &lt;a-text value=\"SHOP\" position=\"0 1.1 1.65\" align=\"center\" width=\"4\" color=\"#7ff\"\n                  shader=\"msdf\" font=\"https:\/\/cdn.aframe.io\/fonts\/Roboto-msdf.json\">&lt;\/a-text>\n        &lt;\/a-entity>\n      &lt;\/a-entity>\n\n      &lt;!-- \u5c4b\u53f0\uff08snap\u3067\u5730\u9762\u88dc\u6b63\uff09 -->\n      &lt;a-entity class=\"snap\" position=\"-6 0.55 -4\" rotation=\"0 15 0\">\n        &lt;a-box width=\"2.2\" height=\"0.5\" depth=\"1.2\" position=\"0 0.7 0\" material=\"color:#6a3a22; roughness:1\">&lt;\/a-box>\n        &lt;a-plane width=\"2.4\" height=\"1.2\" position=\"0 1.35 0\" rotation=\"-30 0 0\" material=\"color:#7ff; opacity:0.2; transparent:true\">&lt;\/a-plane>\n        &lt;a-cylinder radius=\"0.05\" height=\"1.4\" position=\"-1.05 0.7 -0.55\" material=\"color:#3b2f23\">&lt;\/a-cylinder>\n        &lt;a-cylinder radius=\"0.05\" height=\"1.4\" position=\"1.05 0.7 -0.55\" material=\"color:#3b2f23\">&lt;\/a-cylinder>\n      &lt;\/a-entity>\n\n      &lt;!-- \u6728\uff06\u8857\u706f\uff08snap\u3067\u5730\u9762\u88dc\u6b63\uff09 -->\n      &lt;a-entity>\n        &lt;a-entity class=\"snap\" position=\"-18 1.85 2\">\n          &lt;a-cylinder radius=\"0.18\" height=\"2.6\" material=\"color:#3b2f23; roughness:1\">&lt;\/a-cylinder>\n          &lt;a-sphere radius=\"1.2\" position=\"0 2.0 0\" material=\"color:#2a7a45; roughness:1\">&lt;\/a-sphere>\n        &lt;\/a-entity>\n\n        &lt;a-entity class=\"snap\" position=\"18 1.85 4\">\n          &lt;a-cylinder radius=\"0.18\" height=\"2.6\" material=\"color:#3b2f23; roughness:1\">&lt;\/a-cylinder>\n          &lt;a-sphere radius=\"1.2\" position=\"0 2.0 0\" material=\"color:#2a7a45; roughness:1\">&lt;\/a-sphere>\n        &lt;\/a-entity>\n\n        &lt;a-entity class=\"snap\" position=\"6 1.60 14\">\n          &lt;a-cylinder radius=\"0.06\" height=\"2.1\" material=\"color:#45515a; roughness:0.6\">&lt;\/a-cylinder>\n          &lt;a-sphere radius=\"0.18\" position=\"0 1.08 0\" material=\"color:#fff; emissive:#7ff; emissiveIntensity:0.65; opacity:0.85; transparent:true\">&lt;\/a-sphere>\n        &lt;\/a-entity>\n      &lt;\/a-entity>\n    &lt;\/a-entity>\n\n    &lt;a-entity id=\"field-castle\" visible=\"false\">\n      &lt;a-ring position=\"0 0.43 0\" radius-inner=\"0\" radius-outer=\"30\" rotation=\"-90 0 0\"\n              material=\"color:#636b75; roughness:0.9; opacity:0.9; transparent:true\">&lt;\/a-ring>\n\n      &lt;a-entity position=\"0 0.75 -18\">\n        &lt;a-box width=\"26\" height=\"6\" depth=\"2.8\" material=\"color:#a8b1bb; roughness:0.65; metalness:0.05\">&lt;\/a-box>\n        &lt;a-box width=\"7\" height=\"4\" depth=\"2.2\" position=\"0 -0.4 1.1\" material=\"color:#8a939e; roughness:0.65\">&lt;\/a-box>\n        &lt;a-box width=\"5.2\" height=\"4.2\" depth=\"0.8\" position=\"0 -0.9 1.8\" material=\"color:#2b1c12; roughness:1\">&lt;\/a-box>\n        &lt;a-plane width=\"1.2\" height=\"2.6\" position=\"-4 0.6 1.9\" material=\"color:#7ff; opacity:0.25; transparent:true\">&lt;\/a-plane>\n        &lt;a-plane width=\"1.2\" height=\"2.6\" position=\"4 0.6 1.9\" material=\"color:#7ff; opacity:0.25; transparent:true\">&lt;\/a-plane>\n      &lt;\/a-entity>\n\n      &lt;a-entity>\n        &lt;a-entity position=\"-12 1.2 -18\">\n          &lt;a-cylinder radius=\"2.1\" height=\"8.2\" material=\"color:#9aa3ad; roughness:0.55; metalness:0.05\">&lt;\/a-cylinder>\n          &lt;a-cone radius-bottom=\"2.3\" height=\"2.4\" position=\"0 5.2 0\" material=\"color:#6a3a22; roughness:1\">&lt;\/a-cone>\n        &lt;\/a-entity>\n        &lt;a-entity position=\"12 1.2 -18\">\n          &lt;a-cylinder radius=\"2.1\" height=\"8.2\" material=\"color:#9aa3ad; roughness:0.55; metalness:0.05\">&lt;\/a-cylinder>\n          &lt;a-cone radius-bottom=\"2.3\" height=\"2.4\" position=\"0 5.2 0\" material=\"color:#6a3a22; roughness:1\">&lt;\/a-cone>\n        &lt;\/a-entity>\n      &lt;\/a-entity>\n\n      &lt;a-ring position=\"0 0.18 -12\" radius-inner=\"18\" radius-outer=\"28\" rotation=\"-90 0 0\"\n              material=\"color:#0b3143; opacity:0.55; transparent:true\">&lt;\/a-ring>\n\n      &lt;a-entity position=\"0 0.55 -6\">\n        &lt;a-cylinder radius=\"1.4\" height=\"0.6\" material=\"color:#4a535c; roughness:0.65\">&lt;\/a-cylinder>\n        &lt;a-sphere radius=\"0.75\" position=\"0 1.0 0\" material=\"color:#a8b1bb; roughness:0.5\">&lt;\/a-sphere>\n        &lt;a-torus-knot radius=\"0.35\" tube=\"0.08\" position=\"0 1.8 0\" p=\"2\" q=\"5\"\n                      material=\"color:#7ff; emissive:#2dd; emissiveIntensity:0.25; opacity:0.5; transparent:true\">&lt;\/a-torus-knot>\n      &lt;\/a-entity>\n    &lt;\/a-entity>\n\n    &lt;a-entity id=\"field-cave\" visible=\"false\">\n      &lt;a-entity position=\"0 0.55 -6\">\n        &lt;a-sphere radius=\"10\" material=\"color:#0b0f14; opacity:0.22; transparent:true\" segments-width=\"18\" segments-height=\"12\">&lt;\/a-sphere>\n      &lt;\/a-entity>\n\n      &lt;a-entity position=\"0 0.55 -16\">\n        &lt;a-torus radius=\"8\" tube=\"2.2\" arc=\"200\" rotation=\"0 0 90\"\n                 material=\"color:#4a3f34; roughness:1; metalness:0\">&lt;\/a-torus>\n      &lt;\/a-entity>\n\n      &lt;a-entity id=\"rocks\">\n        &lt;a-sphere radius=\"5\" position=\"-12 2 -14\" material=\"color:#3a332d; roughness:1\">&lt;\/a-sphere>\n        &lt;a-sphere radius=\"6\" position=\"12 1 -16\" material=\"color:#352f2a; roughness:1\">&lt;\/a-sphere>\n        &lt;a-sphere radius=\"4.5\" position=\"0 3 -22\" material=\"color:#2f2a25; roughness:1\">&lt;\/a-sphere>\n      &lt;\/a-entity>\n\n      &lt;a-entity>\n        &lt;a-cone radius-bottom=\"0.8\" height=\"2.8\" position=\"-4 6 -14\" material=\"color:#2f2a25; roughness:1\">&lt;\/a-cone>\n        &lt;a-cone radius-bottom=\"0.6\" height=\"2.2\" position=\"3 5.7 -16\" material=\"color:#2f2a25; roughness:1\">&lt;\/a-cone>\n        &lt;a-cone radius-bottom=\"0.7\" height=\"2.5\" position=\"8 6.2 -12\" material=\"color:#2f2a25; roughness:1\">&lt;\/a-cone>\n      &lt;\/a-entity>\n\n      &lt;a-entity position=\"-6 0.55 -10\">\n        &lt;a-octahedron radius=\"0.9\" material=\"color:#7ff; opacity:0.55; transparent:true; emissive:#2dd; emissiveIntensity:0.35\">&lt;\/a-octahedron>\n        &lt;a-octahedron radius=\"0.6\" position=\"1.0 0.2 0.3\" material=\"color:#8cf; opacity:0.55; transparent:true; emissive:#2dd; emissiveIntensity:0.25\">&lt;\/a-octahedron>\n        &lt;a-light type=\"point\" intensity=\"0.8\" distance=\"10\" color=\"#7ff\">&lt;\/a-light>\n      &lt;\/a-entity>\n    &lt;\/a-entity>\n\n    &lt;a-entity id=\"field-ruins\" visible=\"false\">\n      &lt;a-ring position=\"0 0.43 0\" radius-inner=\"0\" radius-outer=\"30\" rotation=\"-90 0 0\"\n              material=\"color:#6a6555; roughness:0.95; opacity:0.92; transparent:true\">&lt;\/a-ring>\n\n      &lt;a-entity>\n        &lt;a-entity position=\"-12 0.55 -8\">\n          &lt;a-cylinder radius=\"0.8\" height=\"3.2\" material=\"color:#c9c2a3; roughness:0.9\">&lt;\/a-cylinder>\n          &lt;a-box width=\"2.2\" height=\"0.35\" depth=\"2.2\" position=\"0 1.85 0\" material=\"color:#bdb493; roughness:0.95\">&lt;\/a-box>\n        &lt;\/a-entity>\n        &lt;a-entity position=\"12 0.55 -8\">\n          &lt;a-cylinder radius=\"0.8\" height=\"2.1\" material=\"color:#c9c2a3; roughness:0.9\">&lt;\/a-cylinder>\n          &lt;a-box width=\"2.2\" height=\"0.35\" depth=\"2.2\" position=\"0 1.25 0\" material=\"color:#bdb493; roughness:0.95\">&lt;\/a-box>\n        &lt;\/a-entity>\n        &lt;a-entity position=\"-8 0.55 -18\" rotation=\"0 20 0\">\n          &lt;a-cylinder radius=\"0.7\" height=\"2.4\" material=\"color:#bdb493; roughness:0.95\">&lt;\/a-cylinder>\n          &lt;a-box width=\"1.9\" height=\"0.28\" depth=\"1.9\" position=\"0 1.38 0\" material=\"color:#c9c2a3; roughness:0.95\">&lt;\/a-box>\n        &lt;\/a-entity>\n        &lt;a-entity position=\"8 0.55 -18\" rotation=\"0 -20 0\">\n          &lt;a-cylinder radius=\"0.7\" height=\"3.0\" material=\"color:#bdb493; roughness:0.95\">&lt;\/a-cylinder>\n          &lt;a-box width=\"1.9\" height=\"0.28\" depth=\"1.9\" position=\"0 1.68 0\" material=\"color:#c9c2a3; roughness:0.95\">&lt;\/a-box>\n        &lt;\/a-entity>\n      &lt;\/a-entity>\n\n      &lt;a-entity position=\"0 2.0 -16\">\n        &lt;a-torus radius=\"4.0\" tube=\"0.55\" arc=\"180\" rotation=\"0 0 90\" material=\"color:#c9c2a3; roughness:0.9\">&lt;\/a-torus>\n      &lt;\/a-entity>\n\n      &lt;a-entity position=\"0 0.55 -8\">\n        &lt;a-box width=\"4.2\" height=\"0.8\" depth=\"2.6\" material=\"color:#5a5648; roughness:0.95\">&lt;\/a-box>\n        &lt;a-ring radius-inner=\"0.9\" radius-outer=\"1.5\" rotation=\"-90 0 0\" position=\"0 0.41 0\"\n                material=\"color:#7ff; opacity:0.35; transparent:true; emissive:#2dd; emissiveIntensity:0.25\">&lt;\/a-ring>\n        &lt;a-light type=\"point\" intensity=\"0.9\" distance=\"14\" color=\"#7ff\" position=\"0 1.3 0\">&lt;\/a-light>\n      &lt;\/a-entity>\n\n      &lt;a-entity id=\"floating\" position=\"0 2.2 -10\">\n        &lt;a-box width=\"0.6\" height=\"0.35\" depth=\"0.6\" position=\"-1.2 0.3 0\" material=\"color:#c9c2a3; roughness:0.9\">&lt;\/a-box>\n        &lt;a-box width=\"0.4\" height=\"0.25\" depth=\"0.4\" position=\"1.0 -0.1 0.5\" material=\"color:#bdb493; roughness:0.9\">&lt;\/a-box>\n        &lt;a-box width=\"0.5\" height=\"0.3\" depth=\"0.5\" position=\"0.2 0.5 -0.7\" material=\"color:#c9c2a3; roughness:0.9\">&lt;\/a-box>\n      &lt;\/a-entity>\n    &lt;\/a-entity>\n\n    &lt;a-entity id=\"confetti\" visible=\"false\" position=\"0 2.4 10\">\n      &lt;a-ring radius-inner=\"0.2\" radius-outer=\"0.6\" rotation=\"-90 0 0\" material=\"color:#7ff; opacity:0.35; transparent:true\">&lt;\/a-ring>\n      &lt;a-ring radius-inner=\"0.6\" radius-outer=\"1.0\" rotation=\"-90 0 0\" material=\"color:#fff; opacity:0.18; transparent:true\">&lt;\/a-ring>\n    &lt;\/a-entity>\n  &lt;\/a-scene>\n\n&lt;script>\n\/* 3D VR UI \u30dc\u30bf\u30f3 *\/\nAFRAME.registerComponent('vr-btn', {\n  schema: { action: { type:'string' } },\n  init: function(){\n    this.el.addEventListener('click', () => {\n      const fn = window&#91;this.data.action];\n      if(typeof fn === 'function') fn();\n    });\n  }\n});\n\n\/* ===== \u72b6\u614b ===== *\/\nconst state = {\n  field: \"town\",\n  hp: 100,\n  mana: 100,\n  level: 1,\n  exp: 0,\n  expNeed: 100,\n  gold: 0,\n  quest: null,\n  storyStep: 0,\n  inVR: false,\n  audioUnlocked: false,\n  enemy: { name:\"\u5f71\u306e\u7363\", hp:80, maxHp:80, atk:10, exp:35, gold:15 }\n};\nconst FIELD_JP = { town:\"\u8857\", castle:\"\u57ce\", cave:\"\u6d1e\u7a9f\", ruins:\"\u907a\u8de1\" };\nconst ENEMIES = {\n  town:   &#91;{ name:\"\u8def\u5730\u306e\u30b9\u30e9\u30a4\u30e0\", hp:60, atk:9,  exp:35,  gold:16 }, { name:\"\u91ce\u826f\u30b4\u30d6\u30ea\u30f3\", hp:80, atk:12, exp:45, gold:20 }],\n  castle: &#91;{ name:\"\u4ea1\u970a\u9a0e\u58eb\",     hp:110, atk:16, exp:70,  gold:35 }, { name:\"\u57ce\u58c1\u306e\u5f71\",     hp:130, atk:18, exp:85, gold:42 }],\n  cave:   &#91;{ name:\"\u6d1e\u7a9f\u30b3\u30a6\u30e2\u30ea\", hp:90,  atk:15, exp:65,  gold:30 }, { name:\"\u5ca9\u55b0\u3044\u8725\u8734\",   hp:140, atk:20, exp:95, gold:55 }],\n  ruins:  &#91;{ name:\"\u5c01\u5370\u306e\u756a\u4eba\",   hp:170, atk:24, exp:120, gold:70 }, { name:\"\u53e4\u4ee3\u306e\u773c\",     hp:150, atk:22, exp:110,gold:62 }]\n};\n\n\/* \u2605\u3042\u306a\u305f\u304c\u201c\u914d\u7f6e\u306b\u4f7f\u3063\u3066\u304d\u305f\u57fa\u6e96\u5730\u9762\u201d *\/\nconst BASE_GROUND_Y = 0.55;\n\n\/* \u2605\u5cf6\u306f3\u6bb5\u3002\u8ddd\u96e2\u3067\u300c\u4eca\u3044\u308b\u5730\u9762\u306e\u9ad8\u3055\u300d\u3092\u8fd4\u3059\uff08\u57cb\u307e\u308a\u9632\u6b62\u306e\u672c\u4f53\uff09 *\/\nconst GROUND_LAYERS = &#91;\n  { r: 34, y: 0.95 }, \/\/ \u4e0a\u6bb5\uff08radius=34 height=1.2 posY=0.35 \u2192 top=0.95\uff09\n  { r: 50, y: 0.55 }, \/\/ \u4e2d\u6bb5\uff08radius=50 height=1.0 posY=0.05 \u2192 top=0.55\uff09\n  { r: 62, y: 0.40 }  \/\/ \u4e0b\u6bb5\uff08radius=62 height=1.0 posY=-0.1 \u2192 top=0.40\uff09\n];\n\nfunction groundYAt(x, z){\n  const r = Math.hypot(x, z);\n  for(const layer of GROUND_LAYERS){\n    if(r &lt;= layer.r) return layer.y;\n  }\n  return GROUND_LAYERS&#91;GROUND_LAYERS.length - 1].y;\n}\nfunction enemyYAt(x, z){\n  return groundYAt(x, z) + 0.55; \/\/ \u6575\u7403\u534a\u5f840.55\n}\n\n\/* \u2605\u300c\u57fa\u6e960.55\u3067\u7f6e\u3044\u305f\u7269\u300d\u3092\u3001\u5b9f\u5730\u9762\u306b\u5408\u308f\u305b\u3066\u6301\u3061\u4e0a\u3052\u308b *\/\nfunction snapElToGround(el){\n  if(!el) return;\n  const p = el.getAttribute(\"position\");\n  if(!p || typeof p.x!==\"number\" || typeof p.z!==\"number\" || typeof p.y!==\"number\") return;\n  const gy = groundYAt(p.x, p.z);\n  const dy = gy - BASE_GROUND_Y;\n  if(Math.abs(dy) &lt; 0.0001) return;\n  el.setAttribute(\"position\", { x:p.x, y:p.y + dy, z:p.z });\n}\nfunction snapAll(){\n  document.querySelectorAll(\".snap\").forEach(snapElToGround);\n}\n\n\/* ===== \u30e6\u30fc\u30c6\u30a3\u30ea\u30c6\u30a3 ===== *\/\nfunction escapeHtml(s){ return String(s).replace(\/&#91;&amp;&lt;>\"']\/g, m => ({ \"&amp;\":\"&amp;amp;\",\"&lt;\":\"&amp;lt;\",\">\":\"&amp;gt;\",'\"':\"&amp;quot;\",\"'\":\"&amp;#039;\" }&#91;m])); }\nfunction log(msg){\n  const el = document.getElementById(\"log\");\n  const t = new Date().toLocaleTimeString();\n  el.innerHTML = `&lt;div>\u3010${t}\u3011${escapeHtml(msg)}&lt;\/div>` + el.innerHTML;\n}\nfunction clamp(v,a,b){ return Math.max(a, Math.min(b, v)); }\n\n\/* ===== UI\u8868\u793a\/\u975e\u8868\u793a ===== *\/\nlet hudVisible = true;\nfunction setHUDVisible(visible){\n  hudVisible = !!visible;\n  document.getElementById(\"hud\").style.display = hudVisible ? \"flex\" : \"none\";\n  document.getElementById(\"floatingShowUI\").style.display = (!hudVisible &amp;&amp; !state.inVR) ? \"block\" : \"none\";\n  localStorage.setItem(\"elder_ui_hidden\", hudVisible ? \"0\" : \"1\");\n}\nfunction toggleHUD(){ setHUDVisible(!hudVisible); }\n\n\/* ===== UI\u53cd\u6620 ===== *\/\nfunction updateUI(){\n  document.getElementById(\"fieldTag\").textContent = FIELD_JP&#91;state.field] || state.field;\n  document.getElementById(\"hpText\").textContent = Math.floor(state.hp);\n  document.getElementById(\"manaText\").textContent = Math.floor(state.mana);\n  document.getElementById(\"level\").textContent = state.level;\n  document.getElementById(\"expText\").textContent = state.exp;\n  document.getElementById(\"expNeedText\").textContent = state.expNeed;\n  document.getElementById(\"goldText\").textContent = state.gold;\n  document.getElementById(\"hpBar\").style.width = clamp(state.hp,0,100) + \"%\";\n  document.getElementById(\"manaBar\").style.width = clamp(state.mana,0,100) + \"%\";\n  document.getElementById(\"expBar\").style.width = Math.min(100, (state.exp\/state.expNeed)*100) + \"%\";\n}\n\n\/* ===== DOM\u30dc\u30bf\u30f3\u3092\u78ba\u5b9f\u306b\uff08\u591a\u91cd\u767a\u706b\u3092\u6291\u3048\u308b\uff09 ===== *\/\nfunction bindPress(el, fn){\n  let last = 0;\n  const handler = (e) => {\n    const now = performance.now();\n    if(now - last &lt; 180) return; \/\/ \u9023\u6253\/\u591a\u91cd\u9632\u6b62\n    last = now;\n    try{ e.preventDefault(); }catch(_){}\n    unlockAudio();\n    fn();\n  };\n  el.addEventListener(\"pointerup\", handler, { passive:false });\n  el.addEventListener(\"touchend\", handler, { passive:false });\n  el.addEventListener(\"click\", handler, { passive:false });\n}\n\n\/* ===== \u30aa\u30fc\u30c7\u30a3\u30aa ===== *\/\nfunction unlockAudio(){\n  if(state.audioUnlocked) return;\n  state.audioUnlocked = true;\n  const bgm = document.getElementById(\"bgm\");\n  try{\n    bgm.components.sound.playSound();\n    log(\"\ud83d\udd0a BGM\u958b\u59cb\uff08\u30e6\u30fc\u30b6\u30fc\u64cd\u4f5c\u3067\u89e3\u9664\uff09\");\n  }catch(e){}\n}\nfunction setBGMByField(){\n  const bgm = document.getElementById(\"bgm\");\n  const srcMap = { town:\"#bgmTown\", castle:\"#bgmCastle\", cave:\"#bgmCave\", ruins:\"#bgmRuins\" };\n  const src = srcMap&#91;state.field] || \"#bgmTown\";\n  bgm.setAttribute(\"sound\", `src:${src}; autoplay:false; loop:true; volume:0.65; positional:false`);\n  try{\n    bgm.components.sound.stopSound();\n    if(state.audioUnlocked) bgm.components.sound.playSound();\n  }catch(e){}\n}\n\n\/* ===== \u30d5\u30a3\u30fc\u30eb\u30c9\u5207\u66ff ===== *\/\nfunction setField(field){\n  state.field = field;\n  &#91;\"town\",\"castle\",\"cave\",\"ruins\"].forEach(name=>{\n    document.getElementById(\"field-\"+name).setAttribute(\"visible\", name===field);\n  });\n  document.getElementById(\"npcGuide\").setAttribute(\"visible\", field===\"town\");\n  document.getElementById(\"npcKnight\").setAttribute(\"visible\", field===\"castle\");\n  document.getElementById(\"npcMiner\").setAttribute(\"visible\", field===\"cave\");\n  document.getElementById(\"npcSage\").setAttribute(\"visible\", field===\"ruins\");\n\n  const sky = document.getElementById(\"sky\");\n  const sun = document.getElementById(\"sun\");\n  if(field===\"town\"){ sky.setAttribute(\"color\",\"#061018\"); sun.setAttribute(\"intensity\",\"1.35\"); }\n  if(field===\"castle\"){ sky.setAttribute(\"color\",\"#071321\"); sun.setAttribute(\"intensity\",\"1.45\"); }\n  if(field===\"cave\"){ sky.setAttribute(\"color\",\"#04070b\"); sun.setAttribute(\"intensity\",\"0.85\"); }\n  if(field===\"ruins\"){ sky.setAttribute(\"color\",\"#050b10\"); sun.setAttribute(\"intensity\",\"1.05\"); }\n\n  setBGMByField();\n  spawnEnemy();\n  updateUI();\n  log(`\ud83d\udccd ${FIELD_JP&#91;field]} \u306b\u79fb\u52d5\u3057\u305f`);\n}\n\n\/* ===== \u6575 ===== *\/\nfunction spawnEnemy(){\n  const list = ENEMIES&#91;state.field] || ENEMIES.town;\n  const e = list&#91;Math.floor(Math.random()*list.length)];\n  state.enemy = { name:e.name, hp:e.hp, maxHp:e.hp, atk:e.atk, exp:e.exp, gold:e.gold };\n  document.getElementById(\"enemyName3D\").setAttribute(\"value\", e.name);\n  const enemy = document.getElementById(\"enemy\");\n  enemy.setAttribute(\"visible\",\"true\");\n  enemy.setAttribute(\"position\", { x:0, y:enemyYAt(0, -2), z:-2 });\n  enemy.setAttribute(\"animation__pop\",\"property: scale; from: 0.7 0.7 0.7; to: 1 1 1; dur: 220; easing: easeOutBack\");\n  log(`\u26a0\ufe0f ${e.name} \u304c\u73fe\u308c\u305f`);\n}\nfunction enemyCounter(){\n  if(Math.random() &lt; 0.18){ log(`\ud83d\udca8 ${state.enemy.name} \u306e\u653b\u6483\u306f\u5916\u308c\u305f`); return; }\n  const raw = state.enemy.atk + Math.floor(Math.random()*6) - Math.floor(state.level\/4);\n  const dmg = Math.max(2, raw);\n  state.hp -= dmg;\n  log(`\ud83e\ude78 \u53cd\u6483\uff1a${state.enemy.name} \u304b\u3089 ${dmg} \u30c0\u30e1\u30fc\u30b8`);\n  if(state.hp &lt;= 0){ state.hp = 1; log(\"\ud83e\uddca \u5012\u308c\u304b\u3051\u305f\u2026\uff08HP1\u3067\u8e0f\u307f\u3068\u3069\u307e\u3063\u305f\uff09\"); }\n  updateUI();\n}\nfunction gainRewards(exp, gold){\n  state.exp += exp;\n  state.gold += gold;\n  log(`\u2705 \u5831\u916c\uff1aEXP +${exp} \/ ${gold}G`);\n  while(state.exp >= state.expNeed){\n    state.exp -= state.expNeed;\n    state.level++;\n    state.expNeed = Math.floor(state.expNeed*1.25 + 25);\n    state.hp = clamp(state.hp + 18, 0, 100);\n    state.mana = clamp(state.mana + 12, 0, 100);\n    log(`\ud83c\udf89 \u30ec\u30d9\u30eb\u30a2\u30c3\u30d7\uff01 Lv.${state.level}`);\n  }\n  updateUI();\n}\nfunction enemyDie(){\n  const enemy = document.getElementById(\"enemy\");\n  enemy.setAttribute(\"animation__die\",\"property: scale; to: 0.01 0.01 0.01; dur: 250; easing: easeInQuad\");\n  setTimeout(()=> enemy.setAttribute(\"visible\",\"false\"), 260);\n  gainRewards(state.enemy.exp, state.enemy.gold);\n  setTimeout(()=> spawnEnemy(), 1200);\n}\nfunction damageEnemy(dmg, by=\"\u653b\u6483\"){\n  state.enemy.hp -= dmg;\n  log(`\u2694\ufe0f ${by}\uff1a${state.enemy.name} \u306b ${dmg} \u30c0\u30e1\u30fc\u30b8\uff08\u6b8b\u308a ${Math.max(0,state.enemy.hp)}\uff09`);\n  document.getElementById(\"enemyModel\").setAttribute(\"animation__hit\",\"property: rotation; dir: alternate; dur: 70; loop: 4; to: 0 0 12\");\n  if(state.enemy.hp &lt;= 0){ enemyDie(); return; }\n  enemyCounter();\n}\n\n\/* ===== \u884c\u52d5 ===== *\/\nfunction wave(){ document.getElementById(\"hero\").setAttribute(\"animation__wave\",\"property: rotation; dir: alternate; dur: 180; loop: 6; to: 0 0 8\"); log(\"\ud83d\udc4b Wave!\"); }\nfunction cheer(){\n  const conf = document.getElementById(\"confetti\");\n  conf.setAttribute(\"visible\",\"true\");\n  conf.setAttribute(\"animation__up\",\"property: position; from: 0 2.4 10; to: 0 4.2 10; dur: 520; easing: easeOutQuad\");\n  conf.setAttribute(\"animation__fade\",\"property: material.opacity; from: 0.35; to: 0; dur: 520; easing: easeOutQuad\");\n  setTimeout(()=>{ conf.setAttribute(\"visible\",\"false\"); conf.setAttribute(\"material\",\"opacity:0.35; transparent:true\"); }, 560);\n  log(\"\ud83c\udf89 Cheer!\");\n}\nfunction rest(){\n  const bhp=state.hp, bmn=state.mana;\n  state.hp = clamp(state.hp + 40, 0, 100);\n  state.mana = clamp(state.mana + 40, 0, 100);\n  updateUI();\n  log(`\ud83d\udecf \u4f11\u61a9\uff1aHP ${bhp}\u2192${state.hp} \/ \u9b54\u529b ${bmn}\u2192${state.mana}`);\n}\nfunction attack(){ const dmg = (14 + Math.floor(state.level\/2)) + Math.floor(Math.random()*8); damageEnemy(dmg, \"\u901a\u5e38\u653b\u6483\"); updateUI(); }\nfunction castSpell(){\n  if(state.mana &lt; 18){ log(\"\ud83d\udca4 \u9b54\u529b\u304c\u8db3\u308a\u306a\u3044\"); return; }\n  state.mana -= 18;\n  const dmg = 24 + Math.floor(state.level*1.2) + Math.floor(Math.random()*10);\n  damageEnemy(dmg, \"\u9b54\u6cd5\");\n  updateUI();\n}\n\n\/* ===== \u30e2\u30fc\u30c0\u30eb ===== *\/\nfunction openModal(title, body, buttons){\n  document.getElementById(\"modalTitle\").textContent = title;\n  document.getElementById(\"modalBody\").textContent = body;\n  const area = document.getElementById(\"modalBtns\");\n  area.innerHTML = \"\";\n  buttons.forEach(b=>{\n    const div = document.createElement(\"div\");\n    div.className = \"btn \" + (b.type || \"\");\n    div.textContent = b.label;\n    bindPress(div, ()=>{ try{ b.onClick(); }catch(e){} });\n    area.appendChild(div);\n  });\n  document.getElementById(\"modalBack\").style.display = \"flex\";\n}\nfunction closeModal(){ document.getElementById(\"modalBack\").style.display = \"none\"; unlockAudio(); }\ndocument.getElementById(\"modalBack\").addEventListener(\"click\", (e)=>{ if(e.target &amp;&amp; e.target.id === \"modalBack\") closeModal(); });\n\n\/* ===== \u4f1a\u8a71\/\u30af\u30a8\u30b9\u30c8\/\u30b7\u30e7\u30c3\u30d7 ===== *\/\nfunction talk(){\n  const npcName = (state.field===\"town\") ? \"Guide\"\n               : (state.field===\"castle\") ? \"Castle Knight\"\n               : (state.field===\"cave\") ? \"Miner\"\n               : \"Ruins Sage\";\n  openModal(`\ud83d\udcac ${npcName}`, `${npcName}\uff1a\\n\u3053\u3053\u306f ${FIELD_JP&#91;state.field]}\u3002\\n\u6e96\u5099\u304c\u3067\u304d\u305f\u3089\u6226\u3046\u304b\u3001\u5225\u306e\u5834\u6240\u3078\u884c\u3051\u3002`, &#91;\n    { label:\"\u901a\u5e38\u653b\u6483\", type:\"primary\", onClick:()=>{ closeModal(); attack(); } },\n    { label:\"\u9b54\u6cd5\", type:\"primary\", onClick:()=>{ closeModal(); castSpell(); } },\n    { label:\"\u9589\u3058\u308b\", onClick:()=> closeModal() }\n  ]);\n}\nfunction quest(){\n  openModal(\"\ud83d\udcdc \u30af\u30a8\u30b9\u30c8\", \"\u4eca\u306f\u7c21\u6613\u30af\u30a8\u30b9\u30c8\uff08\u8a0e\u4f10\u3067EXP\u3068G\u3092\u7a3c\u3052\uff09\u3002\\n\u6b21\u6bb5\u968e\u3067\u56fa\u5b9a\u30b7\u30ca\u30ea\u30aa\u3092\u5897\u3084\u305b\u308b\u3002\", &#91;\n    { label:\"\u9589\u3058\u308b\", onClick:()=> closeModal() }\n  ]);\n}\nfunction shop(){\n  openModal(\"\ud83d\uded2 \u30b7\u30e7\u30c3\u30d7\", \"\uff08\u30af\u30e9\u30a4\u30a2\u30f3\u30c8\u306e\u307f\u7c21\u6613\uff09\\n\u8857\u3067\u30b4\u30fc\u30eb\u30c9\u3092\u7a3c\u3044\u3067\u5f37\u5316\u3067\u304d\u308b\u62e1\u5f35\u306b\u5bfe\u5fdc\u3002\", &#91;\n    { label:\"\u9589\u3058\u308b\", onClick:()=> closeModal() }\n  ]);\n}\n\n\/* ===== \u30bb\u30fc\u30d6\/\u30ed\u30fc\u30c9 ===== *\/\nfunction saveGame(){\n  const data = { ...state, audioUnlocked: state.audioUnlocked };\n  localStorage.setItem(\"elder_social_vr_save\", JSON.stringify(data));\n  log(\"\ud83d\udcbe \u30bb\u30fc\u30d6\u5b8c\u4e86\");\n}\nfunction loadGame(){\n  const raw = localStorage.getItem(\"elder_social_vr_save\");\n  if(!raw){ log(\"\ud83d\udcc2 \u30bb\u30fc\u30d6\u30c7\u30fc\u30bf\u304c\u306a\u3044\"); return; }\n  try{\n    const data = JSON.parse(raw);\n    Object.assign(state, data || {});\n    setField(state.field || \"town\");\n    updateUI();\n    log(\"\ud83d\udcc2 \u30ed\u30fc\u30c9\u5b8c\u4e86\");\n  }catch(e){\n    log(\"\u274c \u30ed\u30fc\u30c9\u5931\u6557\uff1a\u30c7\u30fc\u30bf\u7834\u640d\");\n  }\n}\n\n\/* ===== VR Enter\/Exit ===== *\/\nfunction enterVR(){\n  const scene = document.getElementById(\"scene\");\n  state.inVR = true;\n  document.body.classList.add(\"vr\");\n  document.getElementById(\"vrUI\").setAttribute(\"visible\",\"true\");\n  document.getElementById(\"cam\").setAttribute(\"position\",\"0 1.72 0.05\");\n  document.getElementById(\"heroHead\").setAttribute(\"material\",\"opacity:0.0; transparent:true; color:#f4d7bd\");\n  try{ scene.enterVR(); log(\"\ud83d\udd76\ufe0f VR\u306b\u5165\u3063\u305f\"); }catch(e){ log(\"\u26a0\ufe0f WebXR\u306b\u5165\u308c\u306a\u3044\uff08\u7591\u4f3cVR\u3067\u7d9a\u884c\uff09\"); }\n}\nfunction exitApp(){\n  const scene = document.getElementById(\"scene\");\n  state.inVR = false;\n  document.body.classList.remove(\"vr\");\n  document.getElementById(\"vrUI\").setAttribute(\"visible\",\"false\");\n  document.getElementById(\"cam\").setAttribute(\"position\",\"0 1.75 3.4\");\n  document.getElementById(\"heroHead\").setAttribute(\"material\",\"opacity:1.0; transparent:false; color:#f4d7bd\");\n  try{ scene.exitVR(); }catch(e){}\n  setHUDVisible(hudVisible);\n  log(\"\u23cf Exit\");\n}\nfunction fieldTown(){ setField(\"town\"); }\nfunction fieldCastle(){ setField(\"castle\"); }\nfunction fieldCave(){ setField(\"cave\"); }\nfunction fieldRuins(){ setField(\"ruins\"); }\n\n\/* ===== \u64cd\u4f5c ===== *\/\nconst rig = document.getElementById(\"playerRig\");\nconst hero = document.getElementById(\"hero\");\nconst cam  = document.getElementById(\"cam\");\nconst keys = { w:false,a:false,s:false,d:false, shift:false, space:false };\nlet vy = 0, grounded = true;\n\nfunction getYaw(){\n  const rot = cam.getAttribute(\"rotation\");\n  return (rot &amp;&amp; typeof rot.y === \"number\") ? rot.y : 0;\n}\nfunction tickMovement(dt){\n  const speedBase = keys.shift ? 7.2 : 4.4;\n  const step = (speedBase * dt) \/ 1000;\n\n  let moveX = 0, moveZ = 0;\n  if(keys.w) moveZ -= 1;\n  if(keys.s) moveZ += 1;\n  if(keys.a) moveX -= 1;\n  if(keys.d) moveX += 1;\n\n  const len = Math.hypot(moveX, moveZ);\n  if(len > 0){ moveX\/=len; moveZ\/=len; }\n\n  const yaw = (getYaw() * Math.PI) \/ 180;\n  const cos = Math.cos(yaw), sin = Math.sin(yaw);\n  const dx = (moveX * cos - moveZ * sin) * step;\n  const dz = (moveX * sin + moveZ * cos) * step;\n\n  const pos = rig.getAttribute(\"position\");\n  let nx = pos.x + dx, nz = pos.z + dz;\n\n  const r = Math.hypot(nx, nz);\n  const limit = 44;\n  if(r > limit){ const k = limit \/ r; nx *= k; nz *= k; }\n\n  if(keys.space &amp;&amp; grounded){ vy = 5.2; grounded = false; }\n  if(!grounded){ vy -= 12.0 * (dt\/1000); }\n\n  let ny = pos.y + vy * (dt\/1000);\n\n  \/* \u2605\u5730\u9762\u306f\u56fa\u5b9a\u3058\u3083\u306a\u3044\u3002\u4eca\u3044\u308b\u5834\u6240\u306e\u5730\u9762\u3078\u30af\u30e9\u30f3\u30d7\uff08\u57cb\u307e\u308a\u30bc\u30ed\uff09 *\/\n  const gy = groundYAt(nx, nz);\n  if(ny &lt;= gy){ ny = gy; vy = 0; grounded = true; }\n\n  rig.setAttribute(\"position\", { x:nx, y:ny, z:nz });\n\n  if(len > 0){ hero.setAttribute(\"rotation\", { x:0, y:getYaw(), z:0 }); }\n\n  \/\/ \u6575\u306e\u8ffd\u5f93\uff08\u2605y\u3082\u5730\u9762\u8ffd\u5f93\uff09\n  const enemy = document.getElementById(\"enemy\");\n  const epos = enemy.getAttribute(\"position\");\n  const dist = Math.hypot((epos.x - nx), (epos.z - nz));\n  if(dist > 18){\n    const ez = nz - 2.5;\n    enemy.setAttribute(\"position\", { x:nx, y:enemyYAt(nx, ez), z:ez });\n  }\n\n  const floating = document.getElementById(\"floating\");\n  if(floating){\n    const t = performance.now() \/ 1000;\n    floating.setAttribute(\"rotation\", { x:0, y:(t*18)%360, z:0 });\n    floating.setAttribute(\"position\", { x:0, y:2.2 + Math.sin(t*1.4)*0.12, z:-10 });\n  }\n}\nfunction hookThumbstick(){\n  const RH = document.getElementById(\"rightHand\");\n  const LH = document.getElementById(\"leftHand\");\n  const onMove = (e)=>{\n    if(!e || !e.detail) return;\n    const { x, y } = e.detail;\n    keys.w = y &lt; -0.2; keys.s = y > 0.2; keys.a = x &lt; -0.2; keys.d = x > 0.2;\n  };\n  RH.addEventListener(\"thumbstickmoved\", onMove);\n  LH.addEventListener(\"thumbstickmoved\", onMove);\n}\nwindow.addEventListener(\"keydown\", (e)=>{\n  if(e.repeat) return;\n  if(e.code===\"KeyW\") keys.w = true;\n  if(e.code===\"KeyA\") keys.a = true;\n  if(e.code===\"KeyS\") keys.s = true;\n  if(e.code===\"KeyD\") keys.d = true;\n  if(e.code===\"ShiftLeft\" || e.code===\"ShiftRight\") keys.shift = true;\n  if(e.code===\"Space\") keys.space = true;\n  if(e.code===\"KeyJ\"){ unlockAudio(); attack(); }\n  if(e.code===\"KeyK\"){ unlockAudio(); castSpell(); }\n  if(e.code===\"Escape\"){ if(!state.inVR) toggleHUD(); }\n});\nwindow.addEventListener(\"keyup\", (e)=>{\n  if(e.code===\"KeyW\") keys.w = false;\n  if(e.code===\"KeyA\") keys.a = false;\n  if(e.code===\"KeyS\") keys.s = false;\n  if(e.code===\"KeyD\") keys.d = false;\n  if(e.code===\"ShiftLeft\" || e.code===\"ShiftRight\") keys.shift = false;\n  if(e.code===\"Space\") keys.space = false;\n});\n\n\/* ===== DOM\u30dc\u30bf\u30f3\u914d\u7dda ===== *\/\nfunction wireButtons(){\n  bindPress(document.getElementById(\"btnTown\"),   ()=> setField(\"town\"));\n  bindPress(document.getElementById(\"btnCastle\"), ()=> setField(\"castle\"));\n  bindPress(document.getElementById(\"btnCave\"),   ()=> setField(\"cave\"));\n  bindPress(document.getElementById(\"btnRuins\"),  ()=> setField(\"ruins\"));\n\n  bindPress(document.getElementById(\"btnEnterVR\"), ()=> enterVR());\n  bindPress(document.getElementById(\"btnExit\"),    ()=> exitApp());\n  bindPress(document.getElementById(\"btnWave\"),    ()=> wave());\n  bindPress(document.getElementById(\"btnCheer\"),   ()=> cheer());\n\n  bindPress(document.getElementById(\"btnTalk\"),  ()=> talk());\n  bindPress(document.getElementById(\"btnQuest\"), ()=> quest());\n  bindPress(document.getElementById(\"btnShop\"),  ()=> shop());\n  bindPress(document.getElementById(\"btnRest\"),  ()=> rest());\n\n  bindPress(document.getElementById(\"btnSave\"), ()=> saveGame());\n  bindPress(document.getElementById(\"btnLoad\"), ()=> loadGame());\n\n  bindPress(document.getElementById(\"btnHideUI\"), ()=> setHUDVisible(false));\n  bindPress(document.getElementById(\"floatingShowUI\"), ()=> setHUDVisible(true));\n\n  bindPress(document.getElementById(\"panel\"), ()=>{\n    try{ cam.components&#91;\"look-controls\"].pointerLockEnabled = true; }catch(e){}\n  });\n}\n\n\/* ===== \u521d\u671f\u5316 ===== *\/\n(function init(){\n  wireButtons();\n  hookThumbstick();\n\n  const hidden = localStorage.getItem(\"elder_ui_hidden\") === \"1\";\n  setHUDVisible(!hidden);\n\n  \/* \u2605\u307e\u305a\u201c\u57fa\u6e960.55\u3067\u7f6e\u3044\u305f\u7269\u201d\u3092\u5168\u3066\u30b9\u30ca\u30c3\u30d7\uff08\u57cb\u307e\u308a\u89e3\u6d88\uff09 *\/\n  snapAll();\n\n  \/* \u2605\u30d7\u30ec\u30a4\u30e4\u30fc\u306f\u300c\u305d\u306e\u5834\u306e\u5730\u9762\u300d\u306b\u5f37\u5236\u4e00\u81f4\uff08\u57cb\u307e\u308a\u30bc\u30ed\uff09 *\/\n  const p0 = rig.getAttribute(\"position\");\n  if(p0 &amp;&amp; typeof p0.x===\"number\" &amp;&amp; typeof p0.z===\"number\"){\n    rig.setAttribute(\"position\", { x:p0.x, y:groundYAt(p0.x, p0.z), z:p0.z });\n  }\n\n  updateUI();\n  setBGMByField();\n  spawnEnemy();\n  log(\"\u8d77\u52d5\u3002\u5cf6\u306e\u6bb5\u5dee\u306b\u5408\u308f\u305b\u3066 player\/NPC\/\u5efa\u7269\u3092\u81ea\u52d5\u88dc\u6b63\uff08\u57cb\u307e\u308a\u30bc\u30ed\uff09\u3002UI\u306f\u53f3\u4e0a\u3067\u9589\u3058\u3089\u308c\u308b\u3002ESC\u3067\u3082\u5207\u66ff\u3002\");\n\n  let last = performance.now();\n  function loop(now){\n    const dt = now - last;\n    last = now;\n    tickMovement(dt);\n    requestAnimationFrame(loop);\n  }\n  requestAnimationFrame(loop);\n\n  const scene = document.getElementById(\"scene\");\n  scene.addEventListener(\"enter-vr\", ()=>{\n    state.inVR = true;\n    document.body.classList.add(\"vr\");\n    document.getElementById(\"vrUI\").setAttribute(\"visible\",\"true\");\n    document.getElementById(\"cam\").setAttribute(\"position\",\"0 1.72 0.05\");\n    document.getElementById(\"heroHead\").setAttribute(\"material\",\"opacity:0.0; transparent:true; color:#f4d7bd\");\n    log(\"\ud83d\udd76\ufe0f WebXR: enter-vr\");\n  });\n  scene.addEventListener(\"exit-vr\", ()=>{\n    state.inVR = false;\n    document.body.classList.remove(\"vr\");\n    document.getElementById(\"vrUI\").setAttribute(\"visible\",\"false\");\n    document.getElementById(\"cam\").setAttribute(\"position\",\"0 1.75 3.4\");\n    document.getElementById(\"heroHead\").setAttribute(\"material\",\"opacity:1.0; transparent:false; color:#f4d7bd\");\n    setHUDVisible(hudVisible);\n    log(\"\u23cf WebXR: exit-vr\");\n  });\n})();\n&lt;\/script>\n&lt;\/body>\n&lt;\/html>\n<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"_uf_show_specific_survey":0,"_uf_disable_surveys":false,"footnotes":""},"categories":[44],"tags":[],"class_list":["post-26241","post","type-post","status-publish","format-standard","hentry","category-44"],"aioseo_notices":[],"jetpack_featured_media_url":"","_links":{"self":[{"href":"http:\/\/www.tyosuke20xx.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/26241","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/www.tyosuke20xx.com\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.tyosuke20xx.com\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.tyosuke20xx.com\/blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/www.tyosuke20xx.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=26241"}],"version-history":[{"count":1,"href":"http:\/\/www.tyosuke20xx.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/26241\/revisions"}],"predecessor-version":[{"id":26242,"href":"http:\/\/www.tyosuke20xx.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/26241\/revisions\/26242"}],"wp:attachment":[{"href":"http:\/\/www.tyosuke20xx.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=26241"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.tyosuke20xx.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=26241"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.tyosuke20xx.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=26241"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}