游戏的精灵框架到此为止算告一段落,让我们一同来体验它带来的神奇效应。

一个安静的黄昏,主角悠闲的甩着它帅气的毛发独跑于林阴大道。怎知天色已晚即将进入月亮的领地,嘿嘿,我们的故事就从这里开始:Be careful,前方怪物出没!

实在不忍心让主角空有一身武艺而无处施展,本节为了不再让它孤单,我将向游戏中加入可爱的妖精妹妹与之为伴:

好象在哪见过呢?对,就是她了,可爱吧(QXGameEngine中的怪物,^_^||难怪这眼熟)。

妖精怪物属于精灵类型,因此要让它在游戏中出现,我们只需创建QXSpirit的实例;这里首先我添加一个刷怪方法InitMonster,接着循环添加怪物精灵实例及参数:

QXSpirit[] Monster;

/// <summary>

/// 初始化怪物(刷怪)

/// </summary>

/// <param name="num">怪物数量</param>

private void InitMonster(int num) {

Monster = new QXSpirit[num];

Random random = new Random(); //测试用,随机数坐标

for (int i = 0; i < num; i++) {

if (Carrier.FindName("Magicer" + i.ToString()) == null) {

Monster[i] = new QXSpirit();

Monster[i].Name = "Magicer" + i.ToString();

Carrier.RegisterName(Monster[i].Name, Monster[i]);

Monster[i].Equipment[0] = 100;

Monster[i].Equipment[1] = 0;

……

Monster[i].X = 2000 - random.Next(1000);

Monster[i].Y = 1500 - random.Next(1000);

……

Carrier.Children.Add(Monster[i]);

}

}

}

代码太多我就不一一罗列了,下面我提取部分重要的参数进行讲解。首先我定义一个Random类型随机函数用于随机数值的产生,接着判断每一个有名字的精灵是否存在,如果不存在则加入到游戏中。这里为精灵注册名字的目的是为了以后方便管理,例如精灵死掉了,我们需要找到它的实例并将之移除,而惟有通过它的名字或ID之类的方能将之捕获;同时,在定时刷怪的机制下,我们得首先判断某精灵是否还存在,如果存在则不可能再多刷一个,就好比网络游戏中大家是否都有过蹲点等刷BOSS暴装备的经历,一个萝卜一个坑,同一点上刷出两个双胞胎BOSS,这是很匪夷所思的事。那么定义完怪物的名字后,我们接着还需要定义它的身体图片代号,本例中它的代号为100(为了与主角类精灵用的身体图片区别,我以0-99代表主角类身体(衣服)代号范围,100-N代表怪物(NPC)类身体代号范围),最后通过前面的random来定义它们的初始坐标:以(2000,1500)为中心边长为1000的正方形范围内的随机位置。

就这么完啦?对,简单吧,还是那句老话,拓展性优良的架构是经得起全方位的考验滴。嘿嘿,刷它30个怪(InitMonster(30))测试一下:

怪物满天飞,主角此时激动的心情是难以用人类的语言来形容的。可是,当主角向四周望去时,蒙了:杂都和我名同姓捏?作者你脑神经搭到脚底了吧?。。。我还真没注意到哪。在前面的章节里,我将精灵的3个身份描述都定义在了xaml里面(Faction门派,Clan家族,Sname名字)。此时,我们对精灵的重命名必须在精灵初始化的同时进行。但由此带来的新问题:如果每个怪物都有不同的身份描述,而且需要经常性的修改调整,写在内存里的东西是无法扩展的。这不禁让我联想到了第二十二节中的xml配置文件解决方案。网络游戏的服务器会根据地图区域代号加载相应的地图xml配置文件,其中包括地图及遮挡物以及地图上相当重要的精灵对象信息。当需要时我们只需对xml文件进行稍稍修改,例如精灵怪物的位置,描述,等级等相关信息即可以达到更新的目的。根据此原理,我对原有的Config配置文件进行如下改进,并添加怪物参数设置:

<Map Sign="1">

