天天躁日日躁狠狠躁AV麻豆-天天躁人人躁人人躁狂躁-天天澡夜夜澡人人澡-天天影视香色欲综合网-国产成人女人在线视频观看-国产成人女人视频在线观看

Silverlight 2.5D RPG游戲技巧與特效處理:(九)粒子系統

  粒子系統通常用于三維場景中進行真實環境模擬,比如第四節的天氣系統。天氣的實現是粒子系統最重要的應用領域之一,所有的一切無論是云、雨、霧,還是落葉、隕石及閃電,都可視作基礎粒子;除此之外,游戲中常常還會用到粒子系統來渲染像發光、軌跡等抽象效果。當然,有時簡單并不意味著就不能締造奇跡,比如本節大家將要看到的就是基于簡單粒子系統所創建的當下主流2.5D RPG中極其拉風之裝備粒子發散動畫特效。

   一提到Silverlight中的粒子,首先想到的肯定是WriteableBitmap。沒錯,今天的主角就是它,讓人又愛又恨的WriteableBitmap。愛,因為它可以對Silverlight中任意UI對象進行基于像素級別的處理,這意味著只要想得出的效果肯定能實現;正因如此,對其恨之入骨則因為WriteableBitmap在目前的版本中還暫時無法得到GPU硬件加速的支持,其功能偏少,性能也有待進一步提高。

  僅當為了Silverlight 5 的登場打基礎,借鑒《降龍之劍》中的裝備粒子系統,我們同樣可以通過非常簡單的代碼編寫出極度拉風的粒子發射動畫特效。

  于是我們得首先準備基礎粒子素材,比如希望武器會冒著火光,亦或者你希望鎧甲能寒冰四散等,那么我們每樣準備3張或更多的圖片,通過隨即的方式呈現便可達到相當逼真的效果:

  接下來的問題是這些粒子該如何以精確的裝備部件實體區域為起點進行發射?

  用WriteableBitmap對每幀圖片進行寬*高數量像素的逐個掃描?試想如果角色的尺寸是500*500=250000,那么每間隔幾百毫秒都要遍歷幾十萬的像素,UI線程不卡死才怪(順便提一下,UI卡死的罪魁禍首就是循環,在UI線程中應盡量減少循環次數或巧妙的進行分解與規避)。其實我們完全可以采用隨機抽樣的方案,比如每次對其中的1000個像素進行抽樣檢查,當其A值(透明度)不為0時則表示該像素正處于裝備部件的實體區域中。接下來便可仿造流光追影的類似效果,通過WriteableBitmap對目標裝備部件首先進行復制,然后按照如上方式隨機抽取部分裝備實體上的粒子進行發射飄散:

