2014-04-22 74 views
3

我一直在使用artemis-odblibGDX開發基於回合的瓷磚地圖遊戲。與artemis一起使用的瓷磚地圖的數據結構

我希望地圖上有不同的地形類型,比如草地,沙灘,水,山等等,這些不同的地形類型都有不同的移動成本通過以及與遊戲相關的各種附加屬性。

我考慮了幾個不同的方法目前:

  1. 我可以做地圖的系統GameMapSystem和有每種類型的每種類型地形的相關組件的實體所代表的地形(TerrainStats ,偶爾拼寫效果組件Exploding)。我主要關心的是如何管理貼圖到地形類型實體的映射。從概念上講,這應該與維護int[][]一樣簡單,其中的值與地形實體的ID相對應,但在這種情況下,臨時標記組件(Exploding)將一次附加到所有給定的地形類型。這看起來不太理想。那麼,我需要爲每個瓷磚分別設置一個實體嗎?如果我這樣做,我是不是爲實體框架創造額外的開銷?

  2. 我也考慮過製作遊戲地圖和地形類型POJOS,然後簡單地使用特殊效果的標記組件創建標記實體。然而,這樣做,它看起來像我會通過威利尼利的GameMap對象,以使各種系統能夠處理它(渲染,碰撞,路徑等)。此外,我的遊戲地圖是否也需要在任何給定時間跟蹤地圖上的實體以及他們的位置以便執行我的路徑邏輯?如果可能的話,我寧願將實體的管理完全置於實體框架的範圍之內,因爲這意味着更容易維護。

我很好奇,如果有任何方法,我還沒有檢查。否則,我會傾向於方法2,除非有辦法修復我忽略的方法#1。

回答

1

我結束了使用這兩種方法的東西。下面的代碼片段應有助於說明我承擔了方法:

class TerrainType { 
    public String displayName; 
    public String regionName; 
    public int movementCost; 
    /* additional properties omitted */ 
    /* constructors omitted */ 
} 

此結構包含一個地形類型,包括運行成本和其他遊戲相關的統計(我爲了簡化省略其餘部分)的相關信息,顯示檢查時顯示的地形類型的顯示名稱,以及從TextureAtlas拉取的TextureRegion的名稱,我的渲染器對我非常友善。

class GameMapSystem extends EntityProcessingSystem { 
    @Mapper private ComponentMapper<MapPosition> pm; 
    @Mapper private ComponentMapper<SolidObject> som; 

    private ListMultimap<MapPosition, Entity> entityByLocation; 

    private int[][] map; 
    private int width, height; 
    private Array<TerrainType> terrainTypes; 

    /** 
    * Accepts an Array of TerrainType objects and an 2d integer array with 
    * values corresponding to indices into the array for the correct type. 
    * 
    * In my case, these values are gleaned by reading a level description 
    * file, but any source should be fine. 
    */ 
    public GameMapSystem(Array<TerrainType> terrainTypes, int[][] map) { 
     super(Aspect.getForAll(MapPosition.class)); 
     this.terrainTypes = terrainTypes; 
     this.map = map; 
     this.width = map.length; 
     this.height = map[0].length; 
     this.entityByLocation = ArrayListMultimap.create(); 
    } 

    public boolean isOccupied(int x, int y) { 
     List<Entity> entities = entityByLocation(new MapPosition(x, y)); 
     for(Entity e : entities) { 
      if(som.has(e)) { 
       return true; 
      } 
     } 
     return false; 
    } 

    @Override 
    protected void inserted(Entity e) { 
     this.entityByLocation.put(pm.get(e), e); 
    } 

    @Override 
    protected void removed(Entity e) { 
     this.entityByLocation.remove(pm.get(e), e); 
    } 

    /* additional EntityProcessingSystem overrides omitted */ 
} 

這個EntityProcessingSystem然後以被動模式連接到我的世界。應該沒有任何真正的理由在這個系統中爲我的世界實際做任何處理,我真正想要的是能夠聽取insertedremoved事件將實體放入地圖。一個經理在這種情況下可能會過於矯枉過正,因爲它會告訴我每個插入或刪除的實體,而我只關心與地圖有關的地圖(或者更具體地說與地圖相關的位置)。然後,我有一些單獨的路徑查找邏輯,它會消耗額外的(這裏未見到的)方法來簡單地通過向世界對象請求這個被動系統來引導AI。

爲了完整,MapPosition類也如下所示。重要的是包含equals()hashcode()以幫助使用MapPosition作爲集合中的關鍵。

public class MapPosition extends Component 
{ 
    public int x, y; 

    public MapPosition(int x, int y) { 
     this.x = x; 
     this.y = y; 
    } 

    @Override 
    public boolean equals(Object other) { 
     if(!(other instanceof MapPosition)) { 
      return false; 
     } 

     MapPosition pos = (MapPosition)other; 

     return (pos.x == this.x && pos.y == this.y); 
    } 

    @Override 
    public int hashCode() { 
     int hash = 7; 
     hash = 59 * hash + this.x; 
     hash = 59 * hash + this.y; 
     return hash; 
    } 
} 

我很可能會試圖找到比使用番石榴Multimap最終更方便的數據結構,但它工作,現在和我感覺很舒服移動到充實公共API的論文類,其餘。如果此答案確實對其他人有幫助,請記住,此實現的ArrayListMultimap的性能未經過嚴格測試!

0

我正在找出同樣的事情。只是想分享從阿蒂米斯開發一些答案對這個案子這讓我們沒有答案其實更值得一提:

http://slick.ninjacave.com/forum/viewtopic.php?p=20125#p20125 http://slick.ninjacave.com/forum/viewtopic.php?p=20136#p20136

老實說,阿爾忒彌斯是「仍然被認爲是實驗性的」。這是一個我想看到的新範例,它很有前途,但仍然存在那些我沒有真正找到答案的問題,系統扮演的角色有多大,沒有放入實體/組件等等。這裏也有一些戰鬥我的腦袋裏想的是,當涉及到什麼似乎是一個非實體的東西,如地形,背景音樂等

而且另一條線索給出實體/組件有多大作用發揮他要區分如下:

  • 系統「它可以」在/與實體。 (「它可以」獲取EnemyTarget(系統),「它可以」SpawnNewBaddies(系統))
  • 組件是相應組件表中的錶行,並且包含特定功能/狀態的數據。

所以看起來它是由我們來探索實際的解決方案,isn`t足夠成熟的模式有一個「正確」的答案

+0

歡迎的StackOverflow!請務必參考[Tour](http://stackoverflow.com/tour)並仔細閱讀幫助中心以瞭解[如何撰寫正確答案](http://stackoverflow.com/help/how-回答)。在這種情況下,您或許可以通過至少總結鏈接中討論的問題來改進您的答案,而不是簡單地粘貼鏈接本身。 – dg99

+1

啊,好的謝謝,將盡力改進和編輯總結。 –