<Surface Src="Map/1/0.jpg" Width="3200" Height="2400" X="0" Y="0" CenterY="0" Opacity="1"></Surface>

<Masks></Masks>

<Spirits>

<Monster Name="Magicer001" Faction="倾城之恋" Clan="美丽呀" SName="倒影在心房" FrameRange0="10" FrameRange1="12" FrameRange2="11" FrameRange3="13" FrameRange4="15" SingleWidth="150" SingleHeight="150" TotalWidth="9150" TotalHeight="1200" Equipment0="100" Equipment1="0" CenterX="75" CenterY="125" X="700" Y="300" Direction="4" Speed="120"></Monster>

……

<Monster Name="Beast001" Faction="精英" Clan="食人族酋长" SName="绝对无敌" FrameRange0="8" FrameRange1="8" FrameRange2="9" FrameRange3="6" FrameRange4="9" SingleWidth="200" SingleHeight="200" TotalWidth="8000" TotalHeight="1600" Equipment0="101" Equipment1="0" CenterX="100" CenterY="170" X="200" Y="1200" Direction="0" Speed="125"></Monster>

……

</Spirits>

</Map>

以上为xml文件的部分代码,大家将代码中黄色背景的数据与InitMonster方法中的赋值属性进行对照会发现它们之间基本上是一一对应的。设置完后,我们只需通过第二十二节中加载xml数据的方法:

XElement mapdata = Super.GetTreeNode(Super.SystemConfig, "Map", "Sign", "1");

……

//抽离精灵数据中的怪物集合并用其来初始化地图上的怪物

InitMonster(mapdata.Element("Spirits").Elements("Monster"));

即可遍历xml配置文件中地图(Map)代号为1(Sign==1)的精灵类型(Spirits)中的具体类型为怪物(Monster)的数据,然后将它们的值与精灵的参数属性进行一一对应赋值即可以动态的完成精灵怪物的初始化。

仔细看的朋友一定注意到了xml文件中地图1中的怪物除了美丽的妖精外,还多了一个名字叫“绝对无敌”的家伙。嘿嘿,它可是我为了本教程特意花了1个小时处理出来的,以次感谢大家这段时间来对我的支持!同时也是对自己劳动的犒赏!挺值得的。那么我们都各刷它若干只测试一下:

忽忽,怪物出现了。又到了本教程的国际惯例---“自恋一刻”!让主角在地图上逛逛吧~当到了怪多的地方突然会发现有些许的不连贯,问题出在线程上。本教程例子均使用封装好的线程DispatcherTimer,因此管理起来是相当方便的(比起直接使用Thread简单多了),仅仅需要设置它们的优先级别即可进行相应调整。经过再三考虑与调试,最终的线程结构如下:暂时将主角的生命线程表现级别设置为9级(Normal级),将怪物的生命线程表现级别设置为7级(Render级),并且分别对5个不同的动作(站立、跑步、战斗、施法、死亡)设置相应的后台处理级别分别对应为Lowest、Normal、BelowNormal、BelowNormal、Lowest。对这些线程的调试过程是件非常有趣的尝试,我曾反复尝试并乐在其中(太过瘾导致我无法自拔因而延误了教程的发布…读者声音:“癫子”。^_^||)。不同的线程级别搭配将在游戏性能、画面及操作手感上产生相当明显的区别,大家不妨在我的代码基础上,将主角的生命线程表现级别由Normal调节为Background,或将跑步的级别由Normal调节到最低级别Lowest,然后分别运行一下,区别一目了然。

最后发张最终的测试截图,嘿嘿,我的怪兽军团:

轻轻松松就创建出了如此美妙的怪物精灵,这全都得归功于第十四节创建的精灵控件。上天入地如探囊取物,简单设置即可随意实现主角、怪物、NPC等等角色的创建,这就是控件封装给我们带来的完美体验。

下一章我将讲解怪物的层次关系以及如何准确的判断及拾取鼠标下的精灵对象,敬请关注。

