簡體   English   中英

Java OOD 和代碼重復

[英]Java OOD and code duplication

我開始創建一個基本的角色扮演游戲,現在我正在研究基礎知識。 我有一個用於創建新角色和現有角色的代碼重復,這是一件非常糟糕的事情。 我將解釋我的問題 - 開始時,玩家可以通過使用CharacterCreator調用來選擇角色類(如戰士)。 我有一個 Character 類,它描述了有關該角色的所有信息。 我還有一個名為CharacterClassabstract類,它描述了字符類的特定屬性和其他內容(如 Fighter,而不是 java 類)。 CharacterClass有一些子類(如FighterMage等)。 該代碼有效,但設計不佳。

如何擺脫CharacterCharacterClass的代碼重復? 我應該改變設計嗎?

public class Game {
    public static void main(String[] args) {
        Character hero =  CharacterCreator.CharacterCreator();
    }
}


public class CharacterCreator {

    public static Character CharacterCreator() {
        System.out.println("Choose a character: ");
        System.out.println("1. Fighter");
        System.out.println("2. Rogue");
        System.out.println("3. Mage");
        System.out.println("4. Cleric");


        Scanner sc = new Scanner(System.in);
        int scan = sc.nextInt();
        String choice = getCharacterClass(scan);

        System.out.println("Choose Name:");
        Scanner nameIn = new Scanner(System.in);
        String name = nameIn.next();

        CharacterClass chosenClass = null;
        Character hero = null;

        switch (choice){
        case "Fighter":
            chosenClass = new Fighter();
            break;
        case "Rogue":
            chosenClass = new Rogue();
            break;
        case "Mage":
            chosenClass = new Mage();
            break;
        case "Cleric":
            chosenClass = new Cleric();
            break;
        }

        try {
            hero = new Character(name, chosenClass);
            System.out.println("A hero has been created");
            hero.displayCharacter();
        } catch (Exception e){
            System.out.println("There was a problem assigning a character class");
        }

        return hero;

    }

    public static String getCharacterClass(int scan){

        String classIn;

        switch (scan) {
        case 1:
            classIn = "Fighter";
            break;
        case 2:
            classIn = "Rogue";
            break;
        case 3:
            classIn = "Mage";
            break;
        case 4:
            classIn = "Cleric";
            break;
        default:
            System.out.println("Enter again");
            classIn = "def";
        }

        return classIn;
    }
}

public class Character {

    private String name;
    private String characterClass;
    private int level;
    private int hp;
    private int currentHp;
    private int armorClass;

    private long xp;
    /*private int BAB; /*Base attack bonus*/

    private int strength;
    private int constitution;
    private int dexterity;
    private int intelligence;
    private int wisdom;
    private int charisma;

    Character(String name, CharacterClass chosenClass){

        this.name = name;
        this.characterClass = chosenClass.getCharacterClass();
        level =  chosenClass.getLevel() ;
        hp = ( chosenClass.getHp() + getModifier( chosenClass.getConstitution() )  );
        currentHp = hp;
        setArmorClass(10 + getModifier( + chosenClass.getDexterity()));
        strength = chosenClass.getStrength();
        constitution = chosenClass.getConstitution();
        dexterity = chosenClass.getDexterity();
        intelligence = chosenClass.getIntelligence();
        wisdom = chosenClass.getWisdom();
        charisma = chosenClass.getCharisma();
        xp = 0;


    }

    void displayCharacter() throws IOException {
        System.out.print("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
        System.out.println("Name: " + getName());
        System.out.println("Class: " + getCharacterClass());
        System.out.println("Level: " + getLevel());
        System.out.println("HP: " + getHp());
        System.out.println("Armor Class: " + getArmorClass());

        System.out.println("***************");
        System.out.println("Attributes: ");
        System.out.println("Strength: " + getStrength());
        System.out.println("Constitution: " + getConstitution());
        System.out.println("Dexterity: " + getDexterity());
        System.out.println("Intelligence: " + getIntelligence());
        System.out.println("Wisdom: " + getWisdom());
        System.out.println("Charisma: " + getCharisma());
        System.out.println("***************");
        System.out.println("XP: " + getXp());

    }

    public int getModifier(int number){
        int mod = (int)((number -10)/2);
        return mod;
    }

    public String getName() { return name; }
    public String getCharacterClass() { return characterClass; }
    public int getLevel() { return level; }
    public int getHp() { return  hp; }
    public int getCurrentHp() { return  currentHp; }
    public int getArmorClass() { return  armorClass; }
    public int getStrength(){ return strength; }
    public int getConstitution(){ return constitution; }
    public int getDexterity(){ return dexterity; }
    public int getIntelligence(){ return intelligence; }
    public int getWisdom(){ return wisdom; }
    public int getCharisma(){ return charisma;}
    public long getXp(){ return xp;}


    protected void setLevel(int lvl){ level = lvl; }
    protected void setHp(int hitPoints){ hp = hitPoints; }
    protected void setCurrentHp(int curHp){ currentHp = curHp; }
    protected void setArmorClass(int ac){ armorClass = ac; }
    protected void setStrength(int str){ strength = str; }
    protected void setConstitution(int con){ constitution = con; }
    protected void setDexterity( int dex) { dexterity = dex; }
    protected void setIntelligence(int intel){ intelligence = intel; }
    protected void setWisdom(int wis){ wisdom = wis; }
    protected void setCharisma(int cha){charisma = cha; }



}
abstract class CharacterClass {

    private String characterClass;
    private int level;
    private int hp;

    private int strength;
    private int constitution;
    private int dexterity;
    private int intelligence;
    private int wisdom;
    private int charisma;

    protected CharacterClass(){

        setCharacterClass("Character Class");
        setLevel(1);
        setHp(10);
        setStrength(10);
        setConstitution(10);
        setDexterity(10);
        setIntelligence(10);
        setWisdom(10);
        setCharisma(10);
    }

    public String getCharacterClass() { return characterClass; }
    public int getLevel() { return level; }
    public int getHp() { return  hp; }
    public int getStrength(){ return strength; }
    public int getConstitution(){ return constitution; }
    public int getDexterity(){ return dexterity; }
    public int getIntelligence(){ return intelligence; }
    public int getWisdom(){ return wisdom; }
    public int getCharisma(){ return charisma; }

    protected void setCharacterClass(String characterClass){ this.characterClass = characterClass; }
    protected void setLevel(int lvl){ level = lvl; }
    protected void setHp(int hitPoints){ hp = hitPoints; }
    protected void setStrength(int str){ strength = str; }
    protected void setConstitution(int con){ constitution = con; }
    protected void setDexterity( int dex) { dexterity = dex; }
    protected void setIntelligence(int intel){ intelligence = intel; }
    protected void setWisdom(int wis){ wisdom = wis; }
    protected void setCharisma(int cha){charisma = cha; }

}


class Fighter extends CharacterClass {

    Fighter(){
        setCharacterClass("Fighter");
        setLevel(1);
        setHp(10);
        setStrength(14);
        setConstitution(16);
        setDexterity(14);
        setIntelligence(10);
        setWisdom(10);
        setCharisma(10);
    }
}

建議:

  1. CharacterCreator.CharacterCreator()。 方法應該是動詞並描述動作,即 createCharacter
  2. 看看廣告設計模式工廠。 你的創造者是“工廠”。 方法“createCharacter”應采用參數 characterType。 這意味着,從 System.in 獲取信息應該在調用該方法的類中完成。
  3. 為具有數字映射的 characterClass 添加枚舉(查看枚舉中的內部映射)。

雖然這不是您問題的直接解決方案,但從長遠來看,這應該對您有所幫助。 對於游戲,尤其是 RPG 類型的游戲,您有許多看似相似但又不同的對象,繼承並不是設計的最佳基礎。 除了您擁有的示例之外,在設計消耗品/武器/裝備/NPC 等時也會遇到問題。這意味着您最終會在許多類中擁有重復的代碼,因為使用抽象類意味着所有子類都具有相同的行為, 但是這是錯誤的。

在這種情況下,更好的方法是避免繼承並使用ECS 這意味着一切都是一種實體。 為了向實體添加一些“功能”,您將使用組件類型。 例如,物品沒有生命值屬性,但說當掉在地上時,它們可以被攻擊和摧毀。 這意味着我們需要為其添加動態屬性。 我們可以這樣做:

entityItem.addComponent(new HPComponent(50));

這將允許其他系統(如攻擊/傷害)“看到”該實體具有 HP 組件並且可以被攻擊。

這只是 ECS 的一個小例子,還有很多其他內容。 我建議閱讀更多相關內容,因為這將使游戲開發設計(對於大多數游戲)更加流暢。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM