我有Tile课。我有37个Tile对象实例,我希望每个Tile对象能够容纳3个不同的arraylists,或者任何集合,我不确定哪个最适合我的需要。
现在我的班级设置如下:
public class Tile {
public Tile n0;
public Tile n1;
public Tile n2;
public Tile n3;
public Tile n4;
public Tile n5;
public Tile (){
}
public Tile (Terrain ter){
}
public void initNeighbours(){
//middle column
Tile t0 = new Tile();
Tile t1 = new Tile();
Tile t2 = new Tile();
Tile t3 = new Tile();
Tile t4 = new Tile();
Tile t5 = new Tile();
Tile t6 = new Tile();
//middle column
//t0
t0.n0 = null;
t0.n1 = null;
t0.n2 = t7;
t0.n3 = t1;
t0.n4 = t22;
t0.n5 = null;
etc
}
}
我希望拥有一系列生物对象,一系列建筑物和一系列金币。我希望能够打印出每个瓷砖上的内容,添加和删除东西,从一个瓷砖中移除东西,并将相同的东西添加到另一个瓷砖的集合中。
这样做的最佳方式是什么?
答案 0 :(得分:2)
免责声明:这将是一个非常高级的答案,没有代码。
Tile
你有一个六边形网格。使用Tile
个邻居(普通数组)创建一个Tile[6]
类。创建一个外部函数(可能作为Main类的一部分),它将初始化网格,可能从文件中读取其配置,或者您拥有的任何其他源(甚至硬编码) - 指向保持{{1} class clean。
每块瓷砖有什么作用?这是一个关键问题。我倾向于假设您正在制作一种游戏,您可以将对象放在此六边形网格上,这看起来每个网格都可以 生物或一块金或一幢建筑物。我将继续这个假设(你还没有真正定义这些东西)。
Tile
现在为了简化tile只能有一个对象的保证,你引入了一个抽象类型TileObject
。根据您以后的需要,您可以将其设置为抽象类或接口。您的TileObject
,Creature
和Gold
都继承自类/接口。
现在,您可以考虑如何管理这些类型以及它们实际需要的关系。对于初学者来说,很明显每个Building
都知道Tile
,如果有的话。
如果您还需要知道任何给定的TileObject
,以及它所属的TileObject
,显然您需要Tile
反向引用。我将它放在Tile
中并使TileObject
成为一个抽象类。
TileObject
如果你需要能够枚举所有瓷砖,你需要一个瓷砖集合。将它与Collections
类分开,可能在Tile
课程中。确保它是一个无序的集合(只是因为排序没有意义),我会选择Main
。如果您需要能够枚举所有HashSet
,请对它们进行无序收集。如果您需要能够枚举所有单独类型的对象,请跳过包含所有内容的集合,并选择三个独立的集合。如果你需要表示尚未放置的对象,已被消耗但需要被跟踪的对象,等等。我会为每一组创建一个集合,它将使它们更容易枚举。
现在是棘手的部分。您需要定义可以在网格上完成的内容的非常清晰的语义。对于可以采取的每个操作,您需要定义一个非常清晰的方法,最有可能在TileObjects
类中。
考虑Tile
:显然,如果瓷砖是空的,可以在其上放置任何东西。确保设置正向引用(Tile.place (TileObject tileObject)
)以及反向引用(this.tileObject = tileObject
)。您是否检查过tileObject尚未设置tileObject.tile = this
?如果图块不为空,那么哪种展示位置是兼容的?
考虑tile
:它需要确保目标图块(Tile.moveFrom (Tile tile)
)为空或者具有兼容的对象,以便被源图块中包含的对象替换({{1} })。 this
必须为非null。您必须更新两个前向引用和一个后引用。
例如,考虑一个生物(或玩家)消耗黄金的概念。 tile
行动需要认识到这一点。有多少特例?如果只有一个,那就处理它。如果很多,请在适当的tile.tileObject
:Tile.moveFrom (Tile tile)
另外调用TileObject
中实施每个特定的 A置于B 案例。如果您有许多Tile.move
个子类型,并且有许多有效但特定的组合被放置,您将需要multimethods,但我离题了。
考虑一个生物tile.tileObject.placedOver(this.tileObject)
的死亡:它需要从其瓷砖中删除自己。您需要将其从生物/平铺对象的集合中删除。也许您需要知道哪些生物死亡,在这种情况下将其移至专用的TileObject
集合等等。
对于每个可能的行动,你必须非常认真地考虑所有后果,在明确说明意图的方法中实施它们,然后你可以玩整个事情。也许你有这样的规则:“如果这种情况发生在Tile上,那么就会发生在它的邻居身上(可能有一个概率)” - 然后它会变得有点复杂。
为了上帝的缘故,跳过吸气剂和制定者 - 你不是在写API。
答案 1 :(得分:1)
那么你需要在每个Tile对象,或者Creature,Building和Gold的集合中收集Tile对象吗?我会考虑重写所有可以包含在tile中的对象,扩展一个抽象的TileData类或者其他东西..所以你可以只有一个
列表 ArrayList<TileData> stuffOnThisTile;
但是这可能有所帮助吗?再一次,不确定你在寻找什么。
public class Tile {
//public Tile n0;
//public Tile n1;
//public Tile n2;
//public Tile n3;
//public Tile n4;
//public Tile n5;
private ArrayList<Tile> tiles;
private ArrayList<Creature> creatures;
private ArrayList<Building> buildings;
private ArrayList<Gold> golds;
public Tile (){
initLists();
}
public Tile (Terrain ter){
}
private void initLists(){
tiles = new ArrayList<Tile>();
creatures = new ArrayList<Creature>();
buildings = new ArrayList<Building>();
golds = new ArrayList<Gold>();
}
public boolean addGold(Gold g){
golds.add(g);
return true;
}
public Gold getGoldByIndex(int index){
return golds.get(index);
}
public ArrayList<Gold> getAllGold(){
return golds;
}
public String toString(){
String returnString = "";
for (Building b : buildings){
returnString += b.toString();
}
for (Creature c : creatures){
returnString += c.toString();
}
for (Gold g : golds){
returnString += g.toString();
}
return returnString;
}
}