作者:深蓝色右手
出处:http://blog.csdn.net/alamiye010/
教程目录及源码下载:点击进入
本文版权归作者和CSDN共有,欢迎转载。但未经作者同意必须保留此段声明,且在文章页面显著位置给出原文连接,否则保留追究法律责任的权利。

C#开发WPF/Silverlight动画及游戏系列教程(Game Tutorial):(二十四) Be careful!前方怪物出没相关推荐

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

    在上一节中,我们实现了地图牵引式移动,同时还遗留着一个小尾巴:主角和障碍物该如何跟随着地图的移动而移动? 上节中有点到,只要在地图移动的同时,时时根据主角等对象物体的X,Y坐标进行相对于地图的X,Y坐 ...

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

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

  3. C#开发WPF/Silverlight动画及游戏系列教程(Game Tutorial):(十)斜度α地图的构造及算法...

    在当前的网络游戏中,地图基本都是采取一定斜度的拼装地图,这其中存在两种斜度地图的构造方式: 第一种我称之为伪斜度地图:该类型地图表现层图片为斜度的,但地图基底障碍物等的构造则实为正方形,如下图: 其实 ...

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

    在上一节中,我们实现了地图牵引式移动,同时还遗留着一个小尾巴:主角和障碍物该如何跟随着地图的移动而移动? 上节中有点到,只要在地图移动的同时,时时根据主角等对象物体的X,Y坐标进行相对于地图的X,Y坐 ...

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

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

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

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

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

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

  8. C#开发WPF/Silverlight动画及游戏系列教程(Game Tutorial):(二十四) Be careful!前方怪物出没...

    游戏的精灵框架到此为止算告一段落,让我们一同来体验它带来的神奇效应. 一个安静的黄昏,主角悠闲的甩着它帅气的毛发独跑于林阴大道.怎知天色已晚即将进入月亮的领地,嘿嘿,我们的故事就从这里开始:Be ca ...

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

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

最新文章

  1. Windows下Oracle 11g创建数据库
  2. 百度超级链XChain(1)系统架构
  3. Spring配置内置的连接池DriverManagerDataSource
  4. Morpheus - DNS Spoofing
  5. Jmeter 生成HTML性能测试报告
  6. 使用Swagger服务搭建.Net Core API
  7. PYQT5+PYTHON杂谈
  8. Linux 僵尸进程查杀
  9. CICD详解(十五)——Jenkins插件安装失败解决
  10. 前端开发中最常用的JS代码片段
  11. stm32死机问题的处理
  12. 【jmeter连接数据库报错问题排查,以及建立jmeter与mysql之间的简单连接】
  13. 1.Spring Boot使用Apache Curator实现服务的注册和发现「第四章 ZooKeeper Curator应用场景实战」「架构之路ZooKeeper理论和实战」
  14. PM2.5的加重,和建筑工地关系大不大?(附扬尘治理方案)
  15. Ubuntu 16.04 安装wine-qq 7.8 并解决不能输入中文问题
  16. iOS 直播 IJKPlayer
  17. 微软巨资收购Skype 网络电话行业受关注
  18. HTML特效,旋转的正方体
  19. 华为平板 M3(青春版)ROOT教程 华为平板 M3一键root步骤
  20. <![CDATA[ ]]>用法

热门文章

  1. InnoDB——锁、事务和复制
  2. Requests库爬虫详解
  3. 项目要求完成杀毒软件,可是为什么网上关于杀毒软件的资料那么少啊
  4. 伪原创文章写作格式(符合seo优化的文章规范是什么)
  5. 23.本地服务Services
  6. 解决服务器发回了不可路由的地址。使用服务器地址代替的问题
  7. State Threads 回调终结者(ST线程库)
  8. ajax谷歌浏览器提示等待超时,调用谷歌浏览器爬虫,selenium webdriver等设置等待时间和超时时间...
  9. android 蓝牙相关的类,Android中BluetoothAdapter类简介
  10. day4. jetson nx 确认 SPI 时钟