在上一节中,我们实现了地图牵引式移动,同时还遗留着一个小尾巴:主角和障碍物该如何跟随着地图的移动而移动?

   上节中有点到,只要在地图移动的同时,时时根据主角等对象物体的X,Y坐标进行相对于地图的X,Y坐标移动即可达到目的。但是由此又引来了新问题:主角为Image控件,障碍物则为矩形控件,它们都没有X,Y这两个属性,我们该如何对它们的坐标进行记录呢?

   最简单且最直接的方法莫过于将它们的X,Y坐标通过分隔符连接然后记录进Tag属性中,在调用的时候再将它分离取出。例如我们可以在构建障碍物的时候这样做:

            //构建障碍物(本节只为演示,随便建一个)
            for (int y = 11; y <= 14; y++) {
                for (int x = 31; x <= 40; x++) {
                    //障碍物在矩阵中用0表示
                    Matrix[x, y] = 0;
                    rect = new Rectangle();
                    //目前暂时不新创一个自定义控件,而把坐标储存在Tag属性中
                    rect.Tag = x + "," + y;
                    ……
                }
            }

   其中上图中黄色的代码即为将障碍物的X,Y坐标记录进它的Tag属性,然后我们可以通过下面的函数在需要的时候对Tag属性进行分离调用:

        //从矩形障碍物的Tag属性中分离出它的坐标Point
        private Point getPointFromTag(object tag) {
            string[] str = tag.ToString().Split(new char[] { ',' });
            return new Point(Convert.ToDouble(str[0]), Convert.ToDouble(str[1]));
        }

但是,这样做的效率是极其低下的;更主要的是它毫无扩展性可言。障碍物还好对付,如果是主角呢?它不光有X,Y两个属性,还有名字、门派、血条、蓝条、金木水火土、力量、智慧……、线程参数、方向、装备代号等等等等(晕了。。。列不完的),太多太多的五花八门的属性,难不成全都要记录进这一个Tag属性中?将霸王龙关进笼子里这是件很可怕的事情,装也难,取也难!两个字:恐怖。

   读者声音:老大,那该怎么办?搞不定难道还要上吊呀?

   作者:安啦,急什么?下面才是重点。可要认真看呀,超大一个精华!!!

   如果有做过游戏开发的朋友,或者说有了解过游戏开发相关内容的朋友一定会发现,游戏中除了地图引擎外,最关键的莫过于精灵的创建。精灵是游戏中大家见得最多的对象物体,它可以是主角,可以是其他玩家,可以是NPC,可以是怪物及BOSS,甚至可以是坐骑、障碍物等等。很多初学的朋友往往在为如何使用外国人制作好的通用精灵而发愁(毕竟繁杂的英文专业术语及超量的对象属性及方法是大多数人无法轻易弄通的)。幸运的是,在WPF/Silverlight中我们可以找到强大且使用简单的相关支持,它就是下文中我将详细讲解的传说中的精灵控件!

   我们首先来看看如何在WPF/Silverlight中创建一个精灵控件。第一步要做的是在项目中添加一个文件夹(取名Controls)来归类保存它,接下来在该文件夹上点右键添加一个用户控件(取名叫QXSpirit.xaml,嘿嘿,当然其他名字都可啦,高兴就好),如下图。

准备工作完成啦,第二步就是去丰富这个控件,多多给它加内容,让它强大起来。那么我们双击QXSpirit.xaml,窗口中显示的就是它的界面了,暂时是一片空白的,我们首要添加的当然就是迫不及待想要出世的角色了,所以我们这样写:

<UserControl x:Class="WPFGameCourse.Controls.QXSpirit"
    XMLns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    XMLns:x=http://schemas.microsoft.com/winfx/2006/xaml xmlns:QXControl="clr-namespace:QX.Game.Controls;assembly=QX">
    <Canvas x:Name="Spirit">
        <Image x:Name="Body" Width="150" Height="150"/>
        <StackPanel Name="Describtion" Width="150" Height="58" Canvas.Top="-21">
            <!--门派-->
            <QXControl:BorderText x:Name="Faction" Fill="Orchid" FontSize="12" Bold="True" Stroke="Black" StrokeThickness="0.1" Text="娥眉大师姐" Height="13" HorizontalAlignment="Center" />
            <!--家族-->
            <QXControl:BorderText x:Name="Clan" Fill="DarkOrange" FontSize="12" Bold="True" Stroke="Black" StrokeThickness="0.1" Text="破天一剑" Height="13" HorizontalAlignment="Center" />
            <!--名字-->
            <QXControl:BorderText x:Name="Name" Fill="SteelBlue" FontSize="12" Bold="True" Stroke="Black" StrokeThickness="0.1" Text="爱在后院前" Height="13" HorizontalAlignment="Center" />
        </StackPanel>
    </Canvas>
