2015-10-20 118 views
2

我記得我的第一個Java項目(面向對象)的想法。這個項目是一種非常基本的角色扮演遊戲(NO GUI,它非常基礎),所以我有一些OOD問題。Java面向對象的設計

可以選擇一個角色類(你知道,戰士,巫師等等),在未來他可以選擇幾個角色,這樣他就可以擁有一名玩家(至少現在沒有玩家類)一個派對)。角色創建後,他可以與其他敵人作戰(由程序控制)。

  • 每個字符內有一個像一些信息:一個字符類(如戰鬥機),等級,防禦等級,能力(力量,敏捷,智慧等)。
  • 每個班級都有一個庫存。
  • 每個人物都有像一些方法:

  • 攻擊(使用武器,如果他是一個施法者,然後施展法術也可以 使用攻擊)。

  • 保衛(如防禦法術,或使用能力像招架注意:改變 甲流
  • 一些字符類(如嚮導)可以施法大部分法術是進攻還是防守,這樣他們就可以利用攻擊。或防守方法。 讓我們說,castFireball可以調用攻擊(20),例如,一些法術 可以做其他事情一樣castHeal其治癒的特點和變化 當前生命值。

  • 購買(以備將來) 。對於所有字符當然也是一樣的。

  • 從庫存中添加/刪除。

建議實施:。 我想到了創建一個抽象類(類似級別的信息,防禦等級,能力(如力量,敏捷,智慧等)和一些方法,如攻退可守的其他具體的班會擴展字符,所以它看起來像:

      Character (abstract) 
           Character Class (like fighter) 
           Level 
           Hit Points 
           Current Hit Points 
           Armor Class 
            . 
            . 
            . 
           Inventory (List) 

           Strength 
           Dexterity 
           Wisdom 


    Fighter  Wizard   Rouge  Cleric (All extends Character) 

問題:?

  1. 這裏使用抽象類被認爲是在這種情況下,一個好的設計,你會建議使用的接口和變化t他設計?
  2. 我是否應該爲力量,智慧等能力製作另一個類,或者它可以作爲角色的一部分嗎?
  3. 我應該爲庫存創建另一個課程嗎?我認爲這可能會更好,對吧?
  4. 通過使用枚舉來存儲所有武器,裝甲和盾牌(可能是其他未來的東西)的數據是一個很好的解決方案?
  5. 法術 - 我不確定什麼是實施它們的好方法。我可以創建一個法術類 ,每種法術都有靜態方法(如castFireball,castHeal方法)。施放法術只與法術角色有關(並且每個角色都有一個已知的法術列表,因此他只能施放他知道的法術)。這是一個很好的實現方法嗎? 我也可以使用txt文件並從文件中獲取相關數據,但我不喜歡這個想法。

請記住,它應該是基本的,但應該爲將來的更改和添加計劃。它看起來像:

你想如何攻擊?

  1. 匕首(主武器)
  2. 發法術

你要哪一種法術施展?

  1. 火球
  2. 治癒
  3. 冰風暴

你打一個火球敵人,並處理20損害。

這是非常含糊,但你明白了..

非常感謝!

回答

1

我建議不要讓Character抽象基類(例如)Fighter。成爲戰士只是角色的一個屬性。例如,我只是告訴你,他可以拿着劍,戴着平板電腦。在某些遊戲中,假定一個Warrior角色永遠是戰士。然後,當需求發生變化時,一個角色可以將類更改爲Mage,這就會導致整個數據遷移問題,而不僅僅是屬性的變化。 K

保持您的繼承樹儘可能淺。儘可能使用聚合和組合而不是繼承。

+0

我認爲是這樣的plalx。事實上,我會進一步詢問爲什麼一個角色只能是一個類。在某些遊戲中,只有技能,在這樣的遊戲中,我可以想象檢查'this.skills.armorwearingskill> = armor.skillrequredToWear'等等。我認爲這爲需求變化提供了更大的靈活性。而且它仍然可以與一個控制這些方面的角色類相適應,如通過一個角色類與其他屬性上的一組約束關聯起來的角色類。處理不斷變化的需求的能力在這裏是值得的。如果他們不改變,繼承是好的。 –

+0

我在這裏看到你的觀點。你是對的,角色類只是一個屬性。如果一個角色可以多於一個類,那麼使用聚合和合成是比繼承更好的設計。如果一個角色只能是一個角色類,那麼我抽象類就可以正常工作。感謝提示:) – Niminim

+0

@Niminim只問自己......是一個角色是一個階級還是一個角色有一個階級?看到你最初看到繼承的構圖通常會導致更好的設計。 – plalx

1

一般來說,類B應該是A一個子類只如果有是,一個他們之間關係 - 也就是說,如果它將使意義說的B任何實例也爲A一個實例。通過應用這一點,你可以看到字符類是唯一可行的候選人的Character子類:一個Warrior一個Character,但它不是一個Weapon一個Character的情況。相反,其他類別之間有一個關係,而Character有一個一個Weapon。在這種情況下,你應該使用組合Character類可以有Weapon類型的字段(或者更可能是List<Weapon>類型的字段,以便可以擁有多個武器)。

但即使你可以作出一個類層次結構,它不是肯定你應該。如果角色類別之間的差異可以完全實現爲統計差異(大概只是該類別中的字段)或一些簡單的能力差異,則可能只需要類別Character。另一方面,如果的行爲差異非常大,並且最終會得到一堆if語句來爲不同情況下的各種字符類別選擇適當的行爲,那麼引入子類可能是明智的。但是,作爲@plalx和@B。 Dalton指出,通常可以使用組合來替代,將行爲差異提取到抽象的CharacterAbilities類及其子類。

+0

當然起初似乎一個戰士是一個字符,但它的觀點是所有問題。一個角色是一個階級還是一個角色有一個階級?你可以經常把事情變成最終的結果,而不是導致更柔軟的設計。 – plalx

+0

@plalx:夠公平的;看到我的新段落。 –

+0

感謝您的建議,Aasmund! – Niminim

0
  1. 這裏使用抽象類工作得很好,因爲所有其他字符類都將從這個類擴展而來,並且類本身永遠不會實例化。如果你的能力比整數更復雜,你可以考慮讓他們成爲一個班級,但是如果你所做的只是添加臨時增益/減益效果,我建議每個能力都有兩個整數:一個目前的能力值和另一個沒有buff/debuff的基礎值。

  2. 將庫存作爲一個類是一個好主意。有些人可能會試圖創建一系列庫存物品,並根據遊戲需要進行操作。我認爲創建一個單獨的類保持了一切都很好的封裝,即使你只是操縱一個數組。

  3. 枚舉在創建武器時很有用,但我也會爲此推薦一個單獨的類。如果你使用枚舉的所有項目,你可能最終不得不使用大量的數學,特別是分割和模塊化來獲得項目類型。創建一個項目類並將其擴展到不同的項目類型允許使用父類類型將所有項目包含在一個公共數組中,同時爲它們提供不同的統計/能力/用途。法術可以遵循類似於我上面描述的方式(事實上,如果你想把它們放在你的庫存中,法術可能是一個物品)。確保有一些枚舉來描述咒語及其功能,然後提供一種方法來解釋這些咒語。

+0

1 + 2 + 3。謝謝! 4.我想要分別創建武器,戰利品,裝甲和「其他東西」的枚舉,雖然創建另一個類也聽起來不錯 – Niminim

+0

5.如果我說得對,那麼你建議enum將包含信息和方法,另一種方法會調用該方法,對吧? – Niminim

+0

如果您將所有物品保留爲沒有類的枚舉,那麼只要您想打印出他們的名字,傷害或防禦,就需要通過翻譯器運行它們。這最終會成爲一個非常長的轉換聲明,但絕對是解決它的一種方法。我認爲將這些信息存儲在一個類中會更容易。對於5,我的意思是說,所有法術都應該有一個通用的方法,這個方法在投射時被調用,這些枚舉告訴我們在這個方法中會發生什麼。這樣一個物體可以施放咒語,而不必真正關心它是什麼咒語,讓咒語完成剩下的任務。 – Mackie

0

類應該有一個責任(或者更具體的一個理由去改變)

1)抽象類看起來要走的路,因爲你可以包含在類常見的行爲,減少重複。一個接口只定義'合同'

2)參見開頭語句,聽起來像是另一個責任。

3)請參閱第2

4)取決於內容,類可能會更好

5)有可能不同的抽象類繼承來回字符,以確定拼寫性質。避免靜態方法。另外值得一看法術的設計模式。可以有一個方法'castSpell'的接口,每個咒語都實現自己的功能。

有很多不同的選項 - 最好有一個去看看有什麼作用。如果您遇到問題,請發佈代碼。

0

至於武器,盾牌和法術,我會他們模擬成兩個接口:

  • PassiveItem - 東西,修改角色的能力沒有他們需要執行任何操作(如屏蔽增加了他們的防守)
    • 這將有某種applyEffect()方法的可修改能力(可能創造的基礎能力的一個副本,然後運行所有被動項目上那些applyEffect()得到最終的能力與項目)
  • ActiveItem - 需要人物的行動的武器,物品和法術產生任何影響
    • 這將有方法performAction(Character self, Character target)將修改拖在某種程度上打擊字符,例如HealSpell執行會增加角色的生命值,Dagger會對目標執行攻擊。