2014-04-22 37 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

啊,好的谢谢,将尽力改进和编辑总结。 –