2013-02-21 52 views
0

我一直在开发一个庞大的角色扮演游戏。问题是我在设计项目和库存系统时会遇到问题。目前我有一些与此类似:高级项目实例管理问题

  • 公共抽象类项目有5个嵌套类,所有是抽象的,静态的代表物品的种类。每个嵌套类都有一个唯一的use(),delete()(它完成了类实例)和sell()(触发器删除)void。它们也有可选的getter和setter方法,如填充所有必需字段的setAll()方法。
  • 默认:有基础价格,可交易性布尔值,字符串名称等...非常灵活
  • 武器:除了默认类型的东西,它在装备上有统计奖金的整数(用于装备()和unquip()void)。与公共课英雄互动。
  • 装备:武器类似,只是它有一个名为“EquipSlot”枚举字段决定了它配备。
  • 耗材:类似违约,只是有一个消费()无效,允许玩家使用时受到一定影响应用到英雄。消费通常意味着触发delete()void。
  • 特殊:一般任务有关的物品,其中“可交易”布尔是静态的,最终总是假。现在

,我做定制化项目的方式是这样的。

  • 首先,我提出一个新的类(不是抽象的)
  • 然后,我让它扩展Item.ItemType
  • 然后,我做它具有SETALL(信息)空洞内的构造函数。
  • 然后,我可以在其他类中使用这个类。

这一切看起来是这样的:

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()'和那种东西的惊人的方法。来命名实例

的问题,因为我不知道如何使一个自动化的形式,这将使该实例不同的名称从另一个实例,以便它们不会发生碰撞。另外,我想实现一个库存系统,它使用槽作为容器并可以保留堆栈(仅限Stackable项),其主要特点是可以将它们拖放到其他槽中(例如,重新组织或移动到另一个库存实例(如银行),或放置在英雄的武器或装备槽中(如果允许的话)),并且您可以点击它们来显示一个屏幕,显示该项目的名称,描述和可能的操作(哪个触发器前面提到的delete()和use()void)。

谢谢你阅读所有!我知道我可能要求太多,但我会很感激任何答案!

+0

我不完全相信你的要求。你在寻找一种生成独特名字的方法吗?如果是这样,你的标准是什么?他们是否必须是人类可读的名称或ID?如果是后者,则可以使用UUID生成器。如果前者,使他们独一无二是一项挑战。 – 2013-02-21 16:47:45

+0

你需要一个独特的名字,或只是一种方法来区分引擎中的项目。 – aglassman 2013-02-21 16:48:08

+0

它们可以是ID而不会产生问题。我只需要每个实例具有不同的名称,并在Inventory用户界面中单击时可以访问。另外,每个实例都有一个在变量中声明的图标图像。这是Inventory用户界面中显示的内容。 – user2096175 2013-02-21 16:52:09

回答

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”更差,因为同步持续时间更长。

注:我无法弄清楚如何使这一最后的建议更快;我想到了使用ConcurrentHashMap,但这是行不通的,因为它工作在较低的水平;即,将不能保证两个线程不会互相idMap.getidMap.put语句之间的干扰。