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

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

概述上一个草动效果是完全的随机摇摆效果,并没有特定的规律,看起来不是很自然,在实际的游戏进行过程当中,玩家并不太注意是否真的和现实世界一模一样,但是作为开发者,没有理由拒绝极致,这一次咱们一起做一个风吹过的草动效果。   真实中的风动效果,如下示意图,是一种类似波动的形象,当然了,风完全看不到,那么为了达到这个效果,应该从一个方向吹过,然后产生摇摆。   问题来了,如何知道风碰到了那些草,可能最简单的

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


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


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


将整个显示区域划分成小块,每个小块上可能没有草,可能有草,也可能有很多草,每个格子是一个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类代码
    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); }        }                      
上面的准备已经就绪,那么我们如何产生风的自然波动呢,请看下图示意:


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

 

GrassLogic代码
    public class GrassLogic        {        List<Grass01>[,] GrassBuffArray;        int ArrayW;        int ArrayH;        int RangeW;        int RangeH;        dispatcherTimer WaveTimer = new dispatcherTimer();        public GrassLogic(int arrayW, 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网页游戏。

总结

以上是内存溢出为你收集整理的Silverlight C# 游戏开发:草动系统(二)随风而动全部内容,希望文章能够帮你解决Silverlight C# 游戏开发:草动系统(二)随风而动所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/web/1027986.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-23
下一篇 2022-05-23

发表评论

登录后才能评论

评论列表(0条)

保存