標準 MMORPG 每個精靈佔據腳底區域,屬動態障礙物,隨移動時時變化。建構動態障礙物系統是全面進軍戰鬥系統的必要前奏,避免主角與怪物重疊攻擊。
byte[,] FixedObstruction = new byte[1024, 1024], VaryObstruction;
FixedObstruction:地圖固定障礙(牆壁、樹木等)。VaryObstruction:動態,含精靈腳底區域。
public int HoldWidth { get; set; } // 擴展寬度
public int HoldHeight { get; set; } // 擴展高度
以精靈座標為中心擴展。本例 HoldWidth=1, HoldHeight=0。
預測時先排除自身腳底區域,用區域邊緣點取代原預測點。向左移動例:
case 6: // 左
return VaryObstruction[(int)(Leader.X / GridSizeX) - Leader.HoldWidth - 1, (int)(Leader.Y / GridSizeY)] == 0;
原理:複製固定陣列→遍歷索敵區域精靈標記腳底區域→定時重複。必須異步(不佔 UI 執行緒),用 BackgroundWorker。
AuxiliaryThread = new DispatcherTimer(DispatcherPriority.Normal);
AuxiliaryThread.Tick += AuxiliaryThread_Tick;
AuxiliaryThread.Interval = TimeSpan.FromMilliseconds(1000);
AuxiliaryThread.Start();
BackWorker = new BackgroundWorker();
BackWorker.DoWork += BackWorker_DoWork;
BackWorker.RunWorkerCompleted += BackWorker_RunWorkerCompleted;
private void AuxiliaryThread_Tick(object sender, EventArgs e) {
if (!BackWorker.IsBusy) BackWorker.RunWorkerAsync();
}
delegate void WorkDelegate();
private void RefreshFace() {
VaryObstruction = (byte[,])FixedObstruction.Clone();
for (int i = 0; i < Carrier.Children.Count; i++) {
if (Carrier.Children[i] is QXSpirit) {
QXSpirit spirit = Carrier.Children[i] as QXSpirit;
if (spirit != Leader) {
int x = (int)(spirit.X / GridSizeX);
int y = (int)(spirit.Y / GridSizeY);
for (int m = x - spirit.HoldWidth; m <= x + spirit.HoldWidth; m++)
for (int n = y - spirit.HoldHeight; n <= y + spirit.HoldHeight; n++)
if (FixedObstruction[m, n] != 0) VaryObstruction[m, n] = 0;
}
}
}
}
private void BackWorker_DoWork(object sender, DoWorkEventArgs e) {
this.Dispatcher.BeginInvoke(new WorkDelegate(RefreshFace), DispatcherPriority.Normal, null);
}
WPF/Silverlight 跨執行緒必須用 Dispatcher.BeginInvoke。優先級設 Normal。完成事件可計數除錯。
將主角/監視頭像面板刷新邏輯同放入 RefreshFace,BackgroundWorker 每秒自動更新,如保姆般無微不至。
點擊按鈕移動怪物,測試舊位置障礙物是否殘留、新位置是否生效:
1 秒頻率在高精度遊戲不足,建議 ≤500ms;但過小導致效能過度消耗與異步錯誤識別(穿越)。建議 WPF 500ms、Silverlight 1s。固定障礙物 (FixedObstruction) 載入後不變,永遠不可穿越,這才是核心保障。
後期怪物 AI 兩種方案:① 共用固定障礙(怪物間重疊);② 各自擁有動態陣列(完美但耗資源)。更完美方案:移動前才複製全域 VaryObstruction 並微調為該次移動專用陣列。
20 隻怪物隨機分佈測試:
動態障礙物系統完成,暴風雨前夜,讓激情燃燒!下期敬請期待。