Java OOD和代码重复

我开始创建一个基本的角色扮演游戏,现在我正在研究基础知识。 我有一个代码重复用于创建新角色和现有角色,这是一件非常糟糕的事情。 我将解释我的问题 – 一开始玩家可以通过使用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添加enum并映射到数字(在枚举中查看内部地图)。

虽然这不是您问题的直接解决方案,但从长远来看,这应该对您有所帮助。 当涉及到游戏,特别是RPG类型时,你有很多看似相似但又不同的对象,inheritance并不是设计的最佳基础。 在您拥有的示例之上,在设计耗材/武器/齿轮/ NPC等时也会遇到问题。这意味着您最终会在许多类中使用重复的代码,因为使用抽象类意味着所有子类都具有相同的行为, 但是这是错误的。

在这种情况下,更好的方法是避免inheritance并使用ECS 。 这意味着一切都是一种实体。 为了向实体添加一些“function”,您将使用组件类型。 例如,物品没有HP属性,但是当放在地上时,它们可能会受到攻击和破坏。 意思是我们需要为它添加动态属性。 我们可以这样做:

 entityItem.addComponent(new HPComponent(50)); 

这将允许其他系统(如攻击/损坏)“看到”该实体具有HP组件并且可以受到攻击。

这只是ECS的一个小例子,它还有很多。 我建议阅读更多关于它的内容,因为这将使游戏开发设计(对于大多数游戏)显得更加平滑。