在游戏中,有各种各样特效,其中有一种特效是通过计算随机产生,而不是一张又一张的图片更换,通过模拟现实中的粒子物理规律得到有趣真实的效果,这种叫作粒子特效,它能大量的降低资源大小,咱们一起实现一个简单的跟随鼠标的粒子特效。
<a target="_blank" href="http://blog.51cto.com/attachment/201111/131123850.jpg"></a>
在flash中我不清楚是否好做,但是在Silverlight中实现粒子特效非常容易,今天咱们一起来做一个简单的粒子特效。
现在需要将基本的粒子创建出来,先分析粒子最基本的运动方式和规律,粒子具备衰减的特性,然后就是移动行为,为了让运动不具备规律还要加入例如XY轴随机向量和重力,具体分析请看下图。
依据上面的分析建立全局参数,为了让粒子效果看起来更加真实和不确定,这些包含了随机、透明度、粒子数、大小范围等等,请参看下面的代码:
public class GlobalValue
{
/// <summary>
/// 全局随机函数,从时间取得种子,保证每次都不一样
/// </summary>
public static Random random = new Random((int)DateTime.Now.Ticks);
/// 起始透明度
public const double OPACITY = 1;
/// 每次添加多少个粒子
public const double FIREWORK_NUM = 2;
/// 重力
public const double GRAVITY = 0.1;
/// 偏移X
public const double X_VELOCITY = 5;
/// 偏移Y
public const double Y_VELOCITY = 5;
/// 最小的半径
public const int SIZE_MIN = 1;
/// 最大的半径
public const int SIZE_MAX = 10;
/// 透明度衰减值
public const double OpacityInc = -0.02;
}
然后建立基本粒子,我这里偷懒了,简单的写了一个DOT类:
public class Dot: Canvas
{
public double XVelocity = 1;
public double YVelocity = 1;
public double Gravity = 1;
public Dot(byte red, byte green, byte blue, double size)
double opac = GlobalValue.OPACITY;
size = GlobalValue.random.Next(GlobalValue.SIZE_MIN,GlobalValue.SIZE_MAX);
//生成圆圈粒子
Ellipse ellipse = new Ellipse();
ellipse.Width = size;
ellipse.Height = size;
ellipse.Fill = new SolidColorBrush(Color.FromArgb(255, red, green, blue));
ellipse.Opacity = opac;
ellipse.SetValue(Canvas.LeftProperty, -ellipse.Width / 2);
ellipse.SetValue(Canvas.TopProperty, -ellipse.Height / 2);
this.Children.Add(ellipse);
public void RunFirework()
XX = X + XVelocity;
YY = Y + YVelocity;
this.Opacity += GlobalValue.OpacityInc;
YVelocity += Gravity;
//制作一个绑定属性
public double X
get { return (double)(GetValue(Canvas.LeftProperty)); }
set { SetValue(Canvas.LeftProperty, value); }
public double Y
get { return (double)(GetValue(Canvas.TopProperty)); }
set { SetValue(Canvas.TopProperty, value); }
建立一个Colorful类也是从Canvas上继承下来,它就是所有粒子的容器。
public class Colorful : Canvas
private List<Dot> _dotGroup = new List<Dot>();
private DispatcherTimer _timer;
private static int IntervalTime = 20;
public Colorful()
this.Background = new SolidColorBrush(Colors.Gray);
List<Object> array = new List<Object>();
Object abc = new Object();
Start();
void loop_timer_Tick(object sender, EventArgs e)
moveDots();
void moveDots()
for (int i = _dotGroup.Count - 1; i >= 0; i--)
Dot dot = _dotGroup[i];
dot.RunFirework();
if (dot.Opacity <= 0.1)
this.Children.Remove(dot);
_dotGroup.Remove(dot);
public virtual void addDotToGroup(double x, double y)
int seed = (int)DateTime.Now.Ticks;
for (int i = 0; i < GlobalValue.FIREWORK_NUM; i++)
double size = GlobalValue.SIZE_MIN + (GlobalValue.SIZE_MAX - GlobalValue.SIZE_MIN) * GlobalValue.random.NextDouble();
byte red = (byte)(128 + (128 * GlobalValue.random.NextDouble()));
byte green = (byte)(128 + (128 * GlobalValue.random.NextDouble()));
byte blue = (byte)(128 + (128 * GlobalValue.random.NextDouble()));
double xVelocity = GlobalValue.X_VELOCITY - 2 * GlobalValue.X_VELOCITY * GlobalValue.random.NextDouble();
double yVelocity = -GlobalValue.Y_VELOCITY * GlobalValue.random.NextDouble();
Dot dot = new Dot(red, green, blue, size);
dot.X = x;
dot.Y = y;
dot.XVelocity = xVelocity;
dot.YVelocity = yVelocity;
dot.Gravity = GlobalValue.GRAVITY;
_dotGroup.Add(dot);
this.Children.Add(dot);
public virtual void Start()
_timer = new DispatcherTimer();
_timer.Interval = TimeSpan.FromMilliseconds(IntervalTime);
_timer.Tick += new EventHandler(loop_timer_Tick);
_timer.Start();
这是一个只有执行逻辑的容器,addDot用来增加粒子,moveDots是移动粒子并且检测是否消失,如果消失则从List和父结构中移除掉。
生成逻辑通过面向对象的方式实现,建立一个Colorful_FollowMouse类:
public class Colorful_FollowMouse : Colorful
public Colorful_FollowMouse()
MouseMove += new MouseEventHandler(Colorful_FollowMouse_MouseMove);
void Colorful_FollowMouse_MouseMove(object sender, MouseEventArgs e)
addDotToGroup(e.GetPosition(this).X, e.GetPosition(this).Y);
添加到MainPage中LayoutRoot.Children.Add(new Colorful_ FollowMouse ());
运行看看效果吧:)鼠标滑动一下看看
<a href="http://go.microsoft.com/fwlink/?LinkID=149156&v=3.0.40624.0"> </a>
我在工程中加入了一个Colorful_ClickMouse类,是通过点击产生粒子的操作效果,可以更换看看点击的感觉如何:)
对于一个游戏而言,如果粒子系统作的好,能够为游戏增加很多视觉乐趣,就如今天的颜色点特效,能够应用到很多程序当中,并不只是游戏,而且这个类一旦写好,就可以作为通用的方法为其他开发所用上,这个颜色点很有趣吧,以后后面咱们逐步实现更佳“绚丽”的特效,例如火焰、爆炸等等:)
本文转自nowpaper 51CTO博客,原文链接:http://blog.51cto.com/nowpaper/712440