2013-02-21 79 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語句之間的干擾。