以主角為中心,其移動帶動地圖、物件、其他玩家、怪物等所有物件相對移動。典型例證: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);
}
}
}
...
}
foreach 遍歷中動態增刪集合會拋出 InvalidOperationException(如擊殺怪物移除控件)。for 迴圈無此問題,且拒絕使用 try-catch 掩蓋。
依第十四節精靈控件模式建立 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);
}
未來將加入怪物、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(),其餘代碼零修改,地圖移動模式瞬間轉換,障礙物無縫移植。成果展示:
模式轉換雖快,但代碼臃腫冗餘。下節將進行第一次大規模重構,從設計升華到藝術。