/// <summary>
/// 顯示風中粒子
/// </summary>
/// <param name="role">所修飾角色</param>
/// <param name="equipType">所參照的裝備</param>
/// <param name="particleType">粒子類型</param>
/// <param name="color">顏色</param>
/// <param name="amount"></param>
public void ShowWindParticles(Hero role, EquipTypes equipType, ParticleTypes particleType, Color color, double amount) {
int distance = 0;
double speed = 0;
if (role.Action == Actions.Stop) {
distance
= 40;
speed
= RandomSeed.Next(2000, 3000) * 0.01;
}
else {
distance
= 40;
speed
= RandomSeed.Next(1000, 1500) * 0.01;
}
int halfDistance = distance / 2;
int obliqueDistance = distance * 2 / 3;
string particleName = string.Empty;
switch (particleType) {
case ParticleTypes.Normal:
particleName
= "Particle";
break;
case ParticleTypes.Smoke:
particleName
= "Smoke";
break;
case ParticleTypes.Ice:
particleName
= "Ice";
break;
case ParticleTypes.Spark:
particleName
= "Spark";
break;
}
Dispatcher.BeginInvoke(
delegate {
ObjectBase equip
= role.EquipEntity(equipType);
WriteableBitmap writeableBitmap
= new WriteableBitmap(equip, null);
lock (writeableBitmap) {
writeableBitmap.Invalidate();
int z = 0;
if (equipType == EquipTypes.Weapon) {
z
= role.Z + equip.Z;
}
else {
z
= (role.Direction == Directions.North || role.Direction == Directions.NorthEast || role.Direction == Directions.NorthWest) ? role.Z : role.Z - 20;
}
Point position
= equipType == EquipTypes.Overall ? role.Center : equip.Position;
Point2D destination
= new Point2D();
MonoChrome monoChrome
= new MonoChrome() { FilterColor = color };
switch (role.Direction) {
case Directions.North:
destination.X
= 0; destination.Y = RandomSeed.Next(halfDistance, distance);
break;
case Directions.NorthEast:
destination.X
= -RandomSeed.Next(halfDistance, obliqueDistance); destination.Y = RandomSeed.Next(halfDistance, obliqueDistance);
break;
case Directions.East:
destination.X
= -RandomSeed.Next(halfDistance, distance); destination.Y = 0;
break;
case Directions.SouthEast:
destination.X
= -RandomSeed.Next(halfDistance, obliqueDistance); destination.Y = -RandomSeed.Next(halfDistance, obliqueDistance);
break;
case Directions.South:
destination.X
= 0; destination.Y = -RandomSeed.Next(halfDistance, distance);
break;
case Directions.SouthWest:
destination.X
= RandomSeed.Next(halfDistance, obliqueDistance); destination.Y = -RandomSeed.Next(halfDistance, obliqueDistance);
break;
case Directions.West:
destination.X
= RandomSeed.Next(halfDistance, distance); destination.Y = 0;
break;
case Directions.NorthWest:
destination.X
= RandomSeed.Next(halfDistance, obliqueDistance); destination.Y = RandomSeed.Next(halfDistance, obliqueDistance);
break;
}
for (int i = 0; i < amount; i++) {
int x = RandomSeed.Next(0, writeableBitmap.PixelWidth);
int y = RandomSeed.Next(0, writeableBitmap.PixelHeight);
byte[] bytes = BitConverter.GetBytes(writeableBitmap.Pixels[writeableBitmap.PixelWidth * y + x]);
if (bytes[3] != 0) {
Particle particle
= new Particle() { Effect = monoChrome, Z = z, Source = GlobalMethod.GetProjectImage(string.Format("UI/{0}{1}.png", particleName, RandomSeed.Next(0, 3))) };
space.Children.Add(particle);
EventHandler handler
= null;
particle.Disposed
+= handler = (s, e) => {
Particle p
= s as Particle;
p.Disposed
-= handler;
space.Children.Remove(p);
};
particle.Move(
new Point(role.Position.X - position.X + x, role.Position.Y - position.Y + y), new Point(role.Position.X - position.X + x + destination.X, role.Position.Y - position.Y + y + destination.Y), speed, MoveModes.Opacity);
}
}
}
});
}

NET技術Silverlight 2.5D RPG游戲技巧與特效處理:(九)粒子系統,轉載需保留來源!

鄭重聲明:本文版權歸原作者所有,轉載文章僅為傳播更多信息之目的,如作者信息標記有誤,請第一時間聯系我們修改或刪除,多謝。

主站蜘蛛池模板: 国产精品一区二区三区四区五区 | 久久草这在线观看免费 | 国产精品无需播放器 | 亚洲AV蜜桃永久无码精品红樱桃 | 亚洲 无码 制服 日韩 | 超碰99热在线精品视频 | 亚洲色婷婷久久精品AV蜜桃 | 免费国产久久拍久久爱 | 自拍视频亚洲综合在线精品 | 手机在线看片欧美亚洲 | 亚洲欧美免费无码专区 | 男人桶爽女人 | 国产精品免费大片 | 高H内射NP古文 | 高清mv视频免费观看 | 99视频在线观看免费视频 | 日本妈妈xxxx | 漂亮的av女演员 | jjzz动漫| 国产在线观看免费观看不卡 | 国产精品久久久久影院嫩草 | 久久精品视频在线直播6 | 添加一点爱与你电视剧免费观看 | 香蕉人人超人人超碰超国产 | 第七色 夜夜撸 | 国产精品18久久久久久欧美 | 色橹| 最近更新2019中文字幕免费 | 日韩精品久久日日躁夜夜躁影视 | 精品国产品在线18年 | 亚洲 欧美 清纯 校园 另类 | 99国产精品欲AV蜜桃臀麻豆 | 天天射天天爱天天干 | 国产传媒麻豆剧精品AV | 国产精品久久人妻无码蜜 | 久久99re66热这里只有精品 | 欧美精品亚洲精品日韩专区一 | 特污兔午夜影视院 | 精品久久久噜噜噜久久久app | 99久久久久国产精品免费 | 国产电影无码午夜在线播放 |