程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> 關於C# >> C#開發WPF/Silverlight動畫及游戲系列教程(Game Course):(三十二)

C#開發WPF/Silverlight動畫及游戲系列教程(Game Course):(三十二)

編輯:關於C#

C#開發WPF/Silverlight動畫及游戲系列教程(Game Course):(三十二) 雷、混、冰、毒、火、風 - 幻化中的魔法魅力

本節,我將為大家演示如何為游戲中的魔法增加華麗的附加屬性。

第一步,定義規則:

1)定義魔法附加屬性分類:在本教程示例游戲中,我將魔法附加屬性定義為6類:雷、混、冰、毒、火、風,為什麼要以這樣無規律的方式去命名?因為是教程,我們需要學習的是如何實現對應效果,此6類屬性算是目前網游中最流行的六大魔法屬性,如果大家都掌握了,無論是中國式5行還是諸如其他的風格設計,均能做到游刃有余。

2)定義魔法附加屬性功能及效果:

雷 – 麻痺 – 精靈麻痺(被附加該屬性精靈將無法動彈)

混 – 混亂 – 精靈混亂(被附加該屬性精靈將亂跑)

冰 – 冰凍 – 精靈減速(被附加該屬性精靈移動速度、物理攻擊速度、施法速度均減慢)

毒 – 中毒 – 精靈中毒(被附加該屬性精靈每秒持續減生命值)

火 – 燃燒 – 精靈灼傷(被附加該屬性精靈所有防御類屬性值降低)

風 – 虛弱 – 精靈弱化(被附加該屬性精靈所有攻擊類屬性值降低)

對應枚舉:

<ExtraItems>
 <Item Value="0" Src="Interface/Icon/Extra0.png" Name="麻痺" Description="效果:無法動彈" />
 <Item Value="1" Src="Interface/Icon/Extra1.png" Name="混亂" Description="效果:亂跑" />
 <Item Value="2" Src="Interface/Icon/Extra2.png" Name="冰凍" Description="效果:速度減緩" />
 <Item Value="3" Src="Interface/Icon/Extra3.png" Name="中毒" Description="效果:持續傷血" />
 <Item Value="4" Src="Interface/Icon/Extra4.png" Name="燃燒" Description="效果:所有防御屬性值降低" />
 <Item Value="5" Src="Interface/Icon/Extra5.png" Name="虛弱" Description="效果:所有攻擊屬性值降低" />
</ExtraItems>

3)定義魔法附加屬性視覺表現:

麻痺 – 雪白

混亂 – 黃色

冰凍 – 天藍

中毒 – 綠色

燃燒 – 紅色

虛弱 – 灰色

第二步,具體實現:

首先我們需要考慮的是如何實現精靈的變色,即如何改變精靈圖片源的色相。在很多編程語言中都有現成的類庫可以調用,但是在目前的 WPF/Silverlight中,至今我未能找到一種直接改變圖片色相的方法。但這並不意味著WPF/Silverlight就此束手無策了,WPF /Silverlight的強大圖形表現能力讓我想到了控件蒙版,既然直接的不行,那麼我們就來間接的。

接下來我們為精靈控件QXSpirit的表現層xaml中添加如下一個矩形蒙版:

<Rectangle Name="BodyMask" Opacity="0.3" Visibility="Collapsed"  Panel.ZIndex="1">
 <Rectangle.OpacityMask>
  <ImageBrush x:Name="BodyMaskSource"></ImageBrush>
 </Rectangle.OpacityMask>
</Rectangle>

此精靈身體蒙版默認情況下是不可見的,它的透明度為0.3,並且ZIndex必須覆蓋於精靈之上。只要我們在後台cs中將此蒙版寬高與精靈圖片源寬高時刻保持聯動一致,這樣,當需要的時候通過設置BodyMaskSource.ImageSource = Body.Source;然後根據前文中相應的視覺表現賦予蒙版Fill顏色,並將之顯示出來。即可以輕松的模仿實現精靈圖片源的色相改變。

實現色相改變原來如此的簡單,只是在性能上來說等於增加了多余的消耗,但這並不是長期的,僅僅當精靈被施與附加屬性後才會短時間變色,在恢復正常後即將蒙版隱藏,Collapsed將不再占用界面資源。

完成了界面,剩下的就是實現邏輯。魔法附加屬性不可能是永久的,就好比中毒有個中毒持續時間,麻痺有麻痺持續時間等等,除了那些即效魔法外,本文介紹的這6類魔法附加屬性均為持續性的。因此,我通過為精靈控件添加一個ExtraTime屬性來記錄精靈被施與魔法附加屬性的持續時間:

double[] _ExtraTime = new double[6];
/// <summary>
/// 獲取或設置被附加屬性對應持續時間,與枚舉ExtraAttributes一一對應
/// </summary>
public double[] ExtraTime {
 get { return _ExtraTime; }
 set { _ExtraTime = value; }
}

該時間數組為double類型,分別與枚舉ExtraAttributes一一對應。通過如此設置,我們可以輕松的借助主界面間隔為1秒的輔助線程 AuxiliaryThread去同步更新它們(每秒-1),並實現例如中毒每秒傷血等相關業務邏輯,可謂水到渠成,無縫銜接。

由於此6種附加屬性實現的相應功能相差較大,基本無統一的規律可尋,因此下面我將按類型分類進行講解:

1)雷:

本示例教程中我將之定義為使精靈無法動彈,無法動彈一方面意味著它自身動作被鎖定,另一方面表示它無法移動。代碼實現即:

