Silverlight C# 游戏开发:草动系统(二)随风而动
发布日期:2021-08-20 07:47:31
浏览次数:17
分类:技术文章
本文共 3475 字,大约阅读时间需要 11 分钟。
上一个草动效果是完全的随机摇摆效果,并没有特定的规律,看起来不是很自然,在实际的游戏进行过程当中,玩家并不太注意是否真的和现实世界一模一样,但是作为开发者,没有理由拒绝极致,这一次咱们一起做一个风吹过的草动效果。
真实中的风动效果,如下示意图,是一种类似波动的形象,当然了,风完全看不到,那么为了达到这个效果,应该从一个方向吹过,然后产生摇摆。 问题来了,如何知道风碰到了那些草,可能最简单的方式是遍历一下所有的草,看看符合条件的就执行一下动画,但是效率不可恭维,当屏幕上超过一定数量草的时候,每次的遍历绝对是一个非常大的开销,所以可以结合以前我提出的概念将判断操作分成块来完成,达到性能提升快速执行的效果。 区块概念如下: 将整个显示区域划分成小块,每个小块上可能没有草,可能有草,也可能有很多草,每个格子是一个List,而这些格子正好组成一个数组——元素为List的二维数组,这样做可以很清晰的知道哪些格子有哪些草,将其划分以后遍历也是非常容易。为了达到这个效果,我们写一个GrassLogic的类来组织和管理这个数组: GrassLogic代码
- public class GrassLogic
- {
- List<Grass01>[,] GrassBuffArray;
- int ArrayW;
- int ArrayH;
- int RangeW;
- int RangeH;
- public GrassLogic(int arrayW, int arrayH, int rangeW, int rangeH)
- {
- ArrayW = arrayW;
- ArrayH = arrayH;
- RangeW = rangeW;
- RangeH = rangeH;
- GrassBuffArray = new List<Grass01>[arrayH, arrayW];
- }
- public void AddGrass(Grass01 grass)
- {
- int ty = (int)grass.Y / (RangeH / ArrayH);
- int tx = (int)grass.X / (RangeW / ArrayW);
- if (GrassBuffArray[ty, tx] == null)
- GrassBuffArray[ty, tx] = new List<Grass01>();
- GrassBuffArray[ty, tx].Add(grass);
- }
- }
创建这个逻辑类的时候,我们会传入数组的宽高和显示范围,用来计算草到底在什么位置,是什么归属,细心的朋友会发现grass带有了X和Y两个属性成员,我们要对Grass01控件添加相应的属性。另外我们还要为Grass01的控件增加一个动画,以前的摇摆是循环的,这次我们需要一个只执行一次的动画(故事板),打开Grass01.xaml把下面的代码添加到<UserControl.Resources>内:
Wave故事板代码
- <Storyboard x:Name="Ani_Wave" AutoReverse="True">
- <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.Rotation)" Storyboard.TargetName="LayoutRoot">
- <EasingDoubleKeyFrame KeyTime="0" Value="0"/>
- <EasingDoubleKeyFrame x:Name="WaveValue" KeyTime="0:0:1" Value="10"/>
- </DoubleAnimationUsingKeyFrames>
- </Storyboard>
修改Grass01.xaml.cs里的代码:
Grass01类代码
是否有明白了呢,我们只需要做一个X的游标来标识风吹到了哪里,对此,我们需要对逻辑类做一些改造: - public Grass01()
- {
- InitializeComponent();
- image.CacheMode = new BitmapCache();
- }
- public void GrassWave()
- {
- Ani_Wave.Begin();
- }
- public double X
- {
- get { return Canvas.GetLeft(this); }
- set { Canvas.SetLeft(this, value); }
- }
- public double Y
- {
- get { return Canvas.GetTop(this); }
- set { Canvas.SetTop(this, value); Canvas.SetZIndex(this, (int)value); }
- }
上面的准备已经就绪,那么我们如何产生风的自然波动呢,请看下图示意:
GrassLogic代码
- public class GrassLogic
- {
- List<Grass01>[,] GrassBuffArray;
- int ArrayW;
- int ArrayH;
- int RangeW;
- int RangeH;
- DispatcherTimer WaveTimer = new DispatcherTimer();
- public GrassLogic(int arrayW, int arrayH, int rangeW, int rangeH)
- {
- ArrayW = arrayW;
- ArrayH = arrayH;
- RangeW = rangeW;
- RangeH = rangeH;
- GrassBuffArray = new List<Grass01>[arrayH, arrayW];
- WaveTimer.Tick += new EventHandler(WaveTimer_Tick);
- WaveTimer.Interval = TimeSpan.FromMilliseconds(300);
- }
- int _marker = 0;
- void WaveTimer_Tick(object sender, EventArgs e)
- {
- _marker += 1;
- if (_marker >= ArrayW)
- _marker = 0;
- for (int i = 0; i < ArrayH; i++)
- {
- List<Grass01> items = GrassBuffArray[i, _marker];
- if (items == null)
- continue;
- foreach (var item in items)
- {
- item.GrassWave();
- }
- }
- }
- public void AddGrass(Grass01 grass)
- {
- int ty = (int)grass.Y / (RangeH / ArrayH);
- int tx = (int)grass.X / (RangeW / ArrayW);
- if (GrassBuffArray[ty, tx] == null)
- GrassBuffArray[ty, tx] = new List<Grass01>();
- GrassBuffArray[ty, tx].Add(grass);
- }
- public void StartWave()
- {
- WaveTimer.Start();
- }
- }
加入了一个Timer来循环逻辑,按照格子逐步的推进,执行下面对应的草的动画,当推进到底的时候,从头来过,好了,基本上已经写完,可能需要在MainPage里将生成的草添加到GrassLogic逻辑中,使用AddGrass方法即可,其实这里有一些并不是很严谨的地方,例如移除之类的操作,相信各位有自己的玩法,我的方式是直接通过访问图层然后进行添加操作,移除也是如此,不过在这里不在进行这方面的讨论,请直接参看最终效果:
源代码如下:,可以通过上面的滑杆调整摆动的幅度,最高20,最低1,可以看看那种情况更加自然,人物控制使用键盘WASD
素材来自《窝窝世界》,窝窝世界是Silverlight开发的回合制MMORPG网页游戏。
本文转自nowpaper 51CTO博客,原文链接:http://blog.51cto.com/nowpaper/712376
转载地址:https://blog.csdn.net/weixin_33672109/article/details/89901640 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!
发表评论
最新留言
逛到本站,mark一下
[***.202.152.39]2024年03月22日 17时43分21秒
关于作者
喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
回溯法关于图
2019-04-26
04 Python数据类型之元组、集合
2019-04-26
05 Python之条件与循环
2019-04-26
06 Python之函数调用与定义
2019-04-26
07 Python之Numpy库
2019-04-26
08 Python之Pandas库选择查看、选择
2019-04-26
09 Python之Pandas库之数据处理与规整
2019-04-26
卷积神经网络交通标志识别
2019-04-26
【实战】深度学习构建人脸面部表情识别系统
2019-04-26
Python机器学习&数据分析-关联规则
2019-04-26
【实战】kaggle猫狗大战-卷积神经网络实现猫狗识别
2019-04-26
01 计算机视觉-opencv图像基本操作
2019-04-26
02 计算机视觉-opencv阈值与滤波处理
2019-04-26
03 计算机视觉-opencv图像形态学处理
2019-04-26
04计算机视觉-opencv图像梯度处理
2019-04-26
05计算机视觉-opencv边缘检测
2019-04-26
如何在junit中使用SpringFramework的Ioc容器
2019-04-26
一个案例教你理解Spring面向切面编程(Spring Aop)
2019-04-26
手把手教你整合SSM框架
2019-04-26
自己造个简单数据校验的注解@Value和@Mail
2019-04-26