先給大家一些不愛看的東西:
以上全部內容出現在同一個類裏面
部分類似的方法我沒有全部放出來,如果放出來了,大家的眼睛應該會更痛苦。
有的時候我的閱讀速度過快,以至於我的大腦知道我讀了什麼的時候已經來不及了.jpg
這個類,應該不需要我多說什麼,但凡做代碼的應該都看不下去了。
其實對於我而言,還好。
畢竟我只需要調用方法就好了,至於問題,等什麼時候程序跑不動了再說。
現在,問題出現了,程序跑不動了。
其實也並不是跑不動了,而是這個抽象的類(並非抽象類,我可沒加關鍵字),非常不方便進行修改。
這個類讀取的數據是很多的,畢竟它是完全地對本地JSON文件進行序列化和反序列化的一個類,字典裏保存的也是一個反序列化後的object,但是問題就出在這裏。
字典裏保存的是個object,是個弱類型(AI說的),雖然我搞不清楚什麼是弱類型,但是當我嘗試給一坨東西加些方法的時候,然後,就紅了
而且,這個類跟揹包相關得非常緊,再就是跟整體的保存邏輯(遊戲進程的保存)之間有着非常大的關係。
在此之前,揹包也是一個字典,是一個更加抽象的字典,這個字典存在於一個專門的揹包類裏,這個揹包類是一個實例類,是一個在構造函數里接受一個字符串(通常是地址或者揹包名稱),然後在本地文件內生成一個揹包(如果沒有),或者打開一個本地揹包,後,才能加載一個存儲物品名稱和數量的字典(誰知道我當時怎麼想的)。
至於揹包裏物品的其他信息?沒關係,調用物品類獲取它吧。
這就很抽象了,首先,這些分散的揹包作爲遊戲中數據的一環,在進行遊戲進程保存的時候肯定是需要保存下來的,但是這些揹包又都是分散的(甚至有一個專門的空揹包,用於處理構造函數無參數的情況),也就是說,想要保存,就必須先進行遍歷,但又不是每一個揹包都需要進行保存(畢竟全局倉庫也可以視作一種揹包,而它會自動保存),總之就是小腦踹大腦,有些勃勃生機,萬物競發了。
而想要保存邏輯正常,首先揹包的存儲得正常,揹包想要正常一點,這個狗日的物品就要正常一點,那就從物品開始改!
在暑假期間,我完成了對於人物數據的管理方法的封裝和統一實現。
這是全部的類文件
大致上可以這麼說,每個類管理一部分數據,這些靜態類一般不加載,這些類管理的數據都是構成“人物”這個巨大數據所必須的,每個不同數據提供了單獨的保存和加載邏輯,同時還提供了初始化,修改,刪除,對於法術還專門設計了施法的邏輯,之後,再到PlayerClass這個總管理裏調用這些方法,其餘的程序和代碼只需要調用PlayerClass內部的方法即可,無需進一步調用被封裝好的的各個數據管理類內部的方法。
在具體實現中,PlayerClass類裏存儲了一個巨大的“人物”數據字典,這使得可以只對這個字典進行訪問就能得到我們想要的數據,但是設計到修改或者創建等邏輯,必須遵循以下邏輯。
修改/創建指令->數據管理類執行方法,對數據進行修改後保存->數據管理類返回修改後的數據到總管理類->總管理類修改自身的數據並保存
按照這個思路,我首先將一串結構體從ThingsClass內扯出來,扔到了全局域當中。
這裏在AI的指導下將所有的數據結構換成了類,便於繼承
之後,在這個基礎抽象類的基礎上,創建了若干子類,並設置了它們的克隆方法
這些是全局物品類們,其實按照之前的邏輯到這裏已經高枕無憂了。
這個時候,我的一個朋友(暑假期間一直在跟我學C#)提出了一個疑問,如果我們手上有一把名叫“聖劍”的鐵劍,但是其屬性還真就是鐵劍,那麼該怎麼去生成呢?
我已經設置了Text屬性,可以支持這樣的操作,但是沒有這樣的方法罷了,其實也好辦,畢竟這些東西已經成爲了一個類,類可以生成實例,無非只是生成一個特殊的實例罷了。
問題出在下一個地方,也就是揹包邏輯上面。
按照AI的說法,繼承於某一個基類的子類,可以在字典存儲的時候使用基類來作爲鍵(大致就是這麼個意思),但是,我們並不能直接讓這個揹包字典存儲Items(上圖中的物品基類)。
首先,字典是一個哈希表,其次,字典是一個哈希表,對於兩個基本類似的物品來說(例如一把鐵劍和一把僞裝成“聖劍”的鐵劍),在我們看來它們是一樣的,但是它們不一樣,至少在哈希函數看來這兩個東西就不一樣,所以,它們兩個不能堆疊。
其實不能堆疊還是小事,畢竟有的時候可能真的不需要堆疊,比如任務物品和非任務物品,一把非任務物品的鐵劍自然不能跟任務物品短劍堆疊在一起。
而且,對於這些用來存儲物品的抽象類和子類而言讓它們提供一個生成實例的方法會使代碼重現變回上面的那種莫名其妙的狀態(其實最主要的原因是揹包大改了,而且是一種奇怪的方式改變了)。
一切始於一個下午,我詢問了AI如何才能做到以下的事情:
創建物品,然後在我需要的時候生成這些物品的實例。
是的,實例,在進行保存或者說本地化的物品裏有一個屬性是不需要的。
Text,Text只會在物品實例誕生後出現,在物品實例誕生前完全不需要,甚至都可以不設置,或者乾脆爲null。
保存時不需要這個Text屬性,在未實例化前這個Text也不需要,需要這個Text的時候,是對物品進行實例化的時候。
於是AI向我提議:設置物品模板。
設置物品模板,爲了迎合我的需求,最終選擇了設置兩種不同的模板。
一種模板叫做物品配置模板。
配置模板內對於Text這個不需要的屬性留空,只參與保存
另一個模板是物品運行模板:
物品運行模板提供一個抽象方法創建實例
同時,我設置了兩者間的轉換方法:
通過這兩個方法,實現兩種模板之間的轉換。
接下來就是神奇而且邏輯清晰,令大家感到舒服的部分了
在運行時,遵循以下邏輯:
從本地JSON文件內讀取數據
這是讀取邏輯的其中一部分
這一步,讀取JSON文件內的數據,並原封不動地注入一個字典,然後返回這個字典給之後的邏輯
對讀取數據進行處理
第一個方法我們之後會提到
這一步將獲取的JSON反序列化的結果轉換成配置模板,然後,立刻將配置模板轉換成運行模板,之後,立刻註冊模板。
註冊模板
這一步,使用圖中的註冊方法將運行模板註冊到運行模板庫(字典)內,同時,嚴格設置模板的ID號(根據上述圖中的特殊枚舉屬性TypeItem來完成了保證物品的ID爲xxxxx形式,每兩種相鄰物品類型之間的ID序號差爲10000)。
到這一步,加載邏輯已經做完了,之後使用以下邏輯進行獲取數據:
有時需要獲取模板(多爲生成某些物品,例如寶箱的初始化),有時需要獲取全部的運行模板(例如開發者狀態下查看物品庫),總之,之後只需要獲取所需的數據,再對數據進行處理,就能獲得通用數據(名稱,類別,價值,重量,描述),而大部分情況只需要這樣數據即可(這裏的情況主要指商店或者揹包,你只需要知道某類東西的重量價值和描述即可)。
之後,在另一個類(揹包類)裏提供了專門的實例化方法,可以根據獲得的模板不同實例化不同的數據。(多嘴提一句,這裏的實例化如上圖所示,一般都是接受一個Text=null,如果有,則實例化爲Text=給定參數的實例,如果爲null,則給出Text=Name的實例)
說回正題。
在完成了上述的一大堆操作後,物品模板的加載完成了,接下來就是使用,而在使用的過程中,很有可能生成一些新的模板:
這些正是之前的方法,經過修改後,用於創建模板而不是實例
這些模板仍舊需要保存,而進行保存也是一個相當麻煩的事情。
首先,這一步,我們的字典內存儲的是物品的運行模板,運行模板不能直接保存,因爲它不是配置模板(哪怕兩者內的數據一模一樣),我們需要將其進行轉換,轉換成配置模板再進行保存。
於是便有了這個非常麻煩的轉換方法
然後便是保存方法啦
這裏的保存方法本來不是這樣的,是根據實際使用而專門進行微調了的。
原本長這樣
原本的保存方法可以很好的進行JSON序列化,但是對於這些模板,不能直接這樣做。
因爲模板有很多種,它們在進行存儲的時候都是以“物品運行模板”也就是基類來進行存儲的,在保存的時候,也會保存下基類的通用數據,最終導致數據丟失。
每一個複雜而帶着許多註釋和try代碼的背後,都是一次次的抓耳撓腮
這一步,也是最關鍵的一部。
保存模板到本地JSON文件並覆蓋
有了保存,有了加載,之後只需要進行適當擴展即可。
但是到這一步,我不滿意。
首先,配置模板畢竟是個模板,畢竟它是專程從本地JSON文件裏讀出來的,隨着本地文件越來越多,那麼這個讀取的過程將會越來越慢。
主要問題出在加載步驟上:
現在的加載步驟按照這樣的邏輯:讀取本地JSON文件->轉換爲配置模板->配置模板註冊
10個模板就需要轉換10次和註冊10次,100個模板就要轉換100次和註冊100次,非常消耗性能。
所以,我們爲什麼不能直接填充字典而不去幹這麼長的一趟工呢?(不是硬編碼,我沒那麼閒)
於是這兒多了兩個方法:
一個新的保存和加載方法!
一個特殊的,本質上也是一個JSON序列化和反序列化的方法,但是,這個方法,直接對字典進行操作,而不通過配置模板和註冊方法。
這個東西便是緩存,它保存下一次運行後的字典內部數據,並且在下一次運行的時候,優先使用緩存內部數據(運行模板)直接對字典進行加載,這就省去了很多步驟,大幅加快了大量模板下的啓動速度。
這個方法在哪兒調用呢?
在這裏
有人應該已經發現了,在Load方法裏嘗試了對兩個文件(緩存文件和JSON配置文件)進行比較時間,而在方法Initialize裏,總是先加載緩存,發現沒有緩存,或者緩存比JSON配置文件老(可以理解爲有新的模板被添加了),則讀取JSON配置文件,在註冊運行模板完畢後,保存運行模板到緩存裏,之後,只要沒有添加新的模板,緩存永遠比配置文件新,讀取緩存。
結果:
到這裏,一個舒舒服服的物品管理類算是做完了,別的不說,下輩子不會動了,而且改起來非常簡單,只需要修改克隆方法,修改一下模板間的轉換方法和模板數據即可。
其實到這裏還是存在一些瑕疵的,但是人已經累了,要專心去做戰鬥系統了,如果各位大佬有什麼好的建議,可以跟我說。
感謝各位的閱讀
更多遊戲資訊請關註:電玩幫遊戲資訊專區
電玩幫圖文攻略 www.vgover.com