if (enemy.VLife > injure) {
 enemy.BodyMaskColor = new SolidColorBrush(Colors.Snow);
 enemy.BodyMaskSource.ImageSource = enemy.Body.Source;
 enemy.TimerState = TimerStates.Stop;
 Super.PauseSpiritStoryboard(enemy);
 } else {
  enemy.TimerState = TimerStates.Start;
}

同時需要為直線移動方法與A*移動方法開頭添加一個判斷: if (spirit.ExtraTime[0] > 0) { return; }

測試效果截圖:

2)混

本示例教程中我將之定義為使精靈隨機亂向跑動。此附加屬性非常有趣,實現起來也很簡單,我們只需將精靈的移動目標進行重新隨機更改,即為直線移動方法與A*移動方法開頭添加如下一個判斷處理即可:

if (spirit.ExtraTime[1] > 0) {
 p = new Point(p.X + (p.X > spirit.X ? -random.Next(200) : random.Next(200)),
 p.Y + (p.Y > spirit.Y ? -random.Next(200) : random.Next(200)));
}

測試效果截圖:

3)冰:

本示例教程中我將之定義為使精靈移動速度、攻擊速度、施法速度減速。大家回憶一下第二十八節中關於精靈屬性的設計,其中精靈的所有類型屬性均由4個部分組成,以下為這3個速度屬性的構造定義:

/// <summary>
/// 獲取跑步速度(每移動一個單元格的花費時間,越小越快)
/// </summary>
public double VRunSpeed {
 get { return ABase[5] + Equip[5] + Buff[5] - VAgile * Coefficient[5]; }
}
/// <summary>
/// 獲取物攻速度(越小越快)
/// </summary>
public double VAttackSpeed {
 get { return ABase[6] + Equip[6] + Buff[6] - VAgile * Coefficient[6]; }
}
/// <summary>
/// 獲取施法速度(越小越快)
/// </summary>
public double VMagicSpeed {
 get { return ABase[7] + Equip[7] + Buff[7] - VAgile * Coefficient[7]; }
}

其中的Buff即為附加屬性影響的部分。了解了原理,將之轉換成機器語言即為:

enemy.Buff[5] = enemy.ExtraEffect[magic.ExtraAttribute];
enemy.Buff[6] = enemy.ExtraEffect[magic.ExtraAttribute];
enemy.Buff[7] = enemy.ExtraEffect[magic.ExtraAttribute];

當判斷冰凍持續時間減為0後,我們只需更新這3個Buff值歸0即可。是不是很方便?嘿嘿,同時也證明了第二十八節我對精靈屬性結構設計定義的正確性。

測試效果截圖:

4)毒:

本示例教程中我將之定義為精靈每秒持續傷血。此效果實現起來更簡單了,只需要在主界面間隔為1秒的輔助線程計時器中對中毒時間是否大於0進行判斷,然後進行相應的傷害處理即可;並且其他的所有附加屬性的時間減少均寫在該方法內:

//同步激發精靈附加屬性效果
for (int i = 0; i < Carrier.Children.Count; i++) {
 if (Carrier.Children[i] is QXSpirit) {
  QXSpirit spirit = Carrier.Children[i] as QXSpirit;
  if (spirit.VLife != 0) {
   for (int j = 0; j < spirit.ExtraTime.Count(); j++) {
     if (spirit.ExtraTime[j] > 0) {
      //中毒則每秒傷血
      if (j == 3) {
        Super.DoInjure(Find(spirit.ExtraSpirit), spirit, spirit.ExtraEffect[j]);
      }
//持續時間減少
      spirit.ExtraTime[j] = spirit.ExtraTime[j] - AuxiliaryThread.Interval.Seconds;
      if (spirit.ExtraTime[j] <= 0) {
       //移除附加屬性效果
       Super.RemoveExtraEffect(spirit, j);
      }
     }
   }
  }
 }
}

測試效果截圖:

5)火:

本示例教程中我將之定義為降低精靈所有防御類屬性值。類似於冰的效果,處理時只需將物理防御力的Buff[9]、隔擋率的Buff[10]、魔法防御力的Buff[12]減少對應的火攻擊值即可:

enemy.Buff[9] = -enemy.ExtraEffect[magic.ExtraAttribute];
enemy.Buff[10] = -enemy.ExtraEffect[magic.ExtraAttribute];
enemy.Buff[12] = -enemy.ExtraEffect[magic.ExtraAttribute];

解除時3者歸0。

測試效果截圖:

6)風:

本示例教程中我將之定義為降低精靈所有攻擊類屬性值:

enemy.Buff[1] = -enemy.ExtraEffect[magic.ExtraAttribute];
enemy.Buff[2] = -enemy.ExtraEffect[magic.ExtraAttribute];
enemy.Buff[13] = -enemy.ExtraEffect[magic.ExtraAttribute];
enemy.Buff[14] = -enemy.ExtraEffect[magic.ExtraAttribute];
enemy.Buff[15] = -enemy.ExtraEffect[magic.ExtraAttribute];

解除時5者歸0。

該類型魔法影響對象精靈的最小物理攻擊的Buff[1]、最大物理攻擊的Buff[2]、最小魔法攻擊的Buff[13]、最大魔法攻擊的Buff[14]、暴擊率的Buff[15]等。

測試效果截圖:

非常酷的6大魔法附加屬性,基本上囊括了目前主流的魔法效果。好比麻痺,它又可以延伸出定身、眩暈、凍結等效果;冰凍同樣也可以分解成減慢移動速度、減慢攻速、增加魔法詠唱時間等等。

魔法世界的幻化莫測時刻讓我回味。教程至此已完美的诠釋了我曾經制作的WPF-ARPG游戲引擎,更有過之而無不及~後期的教程我將更深入的對目前的引擎進行補充、完善、優化!敬請關注。

出處:http://alamiye010.cnblogs.com/

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved