2)改進了 “托盤式”主位地圖移動模式。首先我想向一些朋友道歉,一時找不到是哪篇文章後面評論中有提到對一個Canvas進行移動而不是遍歷所有精靈,這樣可以提升邏輯方面的性能;我當時有測試過,為什麼一直堅持不行,因為我沒轉過彎,主角和其他所有對象是完全可以放在一個Canvas裡的,這也意味著它們的ZIndex順序照樣可以很好的處理,同時實現“托盤式”地圖移動模式。最終在QQ群裡“內Cool超人”的感化下,我才得以覺醒。這樣,雖然畫面性並無提升,但是,配合上Coordinate坐標關聯屬性的回調方法使用,可以去掉循環遍歷地圖上所有對象位置,在邏輯上大大的提升了性能。
3)隱藏遠離畫面窗口的精靈對象。這是基於Web游戲所必須做的處理,它將大大減少不必要元素的呈現及邏輯運算:
……
//隱藏及顯示區域范圍內精靈
if ((Math.Abs(sprite.Coordinate.X - Leader.Coordinate.X) > this.ActualWidth / 2) || (Math.Abs(sprite.Coordinate.Y -Leader.Coordinate.Y) > this.ActualHeight / 2)) {
sprite.Visibility = Visibility.Collapsed;
sprite.Timer.Stop();
}else {
if (!sprite.Timer.IsEnabled) {
sprite.Visibility = Visibility.Visible;
sprite.Timer.Start();
}
……
}
……
在間隔0.5秒的輔助計時器事件中進行類似如上判斷,當某個精靈超出了主角可視范圍,即在我們屏幕窗口所能看到的區域以外,則將之隱藏掉,並停止它的切幀動作,否則反之。這對提升游戲整體性能起著決定性關鍵作用。如果是網絡版,我們則可以拓展出2級范圍,其中1級范圍即為上述范圍;而2級范圍則為:當某個已被隱藏的精靈遠離主角到了更遙遠的地方,則我們將之移除掉,從而減少邏輯且實現不必要資源的及時釋放與回收。
4)改進了時時障礙物系統。整個游戲有兩個障礙物數組(可以記錄0-255,0代表障礙物,除0外的所有其他字節均代表無障礙。這裡我使用1標識無任何對象可通行區域,10-19用來標識傳送點。如果以後需要加入新的地形效果拓展,那麼同樣可以使用類似設定:例如20用來標識可通行水域,21標識可通行沙漠等等;這樣,現當主角在這些區域中移動時,會發出相應的腳步聲,使游戲效果更為逼真)。動態障礙物系統實現代碼如下,首先定義一個固定數組和一個動態數組:
byte[,] fixedObstruction, varyObstruction;
fixedObstruction是地圖加載後永遠不變的地圖信息描述載體,它記錄了地圖中肯定無法通過的地形及傳送點的位置等等。varyObstruction是時時的動態地圖信息,會根據所有精靈時時的位置來填充障礙物。
在每次A*移動時,我們通過先去掉精靈腳底的障礙物區域(HoldWidth和HoldHeight),然後啟動A*尋路,找到路徑後再補回精靈的腳底障礙物區域:
……
SetSpriteObstruction(sprite, 1);
AStarMove(sprite, GetSpriteEdge(enemy));
sprite.UseAStarMove = true;
SetSpriteObstruction(sprite, 0);
……
其中SetSpriteObstruction方法為:
/// <summary>
/// 設置精靈占位障礙物對應值
/// </summary>
private void SetSpriteObstruction(QXSprite sprite, byte sign) {
int x = (int)(sprite.Coordinate.X / gridSizeX);
int y = (int)(sprite.Coordinate.Y / gridSizeY);
for (int m = x - sprite.HoldWidth; m <= x + sprite.HoldWidth; m++) {
for (int n = y - sprite.HoldHeight; n <= y + sprite.HoldHeight; n++) {
if (fixedObstruction[m, n] != 0) {
varyObstruction[m, n] = sign;
}
}
}
}