C#開發WPF/Silverlight動畫及游戲系列教程(Game Tutorial):(四十五)制作精美的可任意拖放對象的物品欄及裝備欄
在通常的網絡游戲中,物品、裝備、技能、快捷按鈕等窗口中的圖標都是可以相互拖放的,不同的欄目有著不同的限制,例如技能圖標不能拖放到物品欄及裝備欄中,且不是所有的魔法技能都可以拖放(如被動技能等);而非裝備類的所有物品則無法拖放到角色的裝備欄中。那麼本節我將向大家講解如何在本教程示例游戲中添加物品欄及裝備欄,並實現它們之間雙向物品交換的兩種模式:拖放模式和雙擊模式。
首先制作物品欄。這裡我使用的是官方的工具toolkit:ListBoxDragDropTarget,只需設置它的DragDrop.AllowDrop="True",那麼它內部的ListBox類型容器中的所有Item將均可以被拖放。相關示例大家可以參考紫色永恆的這篇文章:最新Silverlight Toolkit中的Drag&Drop支持。
僅僅使用ListBox的默認配置還是與實際游戲中的物品欄容器顯示相距太遠,物品欄直觀上給我們的印象是一個N*M的網格形容器,裡面的對象是圖標,對內對外都應能做到任意拖放。為了滿足上述需求,我們還得在ListBox的模版改造上下些工夫。
默認情況下, ListBoxDragDropTarget內部拖放時並不能作用於virtualized容器(ListBox的默認容器),因此我們首先需要重寫ItemsPanel 的ItemsPanelTemplate來實現ListBox內部子對象之間能相互拖放:
<toolkit:ListBoxDragDropTarget x:Name="dragDropTarget" window:DragDrop.AllowDrop="True">
<ListBox x:Name="listBox" ……>
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
</ListBox>
< /toolkit:ListBoxDragDropTarget>
問題又來了,StackPanel僅能實現水平或豎直方向上的子控件排列,仔細想想,要是它能折行,不也是一個網格嗎?既要Panel類型,又要具備折行功能,當然非WrapPanel莫屬。下面只需將<StackPanel />換成<toolkit:WrapPanel Orientation="Horizontal" />即可。同時,我們還必須讓該ListBox背景透明且去掉它的滾動條:Background="Transparent" ScrollViewer.HorizontalScrollBarVisibility="Disabled" ScrollVIEwer.VerticalScrollBarVisibility="Disabled"才算完美。
物品欄界面制作完了,如何對它內部進行物品顯示呢?這裡需要用到ObservableCollection<QXIcon>對象作為ListBox的子控件數據源,為什麼選擇ObservableCollection<>而不是List<>等普通列表對象呢?因為ObservableCollection<>在內部子對象變化時會即時提交反饋給界面執行重繪更新,而List則不會,大家不妨自行嘗試一下,可以體會到ObservableCollection<>是相當優雅的。
接下來,在游戲中我為主角定義了一個屬性記錄它現有的所有物品代號,當初始化物品欄時,游戲將讀取這些代號,並從XML中的物品詳細資料中查出相應的數據,例如:
<Items>
< Item Code="0" Categoriy="1" IconCode="45" EquipCode="0" Name="武威之逐日衣" Description="★★★★☆閃避很高" Value="0,0,0,0,200,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0"></Item>
< Item Code="1" Categoriy="1" IconCode="46" EquipCode="0" Name="劍影風紗" Description="很漂亮哦,防御很高" Value="0,0,0,0,0,0,0,0,0,200,0,0,0,0,0,0,0,0,0,0,0"></Item>
< Item Code="2" Categoriy="0" IconCode="47" EquipCode="0" Name="滅神之刃" Description="小心,很容易秒殺" Value="0,1450,8044,10,10,0,0,0,0,0,0,0,0,0,0,20,0,0,0,0,0"></Item>
< Item Code="3" Categoriy="0" IconCode="48" EquipCode="1" Name="幻影狂刀" Description="速度極快,殺人無數" Value="0,300,400,10,10,0,-200,0,0,0,0,0,0,0,0,20,0,0,0,0,0"></Item>
< Item Code="4" Categoriy="2" IconCode="49" EquipCode="0" Name="腰帶1" Description="作者無敵懶" Value="0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0"></Item>
< Item Code="5" Categoriy="2" IconCode="50" EquipCode="1" Name="腰帶2" Description="作者無敵懶" Value="0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0"></Item>
……
< /Items>
其中Value值中的數據一一對應影響主角的21個基本屬性,最後將這些賦予QXIcon,再將所有的QXIcon綁定到物品欄的ObservableCollection<QXIcon>中,到此就全部實現了物品欄對主角所持物品的顯示: