[轉] 評 WOW技能天賦設計

来源:http://www.cnblogs.com/jielesi/archive/2016/10/27/6005712.html
-Advertisement-
Play Games

這個問題是不可迴避的 ...


本文轉至:http://bbs.chinaunix.net/thread-1692302-8-1.html
(只作轉載, 不代表本站和博主同意文中觀點或證實文中信息)

再比如,傳說中的面向對象本該大顯神威的游戲領域——就說流行的WOW吧。

這個游戲有10個職業,10個種族,每個種族都有自己的幾個特有種族天賦(這個種族天賦還可能根據職業有所不同,比如血精靈);每個職業有幾十甚至上百種不同的技能/法術,這些技能有近戰技能,有遠程技能;有的技能會對敵方造成傷害或不良狀態,有的技能能給己方隊友加上好的狀態或治療隊友;而且很多這類技能還會根據目標的狀態切換不同的效果;有些技能是單體效果,有些技能是光環效果(又分為對地方造成光環效果還是對己方兩種,也可能兩者兼備),而另一些技能是地圖範圍效果(如烈焰風暴是一個圓形區域;冰錐術是一個錐形區域;特別的,順劈斬是在當前攻擊目標旁邊不超過5碼的另一個敵對目標——某個boss的順劈斬更強,它會從第一個目標傳遞幾十個目標,總傳遞距離可以達到誇張的幾百碼;並且這個傷害也是各有特色的:戰士的順劈斬是每個目標傷害固定,有些boss的則是同時挨打的人越多傷害越低,但還有個變態boss卻是被打的人越多傷害越高……);大多數技能還可以通過天賦雕文強化/改變的面目全非(比如插一個雕文,法師的火球就不會造成持續傷害但施法速度增加;點一個天賦,法師的冰冷減速效果就會降低對方受到的治療效果;點某個天賦,盜賊的某些技能攻擊就會延長自身提升攻擊速度這個狀態的持續時間,等等);還有很多技能是因為學習了某個專業或裝備/持有某個物品而得到(比如,學了採藥,就可以得到生命之血這個技能,每3分鐘可用,能夠在若幹秒內回覆你若幹生命值——這個技能和採藥技能等級掛鉤,但很可能接下來的某個版本,就會再和玩家的生命上限值掛鉤,以避免它像現在一樣,被玩家斥為廢柴技能);另外,不同等級的技能可能有施法時間甚至額外特效方面的差別;此外,每個技能會造成不同屬性的傷害/效果(神聖、暗影、元素、物理等等),甚至一個技能同時造成多種類型傷害效果,更有冰火球這樣根據目標抵抗力而智能選擇更大殺傷效果類型的變態魔法……

最後,最最重要的是,這所有職業上千個技能(或許加上NPC特有的一些技能,數目會達到幾千種)並不穩定,常常會因為某個技能或某些技能的組合過於強大/弱小而加以修改(比如加一個額外的負面狀態如無敵/聖療;甚至全面修改“抗性”“破甲”概念的定義)——玩過wow的都知道,這事幾乎每個月都有發生。

好吧,你打算怎麼設計這數千個技能/效果?


或者,你就這樣把這些概念用class這個筐一裝,然後到處開特例、特例都解決不了就搞23個模式使勁往一塊粘,管他整體結構如何,淌哪算哪?

扯淡。

有個故事說的好:
有人送幾個瞎子一條魚,瞎子們高興壞了,決定熬魚湯喝。魚湯熬好了,瞎子甲嘗了一口,真鮮啊;瞎子乙趕緊也喝一口,太鮮了,太好喝了。幾個瞎子一邊喝一邊贊美——忽然瞎子丙叫了起來:魚跳我腳上了,它不在鍋里!
眾瞎子大驚:這魚都沒放到鍋里,湯就鮮成這樣了;要是放進鍋里,還不得把我們都鮮死啊!

眾面向對象原教旨主義者把事情攪得一團糟,同樣也會大驚:天哪,用了面向對象都複雜成這樣,這要不用面向對象,這軟體就不能寫了吧!

   這個問題是不可迴避的

暴雪在Diablo 2時代已經解決了: 法術/技能資料庫化


所謂資料庫化,其實等同於表格化,例如我的簡化方案:

法術ID 動畫效果 作用範圍 作用類型 屬性 特殊限制 強化類型 特殊設定


特殊設定可以是一段LUA代碼,比如可以在其中搜索、設置傷害類型,查詢順劈斬/治療鏈等技能的傳遞目標等等。

特殊限制,如驅散限定為只能作用於魔法性buf/debuf(根據職業不同,可能有進攻性驅散和防守性驅散之一,也可能同時具備——這就體現在可否驅散敵方/友方目標的debuf)



在這個方案下,釋放一個法術/技能,就成為一種查表運算——找到此法術ID,找到它的作用類型和傷害屬性,計算特殊設定(包括但不限於順劈斬模式的判斷、天賦加成和天賦效果、雕文加成和雕文效果等等)。

於是,到最後,整個法術體系被分為一組組的魔法buf/debuf、物理buf/debuf,這些buf/debuf會影響傷害公式中的某個因數或者造成傷害效果;而傷害效果又分為立即傷害/立即治療和持續傷害/持續治療;最後則是一套影響範圍判定機制。


舉例來說,騎士開聖盾,他同時得到一個buf和一個debuf。
buf是“無敵”,效果相當於設置傷害公式 a*(....) 前面的a因數為0(沒有無敵時此因數為1),於是所有傷害無效。
debuf則是“自律”,因為他的聖盾、聖療技能判斷條件里都有“有自律debuf,則不允許使用”的設定,於是禁止他在短時間內再次使用這些無賴技能。

敵方法師對他釋放寒冰箭,系統受理,但查詢騎士狀態,發現他處於無敵狀態,返回大大的兩個字“免疫”。

然後,有一個敵方牧師對他使用驅散,查詢牧師的驅散術發現,在驅散術的可驅散列表裡沒有聖盾術,於是提示無法驅散或驅散了另外的可驅散(魔法)效果。
敵方牧師迅速反應過來,再次對他使用強力驅散;查詢牧師強力驅散術,發現該牧師在不久前使用過強力驅散,提示無法施法。
等待3秒後,敵方牧師發現自己的強力驅散冷卻(cool down),再次使用強力驅散,查詢發現強力驅散可驅散聖盾術,於是成功移除騎士的無敵狀態。

現在,敵方法師再次對他釋放寒冰箭,騎士切換冰抗光環,系統查詢騎士狀態,發現冰抗光環,又查詢法師穿透等級,和暴擊等級,根據公式計算能否命中、能否造成全額傷害以及能否暴擊;然後提取法師和騎士雙方裝備、天賦數據代入公式計算傷害加成、減免數據,最後給出騎士受到的傷害數字(包括部分抵抗了多少)。



在暴雪設計師的整理之下,如上種種最終構成了幾個表格;只要查詢並代入相應的數據,即可計算出傷害/治療數值以及類型;特殊效果可以用存儲在資料庫中的LUA代碼補充完成。

最終的設計效果就好像內嵌了一個解釋器,這個解釋器會根據法術ID解釋執行資料庫內部的相關內容。

至此,暴雪就完成了整個游戲中各種技能的資料庫化,以至於給一個角色/物品添加/刪除一個/一些技能都易如反掌。


想想看,假如讓那些面向對象原教旨主義者來設計,會出現什麼情況:

定義一個基類叫技能;然後一個繼承類叫法術技能,另一個叫物理技能;然後神聖法術從法術技能繼承,疾病法術也從法術技能繼承;由於聖騎士一個技能同時具備物理和法術兩種效果,於是必須多重繼承神聖法術和物理技能;多重繼承太危險,於是不得不把神聖法術搞成介面類,引入介面繼承甚至帶實現的純虛函數等等高端概念;然後,活該槍斃的暴雪設計師又想出了讓某個技能同時對目標加上神聖持續傷害效果——於是不得不再加個繼承層次,使得神聖法術是神聖持續傷害法術的子集:僅立刻造成一次持續傷害的DOT(damage of time)技能……

那麼,點一個天賦,一個技能就會有dot,否則就沒有怎麼辦?

設計模式是靈丹妙藥,不是嗎 ^_^


等到把這所有幾千個技能全部搞定,起碼也是一個數萬個類、幾十層的恐怖繼承樹,並且會用完23個設計模式(甚至再發明幾個新模式出來,我也不會感到奇怪),精巧複雜到沒有任何人願意去碰它。



但,請註意,天殺的暴雪設計師,在最開始的設計方案里規定DOT不能暴擊;後來又添加約定說某某某職業的某個dot可以暴擊;另一個職業的某個dot在點天賦後可暴擊;至於死亡騎士,在他穿了T9套裝中的其中四件裝備時,他的某個瘟疫類型的dot可以暴擊——但另一個瘟疫dot永遠不能暴擊。


