feat(gameplay): 添加水晶矿资源产出系统和改进AI卡组管理

- 实现水晶矿占领后的能量资源产出功能,包括manaInterval和manaAmount配置
- 添加敌方AI的能量管理系统,支持通过AddMana方法增加能量
- 实现AI卡组轮转机制,包含手牌管理和抽卡队列功能
- 优化单位AI的目标选择和战斗逻辑,修复目标切换问题

- 水晶矿现在可以按设定间隔为所属阵营提供能量资源
-
This commit is contained in:
huadexuan committed 2026-09-21 18:17:05 +08:00
1 parent b185e5768b
commit 06940a849c
21 files changed
+555 -520

No files matched your search

+111 -81
View File
@@ -3,128 +3,158 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>召唤之战:双路与资源点布局</title>
<title>召唤之战:地图纵深与公共资源布局</title>
<style>
:root { --bg:#101722; --panel:#182332; --ink:#e8eef5; --muted:#a9b6c5; --blue:#3da5ff; --red:#ff5c68; --road:#637386; --side:#d9a441; --bad:#da6870; --good:#54c48a; }
:root { --bg:#101722; --panel:#182332; --ink:#e8eef5; --muted:#a9b6c5; --blue:#3da5ff; --red:#ff5c68; --gold:#e8b94e; --road:#68798d; --line:#304052; --green:#54c48a; }
* { box-sizing:border-box; }
body { margin:0; background:var(--bg); color:var(--ink); font:16px/1.6 -apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif; }
main { max-width:1100px; margin:0 auto; padding:32px 20px 56px; }
h1 { margin:0 0 8px; font-size:30px; }
h2 { margin:28px 0 10px; font-size:22px; }
main { max-width:1180px; margin:0 auto; padding:28px 18px 52px; }
h1 { margin:0 0 6px; font-size:30px; }
h2 { margin:26px 0 10px; font-size:21px; }
p { margin:8px 0; color:var(--muted); }
.intro { margin-bottom:22px; }
.panel { background:var(--panel); border:1px solid #2c3a4c; border-radius:8px; padding:18px; margin-top:18px; }
.map-wrap { display:grid; grid-template-columns:minmax(0, 1fr) 260px; gap:18px; align-items:start; }
.intro { margin-bottom:18px; }
.panel { background:var(--panel); border:1px solid #2c3a4c; border-radius:8px; padding:18px; margin-top:16px; }
.map-wrap { display:grid; grid-template-columns:minmax(0, 1fr) 300px; gap:18px; align-items:start; }
svg { display:block; width:100%; height:auto; background:#dce5d1; border-radius:6px; }
.legend { display:grid; gap:10px; color:var(--muted); font-size:14px; }
.legend div { display:flex; align-items:center; gap:8px; }
.swatch { width:25px; height:12px; border-radius:3px; display:inline-block; flex:0 0 auto; }
.legend { display:grid; gap:12px; color:var(--muted); font-size:14px; }
.legend div { display:flex; align-items:flex-start; gap:8px; }
.swatch { width:26px; height:12px; border-radius:3px; display:inline-block; flex:0 0 auto; margin-top:5px; }
.swatch.main { background:var(--road); }
.swatch.side { background:var(--side); }
.swatch.resource { background:var(--gold); }
.swatch.blue { background:var(--blue); }
.swatch.red { background:var(--red); }
.good { border-left:4px solid var(--good); padding-left:12px; }
.warn { border-left:4px solid var(--bad); padding-left:12px; }
.swatch.boundary { background:#8c6b50; }
.good { border-left:4px solid var(--green); padding-left:12px; }
.note { background:#223044; border-left:4px solid var(--gold); padding:10px 12px; color:var(--muted); }
table { width:100%; border-collapse:collapse; margin-top:12px; }
th,td { text-align:left; padding:9px 10px; border-bottom:1px solid #304052; }
th,td { text-align:left; padding:9px 10px; border-bottom:1px solid var(--line); }
th { color:#fff; background:#223044; }
td { color:var(--muted); }
code { color:#ffd77a; }
@media (max-width:760px) { .map-wrap { grid-template-columns:1fr; } h1 { font-size:25px; } }
.coords { color:#fff; font-weight:600; white-space:nowrap; }
@media (max-width:820px) { .map-wrap { grid-template-columns:1fr; } h1 { font-size:25px; } }
</style>
</head>
<body>
<main>
<h1>《召唤之战》双路与资源点布局</h1>
<p class="intro">这张图回答一个核心问题:<strong>资源点不是必经路上的收费站,而是主路旁边的可选目标。</strong></p>
<h1>《召唤之战》地图纵深与公共资源布局</h1>
<p class="intro">这是<strong>俯视图</strong>,Unity 坐标约定为:横向是 X,纵向是 Z;蓝方在下方,红方在上方。图中每个位置都标了建议坐标,方便直接对照 Unity Inspector。</p>
<section class="panel">
<h2>推荐布局:两条主路 + 两个侧向资源支路</h2>
<h2>推荐方案:保留两个资源点,拉长 Z 轴纵深</h2>
<div class="map-wrap">
<svg viewBox="0 0 700 900" role="img" aria-label="双路资源点布局俯视图">
<svg viewBox="0 0 760 1080" role="img" aria-label="按 Unity X Z 坐标标注的战场布局">
<defs>
<marker id="arrowBlue" markerWidth="9" markerHeight="9" refX="7" refY="4" orient="auto"><path d="M0,0 L8,4 L0,8 Z" fill="#1976d2"/></marker>
<marker id="arrowRed" markerWidth="9" markerHeight="9" refX="7" refY="4" orient="auto"><path d="M0,0 L8,4 L0,8 Z" fill="#d83242"/></marker>
<marker id="arrowGold" markerWidth="9" markerHeight="9" refX="7" refY="4" orient="auto"><path d="M0,0 L8,4 L0,8 Z" fill="#a97909"/></marker>
<marker id="blueArrow" markerWidth="10" markerHeight="10" refX="8" refY="5" orient="auto"><path d="M0,0 L10,5 L0,10 Z" fill="#1976d2"/></marker>
<marker id="redArrow" markerWidth="10" markerHeight="10" refX="8" refY="5" orient="auto"><path d="M0,0 L10,5 L0,10 Z" fill="#d83242"/></marker>
<marker id="goldArrow" markerWidth="10" markerHeight="10" refX="8" refY="5" orient="auto"><path d="M0,0 L10,5 L0,10 Z" fill="#9b710b"/></marker>
</defs>
<rect x="22" y="22" width="656" height="856" rx="12" fill="#b9cba9" stroke="#73866d" stroke-width="3"/>
<text x="350" y="55" text-anchor="middle" font-size="18" font-weight="700" fill="#263728">敌方区域</text>
<text x="350" y="860" text-anchor="middle" font-size="18" font-weight="700" fill="#263728">我方区域</text>
<!-- two independent main roads -->
<path d="M205 790 L205 120" stroke="#415164" stroke-width="86" stroke-linecap="round"/>
<path d="M495 790 L495 120" stroke="#415164" stroke-width="86" stroke-linecap="round"/>
<path d="M205 790 L205 120 M495 790 L495 120" stroke="#7e8da0" stroke-width="4" stroke-dasharray="15 13"/>
<text x="205" y="475" text-anchor="middle" font-size="18" font-weight="700" fill="#fff" transform="rotate(-90 205 475)">左主路:可直接推向敌方城堡</text>
<text x="495" y="475" text-anchor="middle" font-size="18" font-weight="700" fill="#fff" transform="rotate(90 495 475)">右主路:可直接推向敌方城堡</text>
<!-- 坐标换算:X=-15..15 映射到 95..665;Z=0..120 映射到 1015..65 -->
<rect x="75" y="35" width="610" height="980" rx="10" fill="#b9cba9" stroke="#73866d" stroke-width="3"/>
<text x="380" y="61" text-anchor="middle" font-size="17" font-weight="700" fill="#263728">红方区域 Z=80~120</text>
<text x="380" y="1000" text-anchor="middle" font-size="17" font-weight="700" fill="#263728">蓝方区域 Z=0~40</text>
<!-- resource side pockets -->
<path d="M205 355 C155 355 115 350 82 315" fill="none" stroke="#d9a441" stroke-width="34" stroke-linecap="round"/>
<path d="M495 545 C545 545 585 550 618 585" fill="none" stroke="#d9a441" stroke-width="34" stroke-linecap="round"/>
<path d="M205 355 C155 355 115 350 82 315 M495 545 C545 545 585 550 618 585" fill="none" stroke="#ffe29a" stroke-width="3" stroke-dasharray="10 9"/>
<!-- horizontal coordinate guides -->
<g stroke="#91a88b" stroke-width="1" stroke-dasharray="5 7" opacity=".75">
<path d="M95 891 H665"/><path d="M95 728 H665"/><path d="M95 565 H665"/><path d="M95 402 H665"/><path d="M95 239 H665"/><path d="M95 76 H665"/>
</g>
<g fill="#40513e" font-size="12">
<text x="82" y="895" text-anchor="end">Z=15</text><text x="82" y="732" text-anchor="end">Z=35</text><text x="82" y="569" text-anchor="end">Z=55</text><text x="82" y="406" text-anchor="end">Z=75</text><text x="82" y="243" text-anchor="end">Z=95</text><text x="82" y="80" text-anchor="end">Z=115</text>
</g>
<!-- resource nodes -->
<circle cx="70" cy="302" r="43" fill="#e8b94e" stroke="#895f0a" stroke-width="5"/>
<circle cx="630" cy="598" r="43" fill="#e8b94e" stroke="#895f0a" stroke-width="5"/>
<text x="70" y="298" text-anchor="middle" font-size="16" font-weight="700" fill="#3e2d08">水晶矿</text>
<text x="70" y="319" text-anchor="middle" font-size="13" fill="#3e2d08">可选目标</text>
<text x="630" y="594" text-anchor="middle" font-size="16" font-weight="700" fill="#3e2d08">混沌之门</text>
<text x="630" y="615" text-anchor="middle" font-size="13" fill="#3e2d08">可选目标</text>
<!-- three lanes -->
<path d="M205 935 L205 135" stroke="#68798d" stroke-width="78" stroke-linecap="round"/>
<path d="M380 935 L380 135" stroke="#68798d" stroke-width="78" stroke-linecap="round"/>
<path d="M555 935 L555 135" stroke="#68798d" stroke-width="78" stroke-linecap="round"/>
<g stroke="#aab7c4" stroke-width="3" stroke-dasharray="13 12" opacity=".85">
<path d="M205 935 L205 135"/><path d="M380 935 L380 135"/><path d="M555 935 L555 135"/>
</g>
<text x="205" y="540" text-anchor="middle" font-size="16" font-weight="700" fill="#fff" transform="rotate(-90 205 540)">左路</text>
<text x="380" y="540" text-anchor="middle" font-size="16" font-weight="700" fill="#fff" transform="rotate(-90 380 540)">中路:主要交战区</text>
<text x="555" y="540" text-anchor="middle" font-size="16" font-weight="700" fill="#fff" transform="rotate(90 555 540)">右路</text>
<!-- castles -->
<rect x="145" y="755" width="120" height="70" rx="12" fill="#3189d7" stroke="#14558d" stroke-width="5"/>
<rect x="435" y="75" width="120" height="70" rx="12" fill="#e34b58" stroke="#962b35" stroke-width="5"/>
<text x="205" y="797" text-anchor="middle" font-size="18" font-weight="700" fill="#fff">我方城堡</text>
<text x="495" y="117" text-anchor="middle" font-size="18" font-weight="700" fill="#fff">敌方城堡</text>
<!-- blue side -->
<rect x="132" y="920" width="146" height="54" rx="9" fill="#3189d7" stroke="#14558d" stroke-width="4"/>
<text x="205" y="943" text-anchor="middle" font-size="16" font-weight="700" fill="#fff">蓝方主城</text>
<text x="205" y="962" text-anchor="middle" font-size="12" fill="#fff">建议 X=0, Z=8</text>
<circle cx="380" cy="870" r="25" fill="#3da5ff" stroke="#14558d" stroke-width="4"/>
<text x="380" y="866" text-anchor="middle" font-size="13" font-weight="700" fill="#fff">蓝方</text><text x="380" y="883" text-anchor="middle" font-size="12" fill="#fff">出生点</text>
<text x="398" y="905" font-size="12" fill="#14558d">X=0, Z=14</text>
<!-- blue / red direct routes -->
<path d="M205 745 L205 160" fill="none" stroke="#1976d2" stroke-width="5" marker-end="url(#arrowBlue)"/>
<path d="M495 155 L495 740" fill="none" stroke="#d83242" stroke-width="5" marker-end="url(#arrowRed)"/>
<!-- optional resource routes -->
<path d="M175 705 C135 600 115 425 78 340" fill="none" stroke="#a97909" stroke-width="4" stroke-dasharray="12 8" marker-end="url(#arrowGold)"/>
<path d="M525 195 C565 300 585 475 622 560" fill="none" stroke="#a97909" stroke-width="4" stroke-dasharray="12 8" marker-end="url(#arrowGold)"/>
<text x="94" y="520" font-size="14" font-weight="700" fill="#6c5009" transform="rotate(-78 94 520)">主动去争夺资源点</text>
<text x="607" y="390" font-size="14" font-weight="700" fill="#6c5009" transform="rotate(78 607 390)">主动去争夺资源点</text>
<!-- red side -->
<rect x="132" y="76" width="146" height="54" rx="9" fill="#e34b58" stroke="#962b35" stroke-width="4"/>
<text x="205" y="99" text-anchor="middle" font-size="16" font-weight="700" fill="#fff">红方主城</text>
<text x="205" y="118" text-anchor="middle" font-size="12" fill="#fff">建议 X=0, Z=108</text>
<circle cx="380" cy="185" r="25" fill="#ff5c68" stroke="#962b35" stroke-width="4"/>
<text x="380" y="181" text-anchor="middle" font-size="13" font-weight="700" fill="#fff">红方</text><text x="380" y="198" text-anchor="middle" font-size="12" fill="#fff">出生点</text>
<text x="398" y="220" font-size="12" fill="#962b35">X=0, Z=95</text>
<!-- labels -->
<rect x="285" y="420" width="130" height="60" rx="8" fill="#eef4e9" stroke="#80947b"/>
<text x="350" y="445" text-anchor="middle" font-size="15" font-weight="700" fill="#2b3b2a">中间留出</text>
<text x="350" y="466" text-anchor="middle" font-size="15" font-weight="700" fill="#2b3b2a">独立战斗空间</text>
<!-- resources -->
<path d="M205 625 C250 625 275 600 300 565" fill="none" stroke="#d9a441" stroke-width="26" stroke-linecap="round"/>
<path d="M555 505 C510 505 485 530 460 565" fill="none" stroke="#d9a441" stroke-width="26" stroke-linecap="round"/>
<path d="M205 625 C250 625 275 600 300 565 M555 505 C510 505 485 530 460 565" fill="none" stroke="#ffe29a" stroke-width="3" stroke-dasharray="9 8"/>
<circle cx="170" cy="655" r="46" fill="#e8b94e" stroke="#895f0a" stroke-width="5"/>
<text x="170" y="650" text-anchor="middle" font-size="15" font-weight="700" fill="#3e2d08">水晶矿</text>
<text x="170" y="670" text-anchor="middle" font-size="12" fill="#3e2d08">X=-7, Z=45</text>
<circle cx="590" cy="475" r="46" fill="#e8b94e" stroke="#895f0a" stroke-width="5"/>
<text x="590" y="470" text-anchor="middle" font-size="15" font-weight="700" fill="#3e2d08">混沌之门</text>
<text x="590" y="490" text-anchor="middle" font-size="12" fill="#3e2d08">X=7, Z=75</text>
<!-- battle zone -->
<rect x="120" y="500" width="520" height="130" rx="12" fill="none" stroke="#8c6b50" stroke-width="3" stroke-dasharray="10 8"/>
<text x="380" y="553" text-anchor="middle" font-size="17" font-weight="700" fill="#6b513d">中央交战区 Z≈45~75</text>
<text x="380" y="578" text-anchor="middle" font-size="13" fill="#6b513d">资源点在主路外侧,不堵住中路</text>
<!-- movement arrows -->
<path d="M380 850 L380 690" fill="none" stroke="#1976d2" stroke-width="5" marker-end="url(#blueArrow)"/>
<path d="M380 235 L380 395" fill="none" stroke="#d83242" stroke-width="5" marker-end="url(#redArrow)"/>
<path d="M235 640 L290 585" fill="none" stroke="#9b710b" stroke-width="4" stroke-dasharray="10 7" marker-end="url(#goldArrow)"/>
<path d="M525 490 L470 545" fill="none" stroke="#9b710b" stroke-width="4" stroke-dasharray="10 7" marker-end="url(#goldArrow)"/>
<!-- x axis labels -->
<g fill="#40513e" font-size="12"><text x="95" y="1032" text-anchor="middle">X=-15</text><text x="380" y="1032" text-anchor="middle">X=0</text><text x="665" y="1032" text-anchor="middle">X=15</text></g>
</svg>
<div class="legend">
<div><span class="swatch main"></span><span><strong>深灰色:</strong>两条主路。单位可以完全绕过资源点,直接推敌方城堡。</span></div>
<div><span class="swatch side"></span><span><strong>黄色:</strong>资源支路。只有玩家把目标指向资源点时,单位才会走这里。</span></div>
<div><span class="swatch blue"></span><span><strong>蓝箭:</strong>我方从下向上推进。</span></div>
<div><span class="swatch red"></span><span><strong>红箭:</strong>敌方从上向下推进。</span></div>
<div class="good"><strong>核心:</strong>两条主路不交叉,双方不会因为去资源点而必然汇合。</div>
<div><span class="swatch main"></span><span><strong>灰色:</strong>三条纵向路线。单位从主城出生后有较长行军距离。</span></div>
<div><span class="swatch resource"></span><span><strong>黄色:</strong>公共资源点,放在主路外侧,不堵住直攻主城的路线。</span></div>
<div><span class="swatch blue"></span><span><strong>蓝色:</strong>蓝方从下向上推进。</span></div>
<div><span class="swatch red"></span><span><strong>红色:</strong>红方从上向下推进。</span></div>
<div><span class="swatch boundary"></span><span><strong>虚线框:</strong>中央交战和资源争夺区域。</span></div>
<div class="good"><strong>阅读方法:</strong>地图越往上 Z 越大。资源点坐标写在圆点内部,主城和出生点坐标写在对应标注中。</div>
</div>
</div>
</section>
<section class="panel">
<h2>单位有两种选择</h2>
<h2>建议坐标表</h2>
<table>
<thead><tr><th>玩家目标</th><th>单位实际路线</th><th>结果</th></tr></thead>
<thead><tr><th>对象</th><th>建议世界坐标</th><th>作用</th></tr></thead>
<tbody>
<tr><td>敌方城堡</td><td>沿左主路或右主路直走</td><td>直接推进,不经过资源点</td></tr>
<tr><td>水晶矿</td><td>从左主路入口转入侧向支路</td><td>争夺能量收益,占领后再决定是否回主路</td></tr>
<tr><td>混沌之门</td><td>从右主路入口转入侧向支路</td><td>争夺自动出兵收益,占领后再决定是否回主路</td></tr>
<tr><td>途中遇到敌军</td><td>只在近距离视野内拦截</td><td><code>detectionRange = 8</code>,不会隔很远跨路追击</td></tr>
<tr><td>蓝方主城</td><td class="coords">(0, 0, 8)</td><td>蓝方防守核心</td></tr>
<tr><td>蓝方出生点</td><td class="coords">(0, 0, 14)</td><td>出生后先行军约 30 米再进入资源/交战区域</td></tr>
<tr><td>水晶矿</td><td class="coords">(-7, 0, 45)</td><td>左侧公共资源,主路外侧</td></tr>
<tr><td>混沌之门</td><td class="coords">(7, 0, 75)</td><td>右侧公共资源,主路外侧</td></tr>
<tr><td>红方出生点</td><td class="coords">(0, 0, 95)</td><td>出生后先行军约 20 米再进入交战区域</td></tr>
<tr><td>红方主城</td><td class="coords">(0, 0, 108)</td><td>红方防守核心</td></tr>
</tbody>
</table>
<p class="note">这是一套“地图长度约 100~120、宽度约 20~30”的示意坐标,不是要求你现在立即修改场景。先按图确认你想要的战略关系,再落地移动物体和调整 NavMesh。</p>
</section>
<section class="panel">
<h2>不要采用的布局</h2>
<p class="warn"><strong>资源点放在主路正中央:</strong>所有单位都必须经过资源点,资源点会变成必争的收费站,玩家无法选择速攻主城。</p>
<p class="warn"><strong>两条路在中央重新合并:</strong>即使起点分成左右两路,单位最终仍会在合流处相遇,分兵只是视觉上的分路。</p>
<p class="warn"><strong>两个资源点分别贴近己方城堡:</strong>双方到达时间不对称,资源点会天然属于距离更近的一方。</p>
</section>
<section class="panel">
<h2>推荐的 Unity 落地规则</h2>
<p>先做两条互不交叉的 NavMesh 主路。资源点放在主路外侧的凹袋中,各自连接一条短支路。支路入口与敌方主路保持足够距离,避免资源点支路直接变成双方必经的交叉口。</p>
<p>资源点占领后,单位可以回到主路,也可以继续攻击城堡。第一版不需要做复杂的路口优先级,只要保证三件事:<strong>主路能绕过、支路可选择、两条主路不交叉</strong>。</p>
<h2>相机只改 Z 轴范围的位置</h2>
<p>选中 Hierarchy 的 <code>Main Camera</code>,在 Inspector 找到 <code>CameraFollow &gt; 边界限制</code>:</p>
<table>
<thead><tr><th>字段</th><th>当前值</th><th>含义</th></tr></thead>
<tbody>
<tr><td><code>Min Z</code></td><td class="coords">-30</td><td>相机允许移动到的最低 Z</td></tr>
<tr><td><code>Max Z</code></td><td class="coords">91</td><td>相机允许移动到的最高 Z</td></tr>
<tr><td><code>Orthographic Size</code></td><td>另行设置</td><td>镜头远近和可见范围,不属于 Z 轴边界</td></tr>
</tbody>
</table>
<p>如果地图纵向扩大到 Z=108,至少要把 <code>Max Z</code> 调到能覆盖红方主城附近,例如 <code>115</code>。如果只想限制镜头移动范围,改 <code>Min Z / Max Z</code>;不要用它们来解决单位太小的问题。</p>
</section>
</main>
</body>