0

我一直在开发一个大型角色扮演游戏。问题是我在设计如何管理项目和库存系统时遇到了麻烦。目前我有类似的东西:

  • 公共抽象类 Item 有 5 个嵌套类,它们都是抽象的和静态的,代表 Items 的类型。每个嵌套类都有唯一的 use()、delete()(最终确定类实例)和 sell()(触发删除)void。它们还具有可选的 getter 和 setter 方法,例如填充所有必要字段的 setAll() 方法。
  • 默认值:具有基本价格、可交易性布尔值、字符串名称等...非常灵活
  • 武器:除了默认类型具有的东西之外,它具有整数用于装备时的统计奖励(用于equip() 和 unequip() voids)。与公开课英雄互动。
  • 装备:与武器类似,只是它有一个名为“EquipSlot”的枚举字段,用于确定装备的位置。
  • 消耗品:与默认类似,只是有一个consume() void,允许玩家在使用英雄时对英雄应用某些效果。消费通常意味着触发 delete() void。
  • 特殊:通常与任务相关的项目,其中“可交易”布尔值是静态的、最终的并且总是错误的。

现在,我制作定制物品的方式是这样的。

  • 首先,我创建了一个新类(不是抽象的)
  • 然后,我让它扩展 Item.ItemType
  • 然后,我创建了一个内部有 setAll(info) void 的构造函数。
  • 然后,我可以在其他类中使用这个类。

这一切看起来像这样:

package com.ep1ccraft.Classes.Items.Defaults;

import com.ep1ccraft.apis.Item.*;

public class ItemExample extends Item.Default {
    public ItemExample() { // Constructor
        this.setAll(lots of arguments here);
    }
}

那么我可以这样做:

ItemExample something = new ItemExample();

而且我有一个完美的 ItemExample,其中包含我想要的所有属性,因此,我可以制作它的各种实例,并使用诸如“getName()”之类的惊人方法之类的东西。

问题在于命名实例,因为我不知道如何制作一个自动化表单,该表单将为实例提供与另一个实例不同的名称,因此它们不会发生冲突。另外,我想实现一个使用插槽作为容器并且可以保持堆栈(仅限可堆叠物品)的库存系统,它的主要特点是您可以将它们拖放到其他插槽中(例如,重新组织或移动到另一个库存实例,如银行,或放置在英雄的武器或装备槽中,如果允许的话),您可以单击它们以显示一个屏幕,其中显示项目的名称、描述和可能的操作(哪个触发前面提到的 delete() 和 use() 无效)。

感谢您阅读所有内容!我知道也许我要求太多,但无论如何我都会感激任何答案!

4

1 回答 1

0

所以基本上,您要求为您的对象提供一个唯一标识符。对此可能有无数种方法,但立即想到的三种不同方法是:

1:一个UUID;就像是:

java.util.UUID.randomUUID()

优点:一个非常非常简单的解决方案......

缺点:它确实会生成大量字节(16 + 对象本身),占用内存/磁盘存储,这可能是 MMO 中的一个问题

2:全球流水号;就像是:

class ID {
    private static volatile long id = 0;
    public synchronized long nextId() {
        return id++;
    }
}

优点:同样,一个简单的解决方案......

缺点:尽管这是一个非常简单的类,但它确实包含“易失性”和“同步”,这对于 MMO 来说可能是一个问题,尤其是在它被大量使用的情况下。此外,如果您的数字用完,运行 X 年后会发生什么。64 位长确实需要创建很多命名对象,毕竟这可能不是问题......你必须自己做数学。

3:命名的全球流水号;就像是:

class NamedID {
    private static volatile Map<String, Long> idMap = new HashMap<String, Long>();
    public synchronized long nextId(String name) {
        Long id = idMap.get(name);
        if (id == null) {
            id = 0;
        } else {
            id++;
        }
        idMap.put(name, id);
        return id;
    }
}

优点:您可以将 id 的“本地化”设置为您使用的任何名称。

缺点:一个更复杂的解决方案,并且在速度方面比“2”差,因为同步持续时间更长。

注意:我不知道如何更快地提出最后一个建议;我想过使用 a ConcurrentHashMap,但这不起作用,因为它在较低级别上工作;即它不能保证两个线程在idMap.getidMap.put语句之间不会相互干扰。

于 2013-02-21T22:36:49.360 回答