Silverlight C# 游戏开发:草动系统(二)随风而动

简介:

上一个草动效果是完全的随机摇摆效果,并没有特定的规律,看起来不是很自然,在实际的游戏进行过程当中,玩家并不太注意是否真的和现实世界一模一样,但是作为开发者,没有理由拒绝极致,这一次咱们一起做一个风吹过的草动效果。
 


真实中的风动效果,如下示意图,是一种类似波动的形象,当然了,风完全看不到,那么为了达到这个效果,应该从一个方向吹过,然后产生摇摆。
 


问题来了,如何知道风碰到了那些草,可能最简单的方式是遍历一下所有的草,看看符合条件的就执行一下动画,但是效率不可恭维,当屏幕上超过一定数量草的时候,每次的遍历绝对是一个非常大的开销,所以可以结合以前我提出的区块式循环概念将判断操作分成块来完成,达到性能提升快速执行的效果。
区块概念如下:


将整个显示区域划分成小块,每个小块上可能没有草,可能有草,也可能有很多草,每个格子是一个List,而这些格子正好组成一个数组——元素为List的二维数组,这样做可以很清晰的知道哪些格子有哪些草,将其划分以后遍历也是非常容易。为了达到这个效果,我们写一个GrassLogic的类来组织和管理这个数组:

GrassLogic代码
 
 
  1. public class GrassLogic  
  2. {  
  3. List<Grass01>[,] GrassBuffArray;  
  4. int ArrayW;  
  5. int ArrayH;  
  6. int RangeW;  
  7. int RangeH;  
  8. public GrassLogic(int arrayW, int arrayH, int rangeW, int rangeH)  
  9. {  
  10. ArrayW = arrayW;  
  11. ArrayH = arrayH;  
  12. RangeW = rangeW;  
  13. RangeH = rangeH;  
  14. GrassBuffArray = new List<Grass01>[arrayH, arrayW];  
  15. }  
  16. public void AddGrass(Grass01 grass)  
  17. {  
  18. int ty = (int)grass.Y / (RangeH / ArrayH);  
  19. int tx = (int)grass.X / (RangeW / ArrayW);   
  20. if (GrassBuffArray[ty, tx] == null)  
  21. GrassBuffArray[ty, tx] = new List<Grass01>();  
  22. GrassBuffArray[ty, tx].Add(grass);   
  23. }  
  24. }  
 

创建这个逻辑类的时候,我们会传入数组的宽高和显示范围,用来计算草到底在什么位置,是什么归属,细心的朋友会发现grass带有了X和Y两个属性成员,我们要对Grass01控件添加相应的属性。另外我们还要为Grass01的控件增加一个动画,以前的摇摆是循环的,这次我们需要一个只执行一次的动画(故事板),打开Grass01.xaml把下面的代码添加到<UserControl.Resources>内:

Wave故事板代码
 
 
  1. <Storyboard x:Name="Ani_Wave" AutoReverse="True"> 
  2. <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.Rotation)" Storyboard.TargetName="LayoutRoot"> 
  3. <EasingDoubleKeyFrame KeyTime="0" Value="0"/> 
  4. <EasingDoubleKeyFrame x:Name="WaveValue" KeyTime="0:0:1" Value="10"/> 
  5.  
  6. </DoubleAnimationUsingKeyFrames> 
  7. </Storyboard> 
  8.    
  9.  
修改Grass01.xaml.cs里的代码:
Grass01类代码
 
 
  1. public Grass01()  
  2. {  
  3. InitializeComponent();  
  4. image.CacheMode = new BitmapCache();   
  5. }  
  6. public void GrassWave()  
  7. {  
  8. Ani_Wave.Begin();  
  9. }  
  10.  
  11. public double X  
  12. {  
  13. get { return Canvas.GetLeft(this); }  
  14. set { Canvas.SetLeft(this, value); }  
  15. }  
  16. public double Y  
  17. {  
  18. get { return Canvas.GetTop(this); }  
  19. set { Canvas.SetTop(this, value); Canvas.SetZIndex(this, (int)value); }  
  20. }  
  21.    
  22.  