</UserControl>

代码很简单,我先定义一个名为Spirit的Canvas主布局控件(为了方便自由定位它内部的其他子控件,所以在选择上我依然使用我钟爱的Canvas。当然,你也可以使用别的布局控件作为主控件)。然后在它的内部建立一个名为Body的Image子控件,它就是精灵的身体啦(也就是我们前面章节中一直使用着的Image Spirit=new Image())。游戏中的精灵不光只有身体部分,还包括关于它的很多附加信息显示在周围:例如名字、帮派、家族等等。在上面代码中,我将这3个描述精灵身份的文字控件放在一个名为Describtion,类型为StackPanel的布局控件(该布局控件特点为可以轻松的排列子控件)中并且稍微调整一下它的位置以便在角色身体上方合适的位置显示(Canvas.Top="-21")。而这3个描述身份的文字控件均为我事先写好的带描边的名为BorderText的控件,该控件同样编译封装在项目源码中的Dll文件夹中的QX.dll中。在WPF/Silverlight中要引用程序集中的控件,必须在xaml开头申明它。因此,我们需要在UserControl中写这样一句申明:XMLns:QXControl="clr-namespace:QX.Game.Controls;assembly=QX",其中QXControl为下文中引用该控件时需要申明的前缀名称,clr-namespace和assembly这两个词应该不用再解释了吧,会编程的人都应该知道。需要特别说明的是:这么几个字,用TextBlock或Label现成的控件不就行了,何必要劳师动众那么夸张自己去写个控件来实现?对WPF/Silverlight中的中文字有一定了解的朋友都知道,在WPF/Silverlight中,文字都是矢量的,它在显示时被处理过(仿佛像是Photoshop中的文字锐利效果),因此显得模糊不清。例如假设我将本例的3个描述身份控件全用TextBlock来替换,那么效果将如下图:

   我们可以很清晰的看到,在位图中12像素的字是不会显示成这样的;但是在WPF/Silverlight中,它的效果看上去是带模糊。而我在QXControl:BorderText控件中添加了一个Stroke属性和一个StrokeThickness属性,它们分别用来设置文字的描边线颜色和描边线粗细。并且StrokeThickness是double型,这样我就可以以任意想要的粗细对文字描边进行设置了。在上文代码中,我将之设置为0.1,这样显示出来的效果如下图:

   虽然还无法达到最好的效果,但比起普通无描边的文字来说会美化些。由于文字只有12像素大小,在它上面描边无法很清晰的显示。因为,为了让大家更好理解WPF/Silverlight中TextBlock和QXControl:BorderText文字效果区别,我分别在这两个控件中输入“深蓝色”3个字,48像素,其中QXControl:BorderText以黑色1.5像素描边(该控件默认字体为“微软雅黑”),得到以下效果比较图:

  左边为<TextBlock FontSize="48" FontFamily="微软雅黑" Text="深蓝色" Foreground="Pink" />创建的,

 

  右边为<QXControl:BorderText FontSize="48" Stroke="Black" StrokeThickness="1.5" Text="深蓝色" Fill="Pink" />创建的,不用我说大家都会明白谁更幽雅漂亮了吧?更可贵的是,它提供了另一种WPF/Silverlight中关于中文字体模糊的解决方案。因此,在后面的游戏设计中,我将以QXControl:BorderText作为主要的文字控件使用。

   呼呼,到此终于将我们可爱的精灵控件界面xaml代码写完,剩下的就是在Behind代码中丰富精灵的内部了。在下一节中,我将就精灵控件后台代码及上一节中遗留的问题:在地图移动中,主角(精灵)与障碍物如何跟随移动进行讲解,敬请关注。

