C#開發WPF/Silverlight動畫及游戲系列教程(Game Course):(三十三) 錦上添花之魔法特效裝飾
本節我將以凍結魔法為例,向大家講解如何為魔法增加漂亮的特效裝飾。
經過前面的學習,大家是否已總結出一個規律:需要增加額外東西時,首先想到的即是用戶控件;那麼我們首先創建一個名為QXDecoration的用戶控件。接下來就是准備素材了。這裡我制作了3張用於裝飾的冰刺:
分別命名為4-0,4-1,4-2,其命名規則對應上一節中的魔法類型設定,即所有冰凍類魔法均可以用之來裝飾。為什麼要使用3張呢?其實一張就已足夠了,只是效果上每個精靈被凍結後將一模一樣;而通過隨機從這3張中抽取1張用於裝飾凍結效果將大幅度增加畫面的生動性,在大量精靈同時被凍結的情況下產生一種宏大的氣勢感;另外,如果您能通過Blend畫出一個類似的冰刺,那麼基於矢量的裝飾物將可以任意的拉伸及變化,表現出來的效果會更加逼真與貼切。
都准備好後,代碼實現起來是很簡單的,首先將配置寫進Config.xml:
<Decoration Code="4" Num="3" Duration="2" CenterX="40" CenterY="60"></Decoration>
接下來只需在魔法觸發傷害幀時將對應的魔法效果裝飾附加到被攻擊對象的腳底即可:
……
//附加特效裝飾
if (magic.DecorationCode != -1 && canvas.FindName(string.Format("Decoration{0}", enemy.Name)) == null) {
LoadXElement(string.Format("Decoration{0}", magic.DecorationCode.ToString()), GetTreeNode(SystemConfig, "Decoration", "Code", magic.DecorationCode.ToString()));
XElement DecorationData = GetXElement(string.Format("Decoration{0}", magic.DecorationCode.ToString()));
Random rm = new Random();
QXDecoration decoration = new QXDecoration() {
BodySource = getImage(string.Format("Decoration/{0}-{1}.png", magic.DecorationCode, rm.Next((int)DecorationData.Attribute("Num") - 1))),
CenterX = (double)DecorationData.Attribute("CenterX"),
CenterY = (double)DecorationData.Attribute("CenterY"),
X = enemy.X,
Y = enemy.Y,
Duration = (double)DecorationData.Attribute("Duration"),
};
canvas.RegisterName(string.Format("Decoration{0}", enemy.Name), decoration);
canvas.Children.Add(decoration);
}
……
上一節中的冰凍只是減緩對象精靈的各種速度,那麼本節為了演示,我將之改為了凍結效果,類似於麻痺。因此該凍結裝飾的消失分兩種情況:一是在凍結時間歸0時被移除;另一種為被凍結精靈死亡後移除,相關邏輯我寫在源碼中,這裡就不羅列了。
來一張效果圖吧:
相對於上一節,氣勢增加了不少呢,對嗎?
額外的,通常的網絡游戲中,我們都可以通過角色頭像面板中的小圖標來查看當前監視的精靈對象被附加的Buff以及相關信息如持續時間、效果等等,而這個功能在我們的示例游戲中該如何實現呢?
這裡我們同樣的先添加一個名為QXIcon的圖標控件,該控件的界面xaml定義如下:
……
<Canvas x:Name="Icon">
<Image x:Name="Body">
<Image.ToolTip>
<TextBlock x:Name="Details"/>
</Image.ToolTip>
</Image>
</Canvas>
……
該控件的主體是一張圖片,我為之增加了一個ToolTip用於鼠標懸停時顯示該圖片的描述。
接下來再為通用型角色頭像面板增加一個水平排列的StackPanel控件作為這些Buff圖標的容器:
<StackPanel x:Name="ExtraPanel" Orientation="Horizontal" />
為什麼選擇StackPanel而不是其他的布局控件呢?一方面為了與Silverlight更好的兼容,另一方面只要設置好它的寬度,動態的子控件添加或移除隊列起來均非常的完美,我們需要做的僅僅是Add和Remove操作罷了。
最後,在刷新監視對象角色頭像面板方法中添加如下邏輯進行Buff圖標的添加與移除判斷:
……
//更新Buff附加屬性圖標及描述
for (int i = 0; i < obj.ExtraTime.Count(); i++) {
QXIcon icon = ObjectRoleFace.ExtraPanel.FindName(string.Format("Extra{0}", i)) as QXIcon;
if (obj.ExtraTime[i] > 0) {
XElement ExtraItem = Super.GetTreeNode(Super.SystemXElement["ExtraItems"], "Item", "Value", i.ToString());
if (icon == null) {
icon = new QXIcon() {
Width = 16,
Height = 16,
BodySource = Super.getImage(ExtraItem.Attribute("Src").Value)
};
ObjectRoleFace.ExtraPanel.RegisterName(string.Format("Extra{0}", i), icon);
ObjectRoleFace.ExtraPanel.Children.Add(icon);
}
icon.Tip = string.Format("{0}持續:{1}秒", ExtraItem.Attribute("Name").Value, obj.ExtraTime[i]);
} else {
if (icon != null) {
ObjectRoleFace.ExtraPanel.UnregisterName(string.Format("Extra{0}", i));
ObjectRoleFace.ExtraPanel.Children.Remove(icon);
icon = null;
}
}
}
……
運行效果圖:
很酷吧~WPF中的ToolTip非常強大,模板化的它無論內容多少或形式如何均能自如顯示。不同尺寸的QXIcon不僅僅可以用來顯示Buff圖標,還可以拓展到技能圖標、快捷圖標等等;另外,這些Buff圖標在StackPanel的管理下顯得相當智能,前一個圖標消失後,後一個圖標將自動前置,再新加入的Buff圖標又會跟進追尾顯示,而這些的一切亂序隊列均是偉大的StackPanel在默默無聞的處理,我們無須插手任何一句多余的代碼:
角色面板到此為止總算完善了。下一節我將為大家講解如何為本教程示例游戲制作地圖編輯器,初步打算首先實現障礙物設置與地圖切片功能,現做現賣,時間會久一點,要關注哦。
出處:http://alamiye010.cnblogs.com/