上面的准备已经就绪,那么我们如何产生风的自然波动呢,请看下图示意:


是否有明白了呢,我们只需要做一个X的游标来标识风吹到了哪里,对此,我们需要对逻辑类做一些改造:

 

GrassLogic代码
 
 
  1. public class GrassLogic  
  2. {  
  3. List<Grass01>[,] GrassBuffArray;  
  4. int ArrayW;  
  5. int ArrayH;  
  6. int RangeW;  
  7. int RangeH;  
  8. DispatcherTimer WaveTimer = new DispatcherTimer();  
  9. public GrassLogic(int arrayW, int arrayH, int rangeW, int rangeH)  
  10. {  
  11. ArrayW = arrayW;  
  12. ArrayH = arrayH;  
  13. RangeW = rangeW;  
  14. RangeH = rangeH;  
  15. GrassBuffArray = new List<Grass01>[arrayH, arrayW];  
  16. WaveTimer.Tick += new EventHandler(WaveTimer_Tick);  
  17. WaveTimer.Interval = TimeSpan.FromMilliseconds(300);  
  18. }  
  19. int _marker = 0;  
  20.  
  21. void WaveTimer_Tick(object sender, EventArgs e)  
  22. {  
  23. _marker += 1;  
  24. if (_marker >= ArrayW)  
  25. _marker = 0;   
  26. for (int i = 0; i < ArrayH; i++)  
  27. {  
  28. List<Grass01> items = GrassBuffArray[i, _marker];  
  29. if (items == null)  
  30. continue;  
  31. foreach (var item in items)  
  32. {  
  33. item.GrassWave();  
  34. }  
  35. }  
  36. }  
  37. public void AddGrass(Grass01 grass)  
  38. {  
  39. int ty = (int)grass.Y / (RangeH / ArrayH);  
  40. int tx = (int)grass.X / (RangeW / ArrayW);   
  41. if (GrassBuffArray[ty, tx] == null)  
  42. GrassBuffArray[ty, tx] = new List<Grass01>();  
  43. GrassBuffArray[ty, tx].Add(grass);   
  44. }  
  45. public void StartWave()  
  46. {  
  47. WaveTimer.Start();  
  48. }  
  49. }  
  50.    
  51.  
加入了一个Timer来循环逻辑,按照格子逐步的推进,执行下面对应的草的动画,当推进到底的时候,从头来过,好了,基本上已经写完,可能需要在MainPage里将生成的草添加到GrassLogic逻辑中,使用AddGrass方法即可,其实这里有一些并不是很严谨的地方,例如移除之类的操作,相信各位有自己的玩法,我的方式是直接通过访问图层然后进行添加操作,移除也是如此,不过在这里不在进行这方面的讨论,请直接参看最终效果:  

源代码如下:草动系统(二)随风而动,可以通过上面的滑杆调整摆动的幅度,最高20,最低1,可以看看那种情况更加自然,人物控制使用键盘WASD

素材来自《窝窝世界》,窝窝世界是Silverlight开发的回合制MMORPG网页游戏。


本文转自nowpaper 51CTO博客,原文链接:http://blog.51cto.com/nowpaper/712376


