我目前正在编写基于网格的益智游戏,但遇到了问题。
我有一个抽象的Sprite类,其中每个Sprite代表我地图上的某个对象(玩家,墙壁等)。此Sprite类具有子项(Item,Entity,Obstacle),并且这些子项具有子项(Item具有InventoryItem和InstantUseItem),依此类推。只有没有其他子级的子级不是抽象的,因此您只能实例化可以在游戏中找到的具体对象(可以实例化Sword and Arrow,而不能实例化Weapon-它们的父级对象)。
我的问题是我将所有对象存储在Sprite ArrayList中的Tiles(每个地图都有width * height Tiles)上,现在我想做一些事情,例如查找Player对象在哪个Tile上,或全部找到包含敌人对象(或从其继承的类)的图块。
问题是,据我所知,我无法在Map或Tile对象中做与此类似的事情:
public ArrayList<t> findAllSpritesOfType(Type t) {
ArrayList<t> sprites = new ArrayList<t>();
for(Sprite s : this.getSprites()) {
if(s instanceof t) {
sprites.add((t) s); //Add after casting to right class
}
}
return sprites;
}
即使我尝试在Sprite中实现静态功能,我也需要这样做(在Sprite的所有子级中都是一种“自动协方差”):
public static ArrayList<this.Type> getSpritesOnTile(Tile t) {
ArrayList<this.Type> sprites = new ArrayList<this.Type>();
for(Sprite s : t.getSprites()) {
if(s instanceof this.Type) {
sprites.add((this.Type) s); //Add after casting to right class
}
}
return sprites;
}
我想到的其他方法包括:
确保我的程序符合面向对象的原则,并且保持易于扩展的状态,对于该项目非常重要。有什么方法可以实现我的任何解决方案,或者实现我的目标吗?
答案 0 :(得分:2)
看起来这就是您想要的:
public <T extends Sprite> ArrayList<T> findAllSpritesOfType(Class<T> clazz) {
ArrayList<T> sprites = new ArrayList<>();
for(Sprite s : this.getSprites()) {
if(clazz.isInstance(s)) {
sprites.add((T) s);
}
}
return sprites;
}
然后您可以像这样使用它:
List<Item> items = findAllSpritesOfType(Item.class);
另一种方法是返回流而不是列表:
public <T extends Sprite> Stream<T> findAllSpritesOfType(Class<T> clazz) {
return getSprites().stream().filter(clazz::isInstance).map(clazz::cast);
}