嗯嗯嗯,太好解決了——這不就是策略模式嗎?

好吧,你再填幾十幾百個類體系,然後把舊的幾十層繼承樹中的數萬個類一個個都策略化吧。反正不是我在維護……



哎呀不好,那個槍斃了幾百次都還沒死的暴雪設計師又出餿主意了,他要求:當死亡騎士點了邪惡系的某個天賦時,不光給他增加一個新的dot、並且在這個新dot的存在期間,還要保護他的兩個dot性疾病和1個debuf性疾病不被驅散!


繼續補充:在WLK裡面,那個腦袋都被子彈打成篩子了的暴雪設計師又跳出來了,用他滿是漏洞的腦子出了個該殺的主意:他要求添載入具概念,當玩家坐上傳具時,臨時刪除他的所有技能,替換為載具的技能;或者當他坐在特定載具的特定位置時,防止他受到任何傷害、並且允許他釋放自己的所有技能!
更該死的是,他要求,一些技能本來不允許在移動中施放;但現在,當玩家坐在載具上某個位置時,要臨時允許他移動施法!

還有,為了平衡某個野外戰場,他還要求,在某方人數較少時,臨時根據提高他們的生命值和所有技能的攻擊力和治療能力——這個改變必鬚根據進入戰場的人數實時進行;在一方連續在某個戰場失敗時,同樣要給他們一定補償!



嗯嗯,看看這些刁鑽需求吧,如果沒有面向對象,沒有以策略模式為首的28個設計模式(我有理由相信你們需要至少28個設計模式而不是23個)的英明領導,我們這些沒接觸過大項目、不懂面向對象的傻B們,就是哭的拿眼淚把長城溶解掉都沒辦法吧?——我當然知道搭建長城的材料極難溶與水。

可憐的瞎子,你們的魚湯很鮮吧?


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 英文文檔: 2. 函數第三個參數default為可選參數,如果object中含義name屬性,則返回name屬性的值,如果沒有name屬性,則返回default值,如果default未傳入值,則報錯。 ...
  • 英文文檔: 2. 不傳入參數時,生成的空的不可變集合。 ...
  • JVM記憶體區域 我們在編寫程式時,經常會遇到OOM(out of Memory)以及記憶體泄漏等問題。為了避免出現這些問題,我們首先必須對JVM的記憶體劃分有個具體的認識。JVM將記憶體主要劃分為:方法區、虛擬機棧、本地方法棧、堆、程式計數器。JVM運行時數據區如下: 程式計數器 程式計數器是線程私有的區 ...
  • 1、什麼是序列化?為什麼要序列化? Java 序列化就是指將對象轉換為位元組序列的過程,而反序列化則是只將位元組序列轉換成目標對象的過程。 我們都知道,在進行瀏覽器訪問的時候,我們看到的文本、圖片、音頻、視頻等都是通過二進位序列進行傳輸的,那麼如果我們需要將Java對象進行傳輸的時候,是不是也應該先將對 ...
  • 背景 做為一名使用高級語言的程式員,面向對象的設計一直都是體現程式員能力的重要標準之一,所以在我工作兩年後也就是2008年我也開始了對於面向對象設計的學習,主要是拿GOF設計模式來練手,儘管實際項目中沒有真正的使用過。常見的23種設計模式,我從2008一至到2009年將近一年的時間我基本上將這些模式 ...
  • 單例模式一般應用在整個應用中只會存在一個對象。比如應用類,游戲場景類,工具類等。 實現方式: 頭文件 singleton.h: #ifndef _SINGLETON_H_ #define _SINGLETON_H_ class CSingleton{ public: //供外部調用,通過此方法獲取實 ...
  • 一、前言 1.1、什麼是輸入驗證?為什麼需要輸入驗證? 在上一篇文章中,我們學習了數據類型轉換,我們提到了表示層數據處理的兩個方法,也提到了用戶輸入數據需要進行類型轉換才能得到我們想要的數據,那麼,我們怎麼確定類型轉換後的數據,是我們想要的數據呢?這裡有點繞。你可以這樣想:一個成年男子年齡是18歲, ...
  • 以需求用例為基,抽象介面,Case&Coding兩條線並行,服務(M)&消費(VC)分離,單元、介面、功能、集成四層質量管理,自動化集成、測試、交付全程支持。 3個大階段(需求分析階段、研發準備階段、研發測試階段)16個小歷程(*)確定好邊界,明確好對接產物,做好服務管理。 基於SOA架構的TDD測 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...