首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> C# >> 關於C#

C# 開發 WPF/Silverlight 動畫與遊戲系列教程(二十七):動態障礙物系統建構

     編輯:關於C#

前言

標準 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;

動態陣列建構:BackgroundWorker 異步處理

原理:複製固定陣列→遍歷索敵區域精靈標記腳底區域→定時重複。必須異步(不佔 UI 執行緒),用 BackgroundWorker。

步驟 1:建立輔助執行緒與 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;

步驟 2:輔助執行緒啟動異步

private void AuxiliaryThread_Tick(object sender, EventArgs e) {
    if (!BackWorker.IsBusy) BackWorker.RunWorkerAsync();
}

步驟 3:工作委托與刷新邏輯

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 隻怪物隨機分佈測試:

動態障礙物系統完成,暴風雨前夜,讓激情燃燒!下期敬請期待。

出處:https://alamiye010.cnblogs.com/

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved