迭代一个超类的列表,同时允许删除并转换为子类型

时间:2013-12-21 20:45:55

标签: list generics inheritance game-engine

我正在为较旧的街机游戏编写引擎。随着引擎我正在写太空侵略者。我们的想法是让构成引擎的类足够通用,以适应各种各样的街机游戏,然后像Space Invaders这样的特定游戏扩展引擎并填充特定部分。

我有一个游戏引擎开发成两个抽象类,创建游戏循环并根据循环连续之间的经过时间更新精灵。在游戏引擎的一个类中,我有一个资源管理器,其中包含敌人,敌人射弹和玩家射弹的精灵列表。资源管理器当前将这些列表存储为Sprite类型的ArrayLists。然后,游戏引擎在更新方法中迭代这些Sprite列表并更新Sprite。

然后我开始研究太空入侵者并意识到我需要为我的玩家船(生命,玩家状态)扩展Sprite,并且还需要为外星人(点,外星人状态)扩展Sprite。我仍然可以在资源管理器中将我的播放器存储为Sprite,当我需要在SpaceInvaders类中使用播放器时,我可以调用ResourceManager.getPlayer(),它将播放器作为Sprite返回,但是我可以将它转换为播放器。

当我尝试与外星人合作时,问题就出现了。我创建了一个Alien类,它也扩展了Sprite。当我创建外星人时,我将它们创建为Alien对象,然后将它们传递给资源管理器,后者将它们存储在Sprite类型的ArrayList中。在我的碰撞检查方法中,我遍历外星人列表:

for (Iterator<Sprite> iter = resources.getPlayerProjectiles().iterator();
            iter.hasNext();) {
        boolean shotRemove = false;
        Sprite sprite = iter.next();
        for (Iterator<Sprite> iterAlien = resources.getEnemies().iterator();
                iterAlien.hasNext();) {
            Sprite alien = iterAlien.next();
            if (collision(sprite,alien)) {
                shotRemove = true;
                iterAlien.remove();
            }
        }
        if (sprite.getY() < 100 || shotRemove)
            iter.remove();
    }

此时我想使用Alien独有的方法,比如在shotRemove = true行下面写分数+ = alien.getPoints()。但是这个方法只知道外星人是一个Sprite,因为iterAlien是一个Sprite类型的迭代器,因为resources.getEnemes()是一个Sprite类型的列表。如果我尝试将外星人作为外星人施放,我会得到一个classCastException。

总而言之,我希望能够将资源管理器中的列表保持为尽可能通用(Sprite),因为引擎只知道Sprite,但是当我遍历它们时能够使用列表游戏特定类作为扩展Sprite的类(在本例中为Alien)。

我曾尝试在资源管理器中使用像E extends Sprite这样的泛型,但我无法让它工作。我已经阅读了一些关于通配符(?)的内容,但我认为这不是我想要做的。我认为E扩展Sprite是我想要的,因为那时列表是一些扩展Sprite的泛型类型,可以被视为Sprite(在引擎中)或E(SpaceInvaders中的Alien)。

1 个答案:

答案 0 :(得分:0)

你不能保证Sprite是外星人,所以请使用instanceof,例如:

if (sprite instanceof Alien) {
    Alien alien = (Alien)sprite;
    // do something with alien
}

泛型在这里无法帮助你。