C#开发WPF/Silverlight动画及游戏系列教程(Game Course):(十四) 精灵控件横空出世!①相关推荐

  1. C#开发WPF/Silverlight动画及游戏系列教程(Game Tutorial):(四)实现2D人物动画①

    通过前面的学习,我们掌握了如何动态创建物体移动动画,那么接下来我将介绍WPF中如何将物体换成2D游戏角色,并通过使用前面所讲的DispatcherTimer计时器来实现2D人物角色的各种动作动画. 动 ...

  2. C#开发WPF/Silverlight动画及游戏系列教程(Game Tutorial):(四十九) 落雷!治疗!陷阱!连锁闪电!多段群伤!魔法之终极五重奏②...

    本节,我将完成本教程示例游戏的最终两个魔法:传说中的连锁闪电与暴风雪.如此经典与华丽的家伙无论在哪款好游戏中都少不了它们的踪影. 首先是连锁闪电,在<英雄无敌>中体现得尤为出色,击中一个怪 ...

  3. C#开发WPF/Silverlight动画及游戏系列教程(Game Tutorial):(四十七)远距离单体攻击与单体魔法...

    到目前为止,主角能使用的魔法均为群攻型魔法,群攻魔法的原理相对简单,常见如圆形范围,矩形范围,扇形范围等等,当魔法释放后可以按照本教程的做法对所有坐标处于相应范围内的怪物进行伤害处理,这是直观的处理方 ...

  4. C#开发WPF/Silverlight动画及游戏系列教程(Game Tutorial):(四十四)制作主角属性面板及加点器

    游戏中会使用大量的菜单面板,而这些面板往往都带有选项卡.如果用Silverlight工具中的TabControl,则需要通过复杂的xaml重写模板来实现自定义样式,这一点时常让开发者头疼,毕竟界面的东 ...

  5. C#开发WPF/Silverlight动画及游戏系列教程(Game Tutorial):(四十六)飞行模式 – 自由VS天空

    曾几何时开始迷恋无垠的天际,幻想着插上翅膀去飞翔.<天翼之链>.<奇迹>.<梦幻诛仙>向无数玩家展示了飞行的世界.翅膀,常常是一种身份的象征,但如能再赋予它自由的含 ...

  6. C#开发WPF/Silverlight动画及游戏系列教程(Game Tutorial):目录

    本系列教程的示例代码下载(感谢 银光中国 提供资源分流): 第一部分源码:WPFGameTutorial_PartI(1-20节) 第二部分源码:WPFGameTutorial_PartII(21-2 ...

  7. C#开发WPF/Silverlight动画及游戏系列教程(Game Tutorial):(二)让物体动起来②

    第二种方法,CompositionTarget动画,官方描述为:CompositionTarget对象可以根据每个帧回调来创建自定义动画.其实直接点,CompositionTarget创建的动画是基于 ...

  8. C#开发WPF/Silverlight动画及游戏系列教程(Game Tutorial):(一)让物体动起来①

    序:自从QXGame(WPF GAME ENGINE)游戏引擎公布以来,受到很多朋友的热切关注,于是乎有了写教程的想法.那么从今天开始,我将带领大家一步一步的学会如何使用纯C#开发WPF/Silver ...

  9. C#开发WPF/Silverlight动画及游戏系列教程(Game Tutorial):(十八) 完美精灵之八面玲珑(WPF Only)②...

    紧接着上一节,首先得解释一下为什么需要将这272张图片合成为一张大图.因为如果游戏中还有装备.坐骑等其他设置,那么我们就需要对图片源进行时时的合成:同时对272张甚至更多的图片进行合成效率高还是对2张 ...

  10. C#开发WPF/Silverlight动画及游戏系列教程(Game Tutorial):(二十五)完美捕捉精灵之神器 -- HitTest...

    怪物们都出现了,如何选中自己心仪的怪是主角目前首要做的事. 为了进行鼠标状态区别,我首先对鼠标变化规则进行约束:当鼠标在屏幕上空旷地图区域移动时,鼠标光标形态表现为默认光标 (0号光标图片),当鼠标经 ...

最新文章

  1. android 文件下载 超简单
  2. html5 canvas画进度条
  3. Bing空间数据服务
  4. STL的红与黑--rb_tree红黑树
  5. Raspberry Pi 软件源
  6. sp烘焙流程_3分钟带你快速入门substance painter 贴图制作
  7. WebSockets 简介
  8. OCA读书笔记(1) - 浏览Oracle数据库架构
  9. 【电路补习笔记】4、二极管的参数与选型
  10. 2020级C语言大作业 - 鸭王争霸赛
  11. python length从哪个包引入_python collections包
  12. 基于c的xml文件解析(转)
  13. 【weiphp微信开发教程】留言板插件开发详解
  14. Linux学习记录--命令与文件的查询
  15. 7.卷2(进程间通信)---互斥锁和条件变量
  16. UVa 1658,Admiral (拆点+限制最小费用流)
  17. OFFICE技术讲座:影响文字效果的四个因素是哪些
  18. Steam 界面布局出错的问题
  19. win11如何快速关机 windows11快捷键关机的设置方法
  20. 比亚乔-截至2020年5月,全球两轮车销量同比下降21%

热门文章

  1. [设计]字象乾坤之字体的性格
  2. 全新版会声会影2023专业版与旗舰版的功能详细对比
  3. 计算机毕业设计android的校园快递查询收取寄件app(源码+系统+mysql数据库+Lw文档)
  4. 现代功能性化妆品及其实用配方
  5. 图解机器学习第四部分第十四章——K均值聚类算法
  6. MATLAB校准磁力计
  7. Java -- JSP面试题及答案(需更深入了解)
  8. bin log,redo log以及undo log详解
  9. 动手学深度学习window环境搭建教程
  10. 2023年湖北省建筑八大员(建设厅七大员)报考流程和拿证流程来咯!