gpt4 book ai didi

java - 面向对象设计 - 法术

转载 作者:塔克拉玛干 更新时间:2023-11-03 04:08:19 25 4
gpt4 key购买 nike

我的第一个 Java 项目是一个基本的角色扮演游戏。现在我在研究法术,我需要一些 OOD 指导。

我有Character,它是一个抽象类Character 有一些子类(比如magefighterrogue牧师).

法师牧师(至于现在,牧师没有法力,但它可能会改变) 都是施法者。

我还有一个 Spell 类,其中包含一些信息(例如 spell namemana cost 等)。 MageSpellsListClericSpellsList 是另外两个类,它们都有 Spell 类列表。我也有 Effects 类(施法应该使用它)。

什么是处理法术的良好面向对象设计(解决方案不应包括 Effects 类,我可以稍后处理)?

也许使用“SpellCaster”接口(interface)和一些方法,如 castSpell 和 showSpellbook,这样 Mage 和 Cleric 将实现该接口(interface)? .

也许 MageSpellsList 和 ClericSpellsList 应该是 Spell 的子类?我的目

法师.java:

public class Mage extends Character {

private List<Spell> spellBook;
private int mana;
private int CurrentMana;

public Mage(String name) {

super(name);

setName(name);
setCharacterClass("Mage");
setLevel(1);
setHitDice(4);

setStrength(10);
setConstitution(10);
setDexterity(14);
setIntelligence(16);
setWisdom(14);
setCharisma(10);

setHp((int) (4 + getModifier(getConstitution())));
setCurrentHp(getHp());
setArmorClass(10 + getModifier(getDexterity()));
setBaseAttackBonus(0);

setMana(20 + 2 * getModifier(getIntelligence()));
setCurrentMana(getMana());
spellBook = new ArrayList<Spell>();

}

public int getMana() {
return mana;
}

public int getCurrentMana() {
return CurrentMana;
}

protected void setMana(int mna) {
mana = mna;
}

protected void setCurrentMana(int CurrMana) {
CurrentMana = CurrMana;
}

public void showSpellBook() {

for (Iterator<Spell> iter = spellBook.iterator(); iter.hasNext(); ) {
Spell spell = iter.next();
System.out.println("Spell name: " + spell.getSpellName());
System.out.println("Spell effect: " + spell.getEffect());
}
}

public void addToSpellBook(String spellName) {

Spell newSpell;
newSpell = MageSpellsList.getSpell(spellName);
spellBook.add(newSpell);
System.out.println(newSpell.getSpellName() + " has been added to the spellbook");

}


public void chooseSpells() {
System.out.println();
}

void castSpell(String spellName, Character hero, Character target) {
try {
Spell spell = MageSpellsList.getSpell(spellName);
System.out.println("You casted: " + spellName);
System.out.println("Spell effect: " + spell.getEffect());
} catch (Exception e) {
System.out.println("No such spell");
}
}
}

拼写.java:

public class Spell {
private String name;
private int spellLevel;
private String effect;
private int manaCost;
private int duration;

Spell(String name, int spellLevel, String effect, int manaCost, int duration) {
this.name = name;
this.spellLevel = spellLevel;
this.effect = effect;
this.manaCost = manaCost;
this.duration= duration;
}

String getSpellName() { return name; }

int getSpellLevel() { return spellLevel; }

String getEffect() { return effect; }

int getManaCost() {
return manaCost;
}

int getDuration() { return duration; }
}

MageSpellsList.java:

public class MageSpellsList {
static List<Spell> MageSpellsList = new ArrayList<Spell>();

static {
MageSpellsList.add(new Spell("Magic Missiles", 1, "damage", 2, 0));
MageSpellsList.add(new Spell("Magic Armor", 1, "changeStat", 2, 0));
MageSpellsList.add(new Spell("Scorching Ray ", 2, "damage", 4, 0));
MageSpellsList.add(new Spell("Fireball", 3, "damage", 5,0 ));
MageSpellsList.add(new Spell("Ice Storm", 4, "damage", 8, 0));
}

static void showSpellsOfLevel(int spellLevel) {
try {
for (Iterator<Spell> iter = MageSpellsList.iterator(); iter.hasNext(); ) {
Spell spell = iter.next();
if (spellLevel == spell.getSpellLevel()) {
System.out.println("Spell name: " + spell.getSpellName());
System.out.println("Spell effect: " + spell.getEffect());
}
}
} catch (Exception e){
System.out.println("Epells of level " + spellLevel + " haven't been found in spells-list");
}
}

static Spell getSpell(String spellName) {
try {
for (Iterator<Spell> iter = MageSpellsList.iterator(); iter.hasNext(); ) {
Spell spell = iter.next();
if (spellName.equals(spell.getSpellName())) {
return spell;
}
}
} catch (Exception e){
System.out.println(spellName + " haven't been found in spells-list");
return null;
}
return null;
}
}

效果.java:

public class Effects {

public void damage(int dice, Character attacker, Character target){

int damage = DiceRoller.roll(dice);
System.out.println(attacker.getName() + " dealt " + damage + " damage to " + target.getName());
target.setCurrentHp(target.getCurrentHp() - damage);
}

public static void damage(int n, int dice, int bonus, Character target) {

int damage = DiceRoller.roll(n,dice,bonus);
System.out.println("You dealt" + damage + "damage to " + target.getName());
target.setCurrentHp(target.getCurrentHp() - damage);
}

public static void heal(int n, int dice, int bonus, Character target) {

int heal = DiceRoller.roll(n,dice,bonus);
if (heal + target.getCurrentHp() >= target.getHp()) {
target.setCurrentHp(target.getHp());
} else {
target.setCurrentHp(target.getCurrentHp() + heal);
}

System.out.println("You healed" + heal + " hit points!");
}

public static void changeStat(String stat, int mod, Character target){

System.out.println(stat + " + " + mod);

switch (stat) {
case "strength":
target.setStrength(target.getStrength() + mod);
break;
case "constitution":
target.setConstitution(target.getConstitution() + mod);
break;
case "dexterity":
target.setDexterity(target.getDexterity() + mod);
break;
case "intelligence":
target.setIntelligence(target.getIntelligence() + mod);
break;
case "wisdom":
target.setWisdom(target.getWisdom() + mod);
break;
case "charisma":
target.setCharisma(target.getCharisma() + mod);
break;
case "armorClass":
target.setArmorClass(target.getArmorClass() + mod);
break;
}
}
}

最佳答案

序言

我尽量概括类,这样我就不会得到很多只代表不同数据而不是不同结构的特定类。此外,我尝试将数据结构与游戏机制分开。特别是,我尝试将战斗机制全部放在一个地方,而不是将它们分成不同的类别,并且我尝试不对任何数据进行硬编码。在这个答案中,我们将介绍角色、他们的能力/法术、能力的效果,以及战斗机制.

字符

例如,考虑一个代表您角色的 PlayableCharacter。这是一个标准的数据类。它提供了增加或减少生命值和法力值的方法,以及可用能力的集合。

class PlayableCharacter {
private final int maxHealth;
private int health;
private final int maxResource; // mana, energy and so on
private int resource;
private final Collection<Ability> abilities;

// getters and setters
}

能力

能力同样是数据类。它们代表法术力成本、触发效果等。我经常将其表示为一个普通类,然后从外部数据文件中读取个人能力。在这里我们可以跳过它并用枚举声明它们。

enum Ability {
FIREBALL("Fireball", 3, 5, new Effect[] {
new Effect(Mechanic.DAMAGE, 10, 0),
new Effect(Mechanic.BURN, 2, 3)
});

private final String name;
private final int level;
private final int cost;
private final List<Effect> effects;
}

效果

最后,效果说明了一个能力的作用。伤害有多大,持续多长时间,对角色有何影响。同样,这都是数据,没有游戏逻辑。

class Effect {
private final Mechanic effect;
private final int value;
private final int duration;
}

机制只是一个枚举。

enum Mechanic {
DAMAGE, BURN;
}

力学

现在是时候让事情正常进行了。这是您的游戏循环将与之交互的类,您必须向它提供游戏状态(例如哪些角色正在战斗)。

class BattleEngine {
void useAbility(PlayableCharacter source, PlayableCharacter target, Ability ability) {
// ...
}
}

如何实现每个机制取决于您。它的范围可以是每个 Mechanic 的 hell 开关或 if/else,或者您可以将代码移动到 Mechanic 枚举,或者移动到私有(private)嵌套类并使用 EnumMap 以检索每个处理程序。

示例机制

interface MechanicHandler {
void apply(PlayableCharacter source, PlayableCharacter target, Effect effect);
}
class BattleEngine {
private final Map<Mechanic, MechanicHandler> mechanics;

void useAbility(PlayableCharacter source, PlayableCharacter target, Ability ability) {
source.decreaseResource(ability.getCost());
for (Effect effect: ability.getEffects()) {
MechanicHandler mh = mechanics.get(e.getMechanic());
mh.apply(source, target, effect);
}
}

private static final class DicePerLevel implements MechanicHandler {
@Override
public void apply(PlayableCharacter source, PlayableCharacter target, Effect effect) {
int levels = Math.min(effect.getValue(), source.getLevel());
int damage = 0;
for (int i = 0; i < levels; ++i) {
int roll; // roll a d6 die
damage += roll;
}
target.decreaseHealth(damage);
}
}
}

关于java - 面向对象设计 - 法术,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33450665/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com