C#開發WPF/Silverlight動畫及游戲系列教程(Game Course):(三十) 大法師 – 華麗經典之輪回
從紅白機到PS3,從286到奔騰N核;曾記否孩時的回憶?與玩伴並肩闖關。往日的經典已化為過眼煙雲,那些神話般的游戲角色是否仍徘徊於你的夢裡?UO開創了網絡游戲新時代,虛擬世界敞開了魔幻華麗的心扉;於是我堅定了信念,用自己的雙手去開啟這道華麗的輪回!
在傳統的MMORPG游戲中,魔法種類大致分為:單攻魔法、群攻魔法、輔助魔法、地圖魔法等,其中單攻魔法又可以細分為帶過程的(如飛箭),不帶過程的(如閃電),多段單體等等;群攻魔法就更多了,以圓形區域群攻為主流,還有多邊形區域群攻,穿梭群攻,多段群攻等等;輔助魔法主要就是BUFF加成與減持,如加血、加防、加攻、加防護罩等等;地圖魔法則以陷阱為主要代表,還有其他的例如瞬移等等。
本節我將為大家講解最華麗且又是最易於實現的圓形范圍群攻魔法的實現。
魔法控件是實現魔法的前提,因此我們首先建立一個名為QXMagic的魔法控件,並為之賦予一些屬性(具體內容看源碼)。這些屬性都有注釋這裡就不詳講了;其中比較關鍵的是每個魔法同樣擁有一個生命線程,用於播放及觸發攻擊效果,因為魔法從產生到結束是由一系列幀組成的:
有了魔法控件,接著就是考慮該如何實現功能。在通常的MMORPG中,我們主動施放魔法有兩個途徑:鼠標右鍵或鍵盤快捷鍵,過程其實大同小異,那麼本節就以鼠標右鍵施放魔法為例進行講解。
首先我們需要為游戲窗體注冊鼠標右鍵事件,然後在裡面這樣寫:
private void Window_MouseRightButtonDown(object sender, MouseButtonEventArgs e) {
if (Leader.Action == Actions.Death) { return; }
……
Leader.MagicTarget = p;
//假如點擊的地方太遠則先跑到施法范圍再施法,否則直接施法
if (Super.InCircle(Leader.X, Leader.Y, p.X, p.Y, Leader.MagicRange)) {
ChangeDirection(Leader, p);
DoMagic(Leader);
} else {
Leader.IsMagicMove = true;
double n = Math.Sqrt(Math.Pow(p.Y - Leader.Y, 2) + Math.Pow(p.X - Leader.X, 2));
double x = p.X - (p.X - Leader.X) * Leader.MagicRange / n;
double y = p.Y - (p.Y - Leader.Y) * Leader.MagicRange / n;
MoveTo(Leader, new Point(x, y));
}
}
當我們在地圖上點擊鼠標右鍵時,首先判斷主角與施放點之間的距離是否在施法距離內,如果是則放出魔法,否則我們計算出能該方向上與釋放點距離剛好為主角施法距離的點,然後主角向該點跑去,到達後再施法:
同時,我將法術的參數定義在xml參數文件中:
<Magics>
<Magic Code="0" HasDirection="false" FrameNum="19" EffectiveFrame="4" SingleWidth="320" SingleHeight="344" Radius="140" CenterX="154" CenterY="214">
<Level Value="1" ATK="120" Consumption="10"/>
<Level Value="2" ATK="160" Consumption="15"/>
<Level Value="3" ATK="200" Consumption="20"/>
<Level Value="4" ATK="240" Consumption="25"/>
<Level Value="5" ATK="280" Consumption="30"/>
<Level Value="6" ATK="320" Consumption="35"/>
<Level Value="7" ATK="380" Consumption="40"/>
<Level Value="8" ATK="500" Consumption="50"/>
<Level Value="9" ATK="700" Consumption="60"/>
</Magic>
……
<Magics>
大家可以看到,每個法術都擁有一個法術代號用於法術標識(上面的法術代號為Code="0")並且分列出法術各等級的附加攻擊力(ATK)與消耗的魔法值(Consumption),然後在施放魔法之前首先判斷施法者的魔法值與該魔法的魔法消耗值之間的大小關系以判斷施法者當前魔法值是否足夠支持施法者施法:
……
if (VSpell < consumption) {
Super.ShowText(this, true, true, "NotEnough", "魔法值不足", 22, Colors.Green, 0.5);
}
……
這樣施法前的步驟就完成了,下面就是傷害計算與結果處理。
傷害計算與前面章節中的物理攻擊傷害計算很類似,只是由於本例魔法為群攻魔法,所以需要循環遍歷所有在魔法攻擊范圍內(以魔法有效距離Radius為半徑的圓內)的所有敵對精靈,然後進行攻防計算最終產生傷害並輸出顯示出來:
並且,主角在殺死怪物後會獲得怪物的經驗值,同樣的需要顯示輸出:
額外的,主角自身的經驗值屬性也同時增加,並且當達到下一級所需的升級經驗時即會觸發升級效果,每一級所需的經驗值我一並放在xml系統參數文件中:
<LevelUp>
<Experience Level="0" Value="0" />
<Experience Level="1" Value="0" />
<Experience Level="2" Value="400" />
<Experience Level="3" Value="1280" />
<Experience Level="4" Value="2720" />
<Experience Level="5" Value="4800" />
<Experience Level="6" Value="7600" />
<Experience Level="7" Value="11200" />
<Experience Level="8" Value="15680" />
<Experience Level="9" Value="21120" />
<Experience Level="10" Value="27600" />
<Experience Level="11" Value="35200" />
<Experience Level="12" Value="44000" />
<Experience Level="13" Value="54080" />
<Experience Level="14" Value="65520" />
<Experience Level="15" Value="78400" />
<Experience Level="16" Value="92800" />
<Experience Level="17" Value="108800" />
<Experience Level="18" Value="126480" />
<Experience Level="19" Value="145920" />
<Experience Level="20" Value="167200" />
<Experience Level="21" Value="190400" />
<Experience Level="22" Value="215600" />
<Experience Level="23" Value="242880" />
<Experience Level="24" Value="272320" />
<Experience Level="25" Value="304000" />
……
</LevelUp>
該經驗值表是參考魔獸世界的,暫時添加了25級。在游戲初始化時即加載進內存的public static int[] LevelUpExperienceList數組中。關於獲取經驗值並升級的相關邏輯我們可以這樣寫:
/// <summary>
/// 增加經驗值
/// </summary>
/// <param name="spirit">對象精靈</param>
/// <param name="value">增加值</param>
public static void EarnExperience(QXSpirit spirit, int value) {
//如果OL版還需要加入判斷殺對方的人是否為玩家
if (spirit.VExperience + value >= LevelUpExperienceList[spirit.VLevel + 1]) {
//等級+1
spirit.VLevel += 1;
//多出來的經驗
value = spirit.VExperience + value - LevelUpExperienceList[spirit.VLevel];
//當前經驗歸0
spirit.VExperience = 0;
//再重復檢驗一次,防止經驗超過幾級
EarnExperience(spirit, value);
} else {
spirit.VExperience += value;
}
}
這樣就完成了所有從准備施法->施法前判斷->傷害處理->經驗值獲取這一系列完美施法流程。在本節中由於引入了群攻魔法,因此我增加了幾個按鈕用於調試:
至於其他的如單體魔法、輔助魔法等如果時間充裕的話我會在後續章節中進行補充。
這就是夢想,一個狂熱的游戲愛好對曾經輝煌的直著。
夜已深,思緒再次回到了過去,無數經典縷上心頭。與往昔素未謀面的戰友們並肩戰斗,暢快淋漓。如今的網游已索然無謂,抄襲到了一定的深度與骷髅骨架毫無區別。緬懷之余仍有一絲絲的期待 – 只因夢依舊。
出處:http://alamiye010.cnblogs.com/