fix(csharp): SpatialGridCs 网格常量/坐标偏移对齐 GDScript 外壳(激活陷阱)

休眠的 C# 内核 SpatialGridCs 与权威外壳 spatial_grid.gd 三处不一致,
一旦按 ADR-L1 激活即塌:
- 网格尺寸 64×64 → 128×128(覆盖 4096²→8192²,与 GDScript 一致)
- 补 GridOffset=4096:Insert / QueryCircle 的格映射改为 (coord±radius+4096)/64,
  修复负坐标实体全塌到 0 格、覆盖范围减半的问题。
两骨架 BulletManagerCs/EnemyManagerCs 仅读 _active_count 打计时,无 SoA 常量对齐问题。
dotnet build 通过(0 警告 0 错误)。保持休眠(_cs_node 仍恒 null,GDScript fallback 运行)。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-23 16:32:39 +08:00
co-authored by Claude Opus 4.8
parent 35c1742b4c
commit 7038505880
+11 -8
View File
@@ -9,9 +9,12 @@ using System.Collections.Generic;
public partial class SpatialGridCs : Node
{
// ⚠️ 必须与 GDScript 外壳 spatial_grid.gd 的 CELL_SIZE / GRID_COLS / GRID_ROWS / GRID_OFFSET
// 逐一对齐;否则激活 C# 内核后两条路径格子映射不一致(负坐标塌陷 + 覆盖范围减半)。
private const int CellSize = 64;
private const int GridWidth = 64; // 64 格×64 格 = 4096×4096 像素覆盖范围
private const int GridHeight = 64;
private const int GridWidth = 128; // 128×128 格 × 64px = 8192×8192 覆盖范围
private const int GridHeight = 128;
private const int GridOffset = 4096; // 世界中心映射到网格中心(支持负坐标)
private const int GridTotal = GridWidth * GridHeight;
// 网格主体:一维数组模拟二维,直接索引 grid[x + y * GridWidth]
@@ -39,8 +42,8 @@ public partial class SpatialGridCs : Node
// 插入或更新实体位置(由 EnemyManager 每帧调用)
public void Insert(int entityId, Vector2 pos)
{
int cx = Mathf.Clamp((int)(pos.X / CellSize), 0, GridWidth - 1);
int cy = Mathf.Clamp((int)(pos.Y / CellSize), 0, GridHeight - 1);
int cx = Mathf.Clamp((int)((pos.X + GridOffset) / CellSize), 0, GridWidth - 1);
int cy = Mathf.Clamp((int)((pos.Y + GridOffset) / CellSize), 0, GridHeight - 1);
int cellIdx = cx + cy * GridWidth;
if (_entityCell.TryGetValue(entityId, out int oldCell))
@@ -61,10 +64,10 @@ public partial class SpatialGridCs : Node
// ADR-L1 规厙1:内层 foreach 内禁止 Call()
public int[] QueryCircle(Vector2 center, float radius)
{
int minCx = Mathf.Clamp((int)((center.X - radius) / CellSize), 0, GridWidth - 1);
int maxCx = Mathf.Clamp((int)((center.X + radius) / CellSize), 0, GridWidth - 1);
int minCy = Mathf.Clamp((int)((center.Y - radius) / CellSize), 0, GridHeight - 1);
int maxCy = Mathf.Clamp((int)((center.Y + radius) / CellSize), 0, GridHeight - 1);
int minCx = Mathf.Clamp((int)((center.X - radius + GridOffset) / CellSize), 0, GridWidth - 1);
int maxCx = Mathf.Clamp((int)((center.X + radius + GridOffset) / CellSize), 0, GridWidth - 1);
int minCy = Mathf.Clamp((int)((center.Y - radius + GridOffset) / CellSize), 0, GridHeight - 1);
int maxCy = Mathf.Clamp((int)((center.Y + radius + GridOffset) / CellSize), 0, GridHeight - 1);
var result = new List<int>(32);
float radSq = radius * radius;