Welcome

首页 / 软件开发 / C# / C#开发WPF/Silverlight动画及游戏系列教程(Game Tutorial):(四十五)

C#开发WPF/Silverlight动画及游戏系列教程(Game Tutorial):(四十五)2010-02-23 博客园 深蓝色右手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>中,到此就全部实现了物品栏对主角所持物品的显示: