我要加入

夢想家公會

會長:chenjinsheng / 此間半開一盞茶開設日:2015-05-17 23:58:58

  • EXP

  • 資金13569  
  • 關連作品我的世界、我的世界 Classic、我的世界... 看更多
  • 招募制度:自由加入制
  • 成員:23 人
  • 昨日人氣:0

自製屬性系統

推上精選編輯

近期編輯:chenjinsheng ...看更多

自製屬性系統

作者:AniKaBa


自製屬性系統-創建屬性與資料儲存


        在麥塊(Minecraft)裡有等級,但是等級的成長不會再來玩家能力上的成長,雖然說附魔與維修需要用經驗值去交換,對於生存而言成長帶來的好處似乎不夠多,所以我們可以加入屬性,增加所謂的RPG效果,由無到有看起來很像很難的樣子其實是最簡單的。


        看到上面的圖各位要好好思考要加入屬性的樣式,西方還是東方有些遊戲屬性只有陰、陽當然構思如果跟我一樣那我只能說你的構思無法打破他人的想法,我屬性是參考D&D當然各位有哪些想法可以提出來。


        麥塊的儲存方法與大多數遊戲一樣,想想單機遊戲,當你沒走到存檔點,或者迷宮中無法使用存檔功能突然停電,這時會因為你沒存檔只能由舊紀錄重新再打一次,你很氣餒,線上遊戲發生這種事玩家們也很不高興,將玩家資料儲存在記憶體中而不是儲存在實體硬碟裡,經過一定時間或條件再進行存檔至硬碟,伺服器選擇這種作法是對伺服器最好的選擇,沒有人想要存取繁複造成硬碟損壞,畢竟硬碟損壞的影響遠比玩家權益輕微受損來的嚴重多了。


        資料庫,大家常見的就像是Excel一樣當然也有自製的,自製格式只有自製的軟體才能進行解讀,免費的資料庫應該不用我介紹了,我常在文章內看到資料庫因為免費資源太多了,因此買本書不如上網搜尋,加入含有資料庫概念的資料儲存也是種作法。




自製屬性系統-實作屬性與儲存


        建立JAVA專案,各種IDE有各種不同,基本的我們就省下不談了。接著我們要做的事就是要連結我們的插件與Spigot,第一步是讓我們的Main Class (主類別) 繼承 (Extends) JavaPlugin,


        第二步加入Plugin.yml註冊我們的插件,這時候你可以發現Main Class 內的名稱由暗灰色轉為白色,當然每個IDE都不一樣別問我你的IDE為啥沒有這種變化。


        先行作業完成後下階段進入重點,建立新Class將屬性部份寫入,不過在這裡我們要考慮一下用哪種儲存模式,再這我就寫點簡單的直接做物件存取。

        直接作檔案存取很傷硬體設備,目前小弟還沒有能力作的跟線上遊戲一樣,怕造成影響我還會繼續努力改善,不過對於記憶體較少的伺服器而言是一大福音。


        屬性一旦加入你的伺服器就別想拋棄它,所以你需要完整的規劃,任意刪減對於你整個伺服器而言就跟讓玩家打掉重練是一樣的,在這裡我們做一個屬性的介面。

        你可以看見我們的介面有Serializable接口代表該物件是可以序列化的,序列化的目的是為了讓我們的物件可以做儲存與讀取,在這裡你發現多一個serialVersionUID這部份是指定序列化的版本,如果不做指定的話只要這個Class有變動會導致自行產生新的序列化的版本,於是舊版本與新版本便會產生不相容而拋出錯誤。


        Get與Set的建構式,沒錯我們的屬性值還需要能夠讓我們自己,甚至其他想要替插件裝上翅膀的朋友,能夠取得修改屬性值與創造儲存,這一部份一定是免不了的;在這裡我還是要說一下6個值在這裡實在是有點太多了,當然除了建構式又臭又長之外過多也會照成許多不便。

        內容裡我們的各種值是a~f,但是編輯建構式時必須要很明確、簡單容易辨識這些值,不然你希望當其他人或自己使用geta就可以知道自己取得劍術屬性嗎?


        建立這個物件時你不會想要漏掉其中一個值,不然會造成運算錯誤的冏況,建立新物件時預設將所有屬性設定為0,前面有set的結構式能夠幫你將你所需要設定的變更成你想要的,你一定問為什麼要多此一舉,因為我們不會只有一種取得此物件的方法。


        有創建當然還要能儲存,OutputStream的類別有許多種,當然上網查詢才是王道,儲存的方式有很多方法這只是一種方法而已,以這種儲存的方式就像自製的SQL,只有知道檔案內容有哪些資料你才能讀取。

        你一定會問我一定要儲存在插件當下的資料夾裡嗎?當然這是可變更的,個人會將檔案放在PlayerData並且在增加個人以UUID命名的資料夾內,如果沒有寫出很方便的讀取器這個動作是沒必要的。


        儲存之後還需要能夠由檔案中讀取出來,有了這些Api是不是對於後面使用的人方便多了,何況你一定不會只建立這幾種屬性,利人利己也有助於後續的開發。

        JAVA小弟我也只是略懂皮毛,認証跟考試我都不懂我只知道將收集到的資料收集起來後面可能用的到,就像堆積木一樣找到自己收集的一塊挑一個自己認為最好的放上去而已。




自製屬性系統-玩家加入與顯示屬性


        這裡我不會接續原來的插件(RpgA)來寫,而是創建另一個插件去支援它,為什麼要做得這麼麻煩呢?

         沒有一種插件可以滿足所有使用者,而且分開寫作在維護上也比較方便,基本上大多數插件寫作都是為了自己的伺服器有所需求,比如接下來的創作是玩家加入及加入屬性功能,但也有伺服器是後來經過某種程序再加入,如經過試練考核等,因此你也可以再寫一個依你自己的模式需求製作插件來支援我寫的。

        上圖已經放入RpgA中我們可以加以利用的API,使用API的方法與同插件寫入是一樣的不需要額外的寫作方法。

        接下來我們要先讓玩家擁有屬性,在這裡有幾種簡單的方法,第一種是使用指令方式,這時如果以自動化來看指令需要由玩家來執行是比較不好的方法,所以可以用指令木牌插件或壓力板來做觸發,不過更簡單的就是玩家一進遊戲同時也將屬性加入會比較好,這次寫的算是共通性屬性所以沒必要加入過於複雜的設計。


        玩家加入遊戲事件,在事件之中最常使用的就是它,這也是事件中的基礎運用,只需要玩家進入到遊戲中立即觸發作用,內容當中分兩段(第1張圖)主要是檔案判斷這部份用if一分為二,如果不進行檔案判斷便會一值重複作屬性修改為0的動作。

        內容以口語來說就是,玩家加入遊戲觸發以UUID命名的檔案辨識系統(唯一檔案),如玩家第一次進入遊戲(或者伺服器第一次裝)此時辨識系統檢測不到該玩家檔案,自動創建以該玩家UUID命名檔,依照上一篇的說明該玩家所有屬性都會設定為0;登出之後再進入就不是第一次加入遊戲而且屬性檔也有建立,系統會由檔案讀取相干的值並提示玩家目前的屬性。


        別忘記要讓事件起作用還需要在Main Class註冊,不然寫在多也是白費;目前為止我們事件只有一條,再不久加入的更多更煩雜,最好的方法是事前規劃,再做分類拆開。


        寫好一個階段最好是進行實際測試,尤其是「事件」要做到避免有互相干涉的情形,登入2次看看結果是不是跟我一樣。

        當然我們的標題「顯示屬性」還沒有結束,你不可能讓玩家進行登出登入來看自己的屬性值,而目前有幾種簡單的方式來製作,能夠再Spigot API 裏面找到顯示方式大約3~5種 。


        利用指令讓玩家自行輸入來使用,這一種顯示方式對玩家來說是最方便的,想要在時何地都可以使用對伺服器也不會造成太大的影響,如果嫌麻煩還可以使用箱子指令讓玩家用點選的方法來執行,當然也可以用物品點擊左右鍵來取得也行。

        上圖中你可以發現內容的寫法跟前面的事件內容有些相似,不想讓玩家查詢自己的屬性卻只有白色的文字所以有使用ChatColor改變文字顏色,比較常使用的方法有ChatColor.Color + String ,當然你也可以像我一樣使用代碼式轉換,下圖有對照顏色代碼雖然說你不一要用&,不過我個人認為這是習慣用法而且這樣的模式比較符合多數人的習慣。




        沒錯除了「事件」以外「指令」也需要在Main Class註冊,另外還需要寫入說明不過你可以看到我沒有寫說明在裏面,只是單純放一個框架而已,由於在BUKKIT某一版本寫入說明這部份有出現問題後我就沒有再寫入說明(應該已經修好BUG),寫說明的好處是玩家使用/help時,內容顯示可以秀出說明外,還可以查詢如何使用,框架是一定要加入的如果沒做這一部份會導致指令無法運作。

        再次進行測試是否有達到我們的需求,顏色文字排版最好是進遊戲之後再來比對排版,當然也有其他補助插件可以改善排版的問題;目前為止事件與指令介紹的不是很完善等這部份告一段落再來好好研究一番。




自製屬性系統-經驗等級與屬性增長


        經驗在麥塊裡扮演的就是來來去去的作用,打怪、挖礦、燒製可以一點一滴的取得,累積之後會有等級成長但是無實質作用,如果要讓等級起作用還需要考慮到降等的問題玩家死亡、道具附魔。

        定住等級讓玩家不掉等,這部份其實已經破壞原本的遊戲內容,當然你也可以自己編出新等級經驗,問題在於廣泛使用的還是原玩家等級這裡,我們儘量不壞原則下來進行插件的寫作,不過有時也為了讓玩家不作弊而有所犧牲。


        接下來我們還需要運用指令讓玩家進行屬性的調配,當然你也一定發現我們讓玩家打開箱子,使用指令進行屬性升級太簡單了,但是,所有遊戲幾乎都是圖形化的介面,玩家用滑鼠點擊就可以完成許多事,圖形化介面已經不再是伺服器的特色,而是一種必然的作法。


        看到上面簡單的介面是不是越越欲試,當然原本的構想沒這麼簡單就是了,不過光這樣寫的時候除了枯燥外就是乏味。


        這裡我大概說明一下內容好了,我們要以箱子介面來充當圖形介面所以我們需要一個框架,所以我會做的跟RpgAa一樣寫出一個可重複使用的介面,不過再這裡你會發現我們的Class少了public,因為RpgCa不需要讓其他人使用,對於Class權限有興趣的話可以Google一下。

        Plugin Config內容是讓服主設定屬性等級需要多少經驗值(如,需要多少經驗才能升級到LV1)、最大等級,內容還需要玩家們的屬性所以建立new class 需要置入 player uuid才行,重復的內容我們就不多說。


        當然別忘記我們的按鈕,之前建立5的屬性自然需要最少5個按鈕,我們只拉出一個來看請看官們自行舉一反三了,45行你應該發現我們還給按鈕數量為了要玩家一打開就知道自己的屬性等級,不過道具最多只能夠堆疊64個,再往上追加會造成顯示上的錯誤,當然還是可以靠其他插件來補救,不過再這我們還是要限制屬性等級不要超過64較好。

        內容(Lore)的第1行你一定發現內容不是跟道具名稱差不多嗎?沒錯,第1行扮演一個很重要的角色,大多數插件都會以道具名稱來做辨別,但是這樣的作法容易讓玩家們破解並從中作梗,名稱上加入顏色碼是無效的除非你是使用translateAlternateColorCodes(),不過一旦色碼代號流出去就跟反編譯程式流落再我們手上是一樣的道理,也有些人再加上道具類型做判斷,但只是再增加困難度而已,鐵砧就能搞定一切,玩家無法編輯的部份就是說明內容所以判斷使用的Keyword就是Lore的第1行。

        接近結尾處你應該發現了ItemFlag,他可以用來隱藏道具的固定/額外附加的屬性,比如鐵劍有+6 攻擊傷害玩家一看還以為我修煉一個等級會增加6點傷害,附魔燃燒,哇嗚聽起來好遜喔,隱藏附魔後加上個小故事...每當揮下一劍,惡龍便從劍刃之中浮現,並且吐出邪惡的黑焰。攻擊有機率發動特技:魔龍吐熄。


        完成界面按鈕後自然我們要接上按鈕與玩家們互動,其中會利用到的就是事件了,玩家與箱子互動事件之中,一開始我們要辨別是不是打開屬性生級的箱子,由於在這裡不需要移動到裡面的按鈕與玩家的道具,因此所有的互動設定為取消,雖然互動是取消的但是取得的點擊依然存在。


        取得點擊欄位就可以取得點擊的按鈕,辦別玩家經驗值是否能夠提生該技能,可以的話該技能就提生1個等級,是不是很簡單呢,不外乎,很多處發還可以做出更多便利的界面供伺服器使用,在這只是牛身上的一根毛而以。



公會首頁