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

C# 開發 WPF/Silverlight 動畫與遊戲系列教程(二十一):主位式地圖移動模式

     編輯:關於C#

何謂主位式地圖移動模式?

以主角為中心,其移動帶動地圖、物件、其他玩家、怪物等所有物件相對移動。典型例證:MMORPG 中角色永處視窗正中心(八角落除外)。

原理分析:九區域判斷

視窗 800×600,地圖 1750×1440,分九區域:

  • 四角落(左上、右上、左下、右下):地圖靜止,主角自由移動,顯示位置 = 座標 - 中心點
  • 上中、下中:主角水平置中,僅垂直移動,水平由地圖反向移動產生視覺前進
  • 左中、右中:主角垂直置中,僅水平移動,垂直由地圖反向移動
  • 正中:主角恆定視窗中心(定位腳底),移動時地圖反向移動形成視覺位移(主角實際靜止,僅做方向動畫)

結論:只需修改第二十節 AllMove() 方法即可完美模式轉換。

左上區域實現範例

private void AllMove() {
    if (Spirit.X <= WindowCenterX && Spirit.Y <= WindowCenterY) {
        for (int i = 0; i < Carrier.Children.Count; i++) {
            if (Carrier.Children[i] is QXSpirit) {
                QXSpirit spirit = Carrier.Children[i] as QXSpirit;
                Canvas.SetLeft(spirit, spirit.X - spirit.CenterX);
                Canvas.SetTop(spirit, spirit.Y - spirit.CenterY);
                Canvas.SetZIndex(spirit, Convert.ToInt32(spirit.Y));
            } else if (Carrier.Children[i] is Image) {
                Image Map = Carrier.Children[i] as Image;
                Canvas.SetLeft(Map, 0); Canvas.SetTop(Map, 0);
            }
        }
    }
    ...
}

為何用 for 而非 foreach?

foreach 遍歷中動態增刪集合會拋出 InvalidOperationException(如擊殺怪物移除控件)。for 迴圈無此問題,且拒絕使用 try-catch 掩蓋。

地圖控件 QXMap 統一地表與遮罩

依第十四節精靈控件模式建立 QXMap 用戶控件,屬性含 CenterX/Y、X/Y、Width_/Height_、Source、Opacity_。地表 X=Y=0,遮罩 X/Y 為其在圖片左上角座標。統一判斷:

else if (Carrier.Children[i] is QXMap) {
    QXMap Map = Carrier.Children[i] as QXMap;
    Canvas.SetLeft(Map, 0); Canvas.SetTop(Map, 0);
}

介面 QXObject 統一所有遊戲物件

未來將加入怪物、NPC 等,若持續 if-else 將導致維護災難。定義介面 QXObject 規範通用屬性(CenterX/Y、X/Y 等),讓 QXSpirit、QXMap 實作介面。AllMove() 簡化為:

for (int i = 0; i < Carrier.Children.Count; i++) {
    if (Carrier.Children[i] is QXObject) {
        QXObject Obj = Carrier.Children[i] as QXObject;
        Canvas.SetLeft(Obj, Obj.X - Obj.CenterX);
        Canvas.SetTop(Obj, Obj.Y - Obj.CenterY);
        Canvas.SetZIndex(Obj, Convert.ToInt32(Obj.Y));
    }
}

九區域代碼補全後替換舊 AllMove(),其餘代碼零修改,地圖移動模式瞬間轉換,障礙物無縫移植。成果展示:

下一步:大規模重構

模式轉換雖快,但代碼臃腫冗餘。下節將進行第一次大規模重構,從設計升華到藝術。

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