程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> 爐石傳說 C# 開發筆記 (法術篇)

爐石傳說 C# 開發筆記 (法術篇)

編輯:C#入門知識

爐石的設計,最核心的內容是法術效果。   法術卡牌,無疑是法術的集中體現,但是,法術效果除了在法術卡牌之外,也不除不在。   隨從的戰吼,亡語,奧秘的揭示等等都是法術效果的體現。   法術卡牌在爐石裡面有很多種(200種),但是具體整理後,大約也只有10個種類,每個種類通過法術對象的指定方式,效果點數的不同排列組合,演化出了不同卡牌效果。   例如攻擊類的卡牌,  通過攻擊次數的不同(奧術飛彈是3次),攻擊對象不同(有的是只能攻擊隨從,有的只能攻擊英雄,有的兩者都可以),   攻擊方向不同(有的可以攻擊對方,有的是本方,有的是雙方),攻擊模式不同(有的是隨機對象,有的是全體,有的是指定),各種排列組合,獲得不同的法術效果。    綜上所述,一個法術效果的定義看上去是這樣的。   復制代碼        /// <summary>         /// 描述         /// </summary>         public String Description = String.Empty;         /// <summary>         /// 魔法效果         /// </summary>         public enum AbilityEffectEnum         {             /// <summary>             /// 未定義             /// </summary>             未定義,             /// <summary>             /// 攻擊類             /// </summary>             攻擊,             /// <summary>             /// 治療回復             /// </summary>             回復,             /// <summary>             /// 改變狀態             /// </summary>             狀態,             /// <summary>             /// 召喚             /// </summary>             召喚,             /// <summary>             /// 改變卡牌點數             /// </summary>             點數,             /// <summary>             /// 抽牌/棄牌             /// </summary>             卡牌,             /// <summary>             /// 變形             /// 變羊,變青蛙             /// </summary>             變形,             /// <summary>             /// 獲得水晶             /// </summary>             水晶,             /// <summary>             /// 奧秘             /// </summary>             奧秘,         }         /// <summary>         /// 法術類型         /// </summary>         public AbilityEffectEnum AbilityEffectType;         /// <summary>         /// 法術對象選擇模式         /// </summary>         public CardUtility.TargetSelectModeEnum EffictTargetSelectMode;         /// <summary>         /// 法術對象選擇角色         /// </summary>         public CardUtility.TargetSelectRoleEnum EffectTargetSelectRole;         /// <summary>         /// 法術對象選擇方向         /// </summary>         public CardUtility.TargetSelectDirectEnum EffectTargetSelectDirect;         /// <summary>         ///          /// </summary>         /// <returns></returns>         public Boolean IsNeedSelectTarget()         {             return EffictTargetSelectMode == CardUtility.TargetSelectModeEnum.指定;         }         /// 攻擊的時候:99表示消滅一個單位         /// 治療的時候:99表示完全回復一個單位         /// 抽牌的時候:表示抽牌的數量         /// <summary>         /// 效果點數(標准)         /// </summary>         public int StandardEffectPoint;         /// <summary>         /// 效果點數(實際)         /// </summary>         public int ActualEffectPoint;         /// <summary>         /// 效果回數         /// </summary>         public int StandardEffectCount;         /// <summary>         /// 效果回數(實際)         /// </summary>         public int ActualEffectCount;         /// <summary>         /// 附加信息         /// </summary>         public String AddtionInfo; 復制代碼     同時,注意到每張法術卡牌中,可能包含兩個法術效果,所以,設計的時候,每張法術卡牌可以包含兩個效果,兩個效果之間,可以是 AND 或者 OR。   (在抉擇系卡牌的時候,兩個法術效果用OR連接。)   這裡還有一個概念,法術的原子效果:   例如奧術飛彈是進行3次打擊效果。所以,一個原子法術效果就是一次打擊。   每次打擊後,整個戰場進行清算,如果觸發奧秘事件等等,都要實時計算。   對於攻擊全體地方隨從的操作,系統也會對於每次打擊效果進行實時清算。   復制代碼 using System; using System.Collections.Generic;   namespace Card.Effect {     [Serializable]     public class Ability     {         /// <summary>         /// 第一定義         /// </summary>         public EffectDefine FirstAbilityDefine = new EffectDefine();         /// <summary>         /// 第二定義         /// </summary>         public EffectDefine SecondAbilityDefine = new EffectDefine();         /// <summary>         /// 第一定義 和 第二定義 的連接方式         /// </summary>         public Card.CardUtility.EffectJoinType JoinType = Card.CardUtility.EffectJoinType.None;         /// <summary>         /// 是否需要抉擇         /// </summary>         /// <returns></returns>         public Boolean IsNeedSelect()         {             return JoinType == CardUtility.EffectJoinType.OR;         }         /// <summary>         /// 分解獲得效果列表         /// </summary>         /// <param name="IsFirstEffect">需要抉擇的時候,是否選擇第一項目</param>         /// <returns>最小效果列表</returns>         public List<Card.Effect.EffectDefine> GetSingleEffectList(Boolean IsFirstEffect)         {             //這裡都轉化為1次效果             //例如:奧術飛彈的3次工具這裡將轉為3次效果             //這樣做的原因是,每次奧術飛彈攻擊之後,必須要進行一次清算,是否有目標已經被摧毀             //如果被摧毀的話,無法攻擊這個目標了,             //同時,如果出現亡語的話,亡語可能召喚出新的可攻擊目標             List<Card.Effect.EffectDefine> EffectLst = new List<Card.Effect.EffectDefine>();             if (IsNeedSelect())             {                 if (IsFirstEffect)                 {                     for (int i = 0; i < FirstAbilityDefine.ActualEffectCount; i++)                     {                         EffectLst.Add(FirstAbilityDefine);                     }                 }                 else                 {                     for (int i = 0; i < SecondAbilityDefine.ActualEffectCount; i++)                     {                         EffectLst.Add(SecondAbilityDefine);                     }                 }             }             else             {                 for (int i = 0; i < FirstAbilityDefine.ActualEffectCount; i++)                 {                     EffectLst.Add(FirstAbilityDefine);                 }                 if (SecondAbilityDefine.AbilityEffectType !=  EffectDefine.AbilityEffectEnum.未定義)                 {                     for (int i = 0; i < SecondAbilityDefine.ActualEffectCount; i++)                     {                         EffectLst.Add(SecondAbilityDefine);                     }                 }             }             return EffectLst;         }         /// <summary>         /// 初始化         /// </summary>         public void Init()         {             if (FirstAbilityDefine != null) FirstAbilityDefine.Init();             if (SecondAbilityDefine != null) SecondAbilityDefine.Init();                     }     } } 復制代碼 法術的資料整理:   整個資料在整理的時候都保存為XLS文件,然後通過輔助程序,轉化為XML。   程序運行的時候,將XML反序列化成對象。   A000XXX開始的都是實際的法術卡牌。可以作為玩家的手牌   A100XXX都是輔助卡牌,用戶戰吼和亡語等等。   A200XXX都是英雄技能。奧秘計算的時候,不算本方施法,不能享受法術效果加成和施法成本的減少。       施法邏輯:   第一段代碼是施法的入口代碼。   通過 game.UseAbility施法,獲得施法的結果數組。這裡包括了法術的各個動作。這些動作將作為對方客戶端復原的法術的依據。   例如奧術飛彈的施法結果可能是這樣的   ATTACK#YOU#2#1           //對方的2號位隨從1點傷害   ATTACK#YOU#1#1          //對方的1號位隨從1點傷害   ATTACK#YOU#2#1          //對方的2號位隨從1點傷害   這些結果將發送到對方客戶端,進行戰場的同步操作。   然後觸發 本方施法事件,   例如 法術浮龍會相應這個事件,攻擊力 +1,有些奧秘會被揭示,產生效果   復制代碼                     ActionCodeLst.Add(UseAbility(CardSn));                     //初始化 Buff效果等等                     Card.AbilityCard ablity = (Card.AbilityCard)CardUtility.GetCardInfoBySN(CardSn);                     ablity.CardAbility.Init();                     var ResultArg = game.UseAbility(ablity, ConvertPosDirect);                     if (ResultArg.Count != 0)                     {                         ActionCodeLst.AddRange(ResultArg);                         //英雄技能的時候,不算[本方施法] A900001 幸運幣                         if (CardSn.Substring(1, 1) != "2") ActionCodeLst.AddRange(game.MySelf.RoleInfo.BattleField.觸發事件(MinionCard.事件類型列表.本方施法, game));                     }                     else                     {                         ActionCodeLst.Clear();                     } 復制代碼 具體施法的代碼比較冗長和復雜:   這裡還是對於施法前的一些整理工作,   具體的施法動作,還是要交給各個  XXXXEffect處理。每個XXXXXEffect負責某種法術的施法工作。   這裡有個有趣的話題:   法術強度本意是增加法術卡的總傷。以奧術飛彈為例,法術強度+1會令奧術飛彈多1發傷害,而非單發傷害+1。法術強度不影響治療效果。 復制代碼         /// <summary>         /// 使用法術         /// </summary>         /// <param name="card"></param>         /// <param name="ConvertPosDirect">對象方向轉換</param>         public List<String> UseAbility(Card.AbilityCard card, Boolean ConvertPosDirect)         {             List<String> Result = new List<string>();             //法術傷害             if (MySelf.RoleInfo.BattleField.AbilityEffect != 0)             {                 //法術強度本意是增加法術卡的總傷。以奧術飛彈為例,法術強度+1會令奧術飛彈多1發傷害,而非單發傷害+1。法術強度不影響治療效果。                 switch (card.CardAbility.FirstAbilityDefine.AbilityEffectType)                 {                     case EffectDefine.AbilityEffectEnum.攻擊:                         if (card.CardAbility.FirstAbilityDefine.StandardEffectCount == 1)                         {                             card.CardAbility.FirstAbilityDefine.ActualEffectPoint = card.CardAbility.FirstAbilityDefine.StandardEffectPoint + MySelf.RoleInfo.BattleField.AbilityEffect;                         }                         else                         {                             card.CardAbility.FirstAbilityDefine.ActualEffectCount = card.CardAbility.FirstAbilityDefine.StandardEffectCount + MySelf.RoleInfo.BattleField.AbilityEffect;                         }                         break;                     case EffectDefine.AbilityEffectEnum.回復:                         card.CardAbility.FirstAbilityDefine.ActualEffectPoint = card.CardAbility.FirstAbilityDefine.StandardEffectPoint + MySelf.RoleInfo.BattleField.AbilityEffect;                         break;                 }                 if (card.CardAbility.SecondAbilityDefine.AbilityEffectType != EffectDefine.AbilityEffectEnum.未定義)                 {                     switch (card.CardAbility.SecondAbilityDefine.AbilityEffectType)                     {                         case EffectDefine.AbilityEffectEnum.攻擊:                             if (card.CardAbility.SecondAbilityDefine.StandardEffectCount == 1)                             {                                 card.CardAbility.SecondAbilityDefine.ActualEffectPoint = card.CardAbility.SecondAbilityDefine.StandardEffectPoint + MySelf.RoleInfo.BattleField.AbilityEffect;                             }                             else                             {                                 card.CardAbility.SecondAbilityDefine.ActualEffectCount = card.CardAbility.SecondAbilityDefine.StandardEffectCount + MySelf.RoleInfo.BattleField.AbilityEffect;                             }                             break;                         case EffectDefine.AbilityEffectEnum.回復:                             card.CardAbility.SecondAbilityDefine.ActualEffectPoint = card.CardAbility.SecondAbilityDefine.StandardEffectPoint + MySelf.RoleInfo.BattleField.AbilityEffect;                             break;                     }                 }             }             Card.CardUtility.PickEffect PickEffectResult = CardUtility.PickEffect.第一效果;             if (card.CardAbility.IsNeedSelect())             {                 PickEffectResult = PickEffect(card.CardAbility.FirstAbilityDefine.Description, card.CardAbility.SecondAbilityDefine.Description);                 if (PickEffectResult == CardUtility.PickEffect.取消) return new List<string>();             }             var SingleEffectList = card.CardAbility.GetSingleEffectList(PickEffectResult == CardUtility.PickEffect.第一效果);             for (int i = 0; i < SingleEffectList.Count; i++)             {                 Card.CardUtility.TargetPosition Pos = new CardUtility.TargetPosition();                 var singleEff = SingleEffectList[i];                 singleEff.StandardEffectCount = 1;                 if (singleEff.IsNeedSelectTarget())                 {                     Pos = GetSelectTarget(singleEff.EffectTargetSelectDirect, singleEff.EffectTargetSelectRole, false);                     //取消處理                     if (Pos.Postion == -1) return new List<string>();                 }                 else                 {                     if (ConvertPosDirect)                     {                         switch (singleEff.EffectTargetSelectDirect)                         {                             case CardUtility.TargetSelectDirectEnum.本方:                                 singleEff.EffectTargetSelectDirect = CardUtility.TargetSelectDirectEnum.對方;                                 break;                             case CardUtility.TargetSelectDirectEnum.對方:                                 singleEff.EffectTargetSelectDirect = CardUtility.TargetSelectDirectEnum.本方;                                 break;                             case CardUtility.TargetSelectDirectEnum.雙方:                                 break;                             default:                                 break;                         }                     }                 }                 Result.AddRange(EffectDefine.RunSingleEffect(singleEff, this, Pos, Seed));                 Seed++;                 //每次原子操作後進行一次清算                 //將亡語效果也發送給對方                 Result.AddRange(Settle());             }             return Result;         }         /// <summary>

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