相关文章
|
3月前
|
存储 开发框架 .NET
【C#】C# 基础语法与游戏开发
【1月更文挑战第21天】【C#】C# 基础语法与游戏开发
|
4天前
|
开发框架 前端开发 JavaScript
采用C#.Net +JavaScript 开发的云LIS系统源码 二级医院应用案例有演示
技术架构:Asp.NET CORE 3.1 MVC + SQLserver + Redis等 开发语言:C# 6.0、JavaScript 前端框架:JQuery、EasyUI、Bootstrap 后端框架:MVC、SQLSugar等 数 据 库:SQLserver 2012
|
21天前
|
安全 JavaScript 前端开发
C#医院手麻系统源码,手术麻醉管理系统源码
手术麻醉管理系统贯穿患者入院至出院全程,整合术前术后流程,如手术排班、麻醉计划、术中监护及术后恢复。采用C#.net6.0、Vue、Ant-Design等技术,与sqlserver2019数据库结合。系统提供麻醉记录、手术安全核查、费用管理等功能,确保信息数字化和流程规范化。通过自动化记录和数据分析,增强手术安全,优化资源分配,并支持医疗质控与研究。
C#医院手麻系统源码,手术麻醉管理系统源码
|
22天前
|
存储 监控 安全
C#手术麻醉系统源码 大型医院手麻系统4大需求是什么?
C#编写的大型医院手术麻醉系统旨在满足四大核心需求:智慧医院建设,要求实时患者信息共享与监控;医院等级评级,强调安全评估与术后管理;电子病历评级,规定手术预约、麻醉信息的标准化;科室需求,包括系统互联、流程信息化、数据追溯、操作简便、文书完整、快速响应、生命体征动态采集及质量控制。系统提升手麻工作的效率与安全性,确保手术顺利进行。
|
1月前
|
数据挖掘 C# 开发工具
采用C#语言开发的全套医院体检系统PEIS源码功能介绍
体检系统,是专为体检中心/医院体检科等体检机构,专门开发的全流程管理系统,通过软件实现检测仪器数据自动提取,内置多级医生工作台,细化工作将体检检查结果汇总,生成体检报告登记到计算机系统中。通过软件系统进行数据分析统计与评判以及建立体检相关的体检档案。从而实现体检流程的信息化,提高工作效率,减少手动结果录入的一些常犯错误。 在实际应用中,医院体检系统能够解决传统体检中手工操作带来的问题,如工作量大、效率低下、易漏检、重检或错检等。通过与医院信息系统(如HIS、LIS、PACS等)的连接,系统能够满足体检中心的日常工作流程,提供更好的管理、统计和查询分析功能。同时,基于网络基础的系统可以在网上传输
23 1
|
2月前
|
开发框架 前端开发 NoSQL
C#医院区域云LIS系统源码
LIS操作流程标本流转----标本核收----标本上机检验----费用汇总----报告审核----报告发布----报告打印等基础流程
38 3
|
3月前
|
存储 开发框架 .NET
【C#】认识C# (为了游戏开发 O(≧口≦)O)
【1月更文挑战第26天】【C#】认识C# (为了游戏开发 O(≧口≦)O)
|
3月前
|
运维 数据挖掘 C#
C#大型LIS检验信息系统项目源码
LIS系统能实现临床检验信息化,检验科信息管理自动化。其主要功能是将检验科的实验仪器传出的检验数据经数据分析后,自动生成打印报告,通过网络存储在数据库中,使医生能够通过医生工作站方便、及时地看到患者的检验结果。
30 0
|
3月前
|
小程序 前端开发 C#
C#三甲医院在线预约挂号系统源码
医院在线预约挂号系统是一种方便患者预约挂号的系统,患者可以通过该系统进行预约挂号,省去了到医院现场排队等待的时间,提高了就诊效率。随着医院信息化水平的不断发展,医院在线预约挂号管理系统已成为医院管理中不可或缺的一部分。
55 1
|
3月前
|
小程序 前端开发 C#
C#微信公众号HIS预约挂号系统源码
微信公众号预约挂号系统、支付宝小程序预约挂号系统主要是让自费、医保患者在手机上就能实现就医全过程,实时预约挂号、自费、医保结算,同时还可以查询检查检验报告等就诊信息,真正实现了让信息“多跑路”,让群众“少跑腿”。系统与HIS对接,通过医院微信公众号,患者用身份证注册以后,可以预约看诊的时间、医生挂号缴费。预约成功后,会收到预约码或二维码,患者可以在预约的时间段,前往医院看诊。既可以节约患者的等待时间,又可以降低医院的负荷。 一、开发环境 ❀技术架构:net     ❀开发语言:C# ❀开发工具:VS2019     ❀前端框架:uni-app     ❀后端框架:net     ❀数 据
88 1