程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> C#開發WPF/Silverlight動畫及游戲系列教程(Game Course):(二十七)(2)

C#開發WPF/Silverlight動畫及游戲系列教程(Game Course):(二十七)(2)

編輯:關於C語言

一切就緒,現在讓我們著手構建動態障礙物數組VaryObstruction。

同樣的,從實現原理切入。我們首先需要拷貝一份固定障礙物數組(FixedObstruction)的淺表副本賦給動態障礙物數組(VaryObstruction);然後循環遍歷索敵區域內的所有精靈對象,將它們占據區域全部示為障礙物區域並更新VaryObstruction;最後間隔一定時間重復以上過程繼續更新動態障礙物數組。

原理總是比較簡單的,做起來往往並非一帆風順。大家可以從原理中看出兩個重點:1、此過程是一個重復無限循環過程,因此我們可以將此之放在一個計時器中,讓Tick事件去處理;2、此過程是絕對的性能消耗,如果將之放在界面線程中,很肯定的將導致游戲刷新率大副下降,這將極其影響游戲的流暢性。聰明的朋友此時一定想到了後台處理;沒錯,這裡必須使用後台處理,而且必須是異步跨線程的(即不占用界面線程,同時又能讓結果直接影響到界面)。幸運的是,在WPF/Silverlight中,我們可以輕松的使用BackgroundWorker;在Winform時代用過它的朋友都很清楚,它是一個爽歪歪的東西。呵呵,那麼接下來的過程就再簡單不過了,且看功能實現的關鍵步驟及代碼:

第一步,創建這兩個重要對象:

//設置游戲窗體輔助線程

AuxiliaryThread = new DispatcherTimer(DispatcherPriority.Normal);

AuxiliaryThread.Tick += new EventHandler(AuxiliaryThread_Tick);

AuxiliaryThread.Interval = TimeSpan.FromMilliseconds(1000);

AuxiliaryThread.Start();

//設置後台工作者

BackWorker = new BackgroundWorker();

BackWorker.DoWork += new DoWorkEventHandler(BackWorker_DoWork);

BackWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(BackWorker_RunWorkerCompleted);

第二步,在輔助線程(AuxiliaryThread)計時器中啟動異步後台處理:

private void AuxiliaryThread_Tick(object sender, EventArgs e) {

 //異步刷新面板及障礙物

 if (!BackWorker.IsBusy) { BackWorker.RunWorkerAsync(); }

}

第三步,定義工作委托:delegate void WorkDelegate();

然後在已經注冊的後台處理事件(BackWorker_DoWork)中執行異步委托(RefreshFace),從而實現刷新動態障礙物數組:

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++) {

      VaryObstruction[m, n] = 0;

     }

    }

   }

  }

 }

}

private void BackWorker_DoWork(object sender, DoWorkEventArgs e) {

 //跨線程異步刷新障礙物

 this.Dispatcher.BeginInvoke(new WorkDelegate(RefreshFace), DispatcherPriority.Normal, null);

}

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved