0

不幸的是,由于我学校的面向对象软件工程项目,我正在使用 java 和 slick2d 制作冒险游戏。

我正在应用 MVC 架构,并通过从 ItemFactory 类中的平铺地图文件中读取来创建项目。他们似乎很适合这种游戏。

游戏中有多个项目会影响游戏,尤其是角色。(在这种情况下,角色与玩家相同)

有一个字符模型,它有一个内部类 Inventory,它基本上由一个 ArrayList 项目组成。

角色控制器有一个名为 takeItem 的函数,它接受一个容器参数(即货架),该参数也有一个项目的 ArrayList,然后删除里面的内容并放入库存中。

它有一个名为 useItem 的函数,它接受一个 int 索引并使用适当索引中的项目。

在那之前,一切都很好。

现在的主要问题是,这些物品有特定的用途。例如,健康药水增加角色的健康,隐形药水使其隐形等。

为了维持一个好的设计,我如何以及在哪里可以解释和附加功能到这些项目?

到目前为止,我认为是这样的: 1- 我没有向项目类添加任何功能。它只有名称、描述和 Enumerated ItemType 和 int power 2-我正在角色控制器的 useItem() 方法中完成所有工作,即

if (itemBeingUsed.getType() == Common.ItemType.POTION)
    `characterModel.increaseHealth(itemBeingUsed.getPower())`

正如你所看到的,这看起来很奇怪,因为角色控制器就像一个项目解释器。

3- 另一种方法可能是创建一个带有字符控制器的 ItemInterpreter 类。虽然这看起来更优雅,但它会让我在角色控制器中执行一堆不必要的功能,比如调用角色模型的 increaseHelth() 函数的“increaseCharacterHealth”函数等等。

另一个可能的问题是我使用Character Controller的功能来使用物品,但是物品也可能影响游戏,即减慢时间,但是Character Controller位于游戏的类层次结构之下,无法访问Game/GameController功能。减慢游戏时间等似乎至少现在不是这种情况,所以看起来我可以在 CharacterController 类中使用 Items 但我想知道你的意见,如果它是一个好的设计或者什么可以更好。

一些用于清除问题的代码:(注意:它们不完整) 注意:我将 ItemType、Direction 等枚举类型放在所有类都通用的 Common 类中。

在 CharacterController 中使用 item 函数:

public void useItem(int index){ 
        Item item = ((Character)obj).inventory.takeItem(index);
        if (item != null) {
            if (item.getType() == Common.ItemType.POTION) {
                ((Character)obj).increaseHealth(item.getPower()); // I have extended a Person class, now I have to typecast to character everytime, which is also nonsense
            }
            else
                System.out.println("and other items..");
        }
        else
            System.out.println("Cannot use");
    }

我没有放所有代码,但是如果我解释不清楚,我可以。

4

2 回答 2

4

这是接口、继承和多态发挥作用的经典案例。每当您使用 aswitch或 then 序列时,if您都应该考虑多态性。

在这种情况下,为可用项定义一个接口或抽象类。

public interface Useable {
   public void useItem(Person personUsing);
}

现在每个项目都实现了可用,您可以检查一个项目是否可用,如果它显示使用它的选项并在使用时调用该方法。

于 2015-11-16T09:58:01.540 回答
1

作为一名 SOA(面向服务的架构)开发人员,我不会在我的项目中添加逻辑,因为在这种情况下分解和合理化我的代码变得非常困难。此外,如果您想要可扩展的代码,请记住组合远比继承好。

public interface ItemInterface { 
    public String getName();
    public String[] getCharacteristics(); 
}

我会定义一些处理逻辑的项目效果:

public interface ItemEffectInterface {
    public String getName();
    public void affectCharacter(ItemInterface item, CharacterInterface character, parameters);
    public void affectInventory(ItemInterface item, InventoryInterface inventory, parameters);
    public void affectGame(ItemInterface item, GameInterface game, parameters); 
}

我为我的所有对象使用接口来在我的类之间创建低耦合(这提供了更具可扩展性、可维护性和可测试性的代码)。

AbstractItemEffect如果您想在扩展器项效果中为所有方法定义默认行为“什么都不做”,并且只为每个效果定义活动方法,则可以定义一个抽象类。

然后,如果您想要一个动态可配置的游戏,您可以在文件/数据库中定义项目和效果的交互。这是一个 JSON 示例:

[
    {
        "item": "health potion",
        "effect": "heal",
        "parameters": {
            "hp": 100
        }
    },
    {
        "item": "mana potion",
        "effect": "regen",
        "parameters": {
            "mp": 150
        }
    },
    {
        "item": "mana potion",
        "effect": "drunk",
        "parameters": {
            "duration": 1000
        }
    },
    ...
[

然后使用服务类将效果映射到使用时的项目:

public class ItemUser {
    private Map itemEffects = new HashMap();

    // Call it at service initialization after interpreting the configuration
    // (configuration is optional, you can call it directly of course).
    public void addItemEffect(ItemInterface item, ItemEffectInterface itemEffect, parameters) {
        Map effect = new HashMap();
        effect.push("effect", itemEffect);
        effect.pust("parameters", parameters);

        this.itemEffects.put(item.getName(), effect);
    }

    // Call it when you want to use an item.
    public void useItem(ItemInterface item, Character character, GameInterface game, InventoryInterface inventory) {
        Map itemEffects = this.itemEffect[item.getName()];

        // Process all the effects attached to your item 
        // on game, character, inventory, ...
    }
}

使用此架构,您可以将效果附加到许多项目,并将项目附加到许多效果。这应该可以防止您重复代码。

同时,每个物品和物品效果都会处理自己的复杂性,不会使整个系统变得更复杂。这不是您在 中描述的模式“开关盒”的情况2.。想象一下,如果您有 100 个效果和 200 个项目,那么您的班级......

对不起,我的错误/不完整的 JAVA 代码!

于 2015-11-16T15:03:24.353 回答