【发布时间】:2013-12-21 20:45:54
【问题描述】:
我正在为较旧的街机游戏编写引擎。除了引擎,我还在编写 Space Invaders。这个想法是让构成引擎的类足够通用,以适应各种街机游戏,然后像 Space Invaders 这样的特定游戏扩展引擎并填充特定部分。
我有一个开发成两个抽象类的游戏引擎,它们创建一个游戏循环并根据循环连续之间的经过时间更新精灵。在一类游戏引擎中,我有一个资源管理器,其中包含敌人、敌人射弹和玩家射弹的 Sprite 列表。资源管理器当前将这些列表存储为 Sprite 类型的 ArrayList。然后,游戏引擎在更新方法中遍历这些 Sprite 列表并更新 Sprite。
然后我开始研究 Space Invaders,并意识到我需要为我的玩家飞船(生命、玩家状态)扩展 Sprite,还需要为外星人(点数、外星人状态)扩展 Sprite。我仍然可以将我的播放器作为 Sprite 存储在资源管理器中,当我需要在 SpaceInvaders 类中使用播放器时,我可以调用 ResourceManager.getPlayer() 将播放器作为 Sprite 返回,但随后我可以将其转换为播放器。
当我尝试与外星人合作时,问题就出现了。我制作了一个也扩展了 Sprite 的 Alien 类。当我创建外星人时,我将它们创建为 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 行下方写入 score += alien.getPoints()。但是该方法只知道alien 是Sprite,因为iterAlien 是Sprite 类型的迭代器,因为resources.getEnemes() 是Sprite 类型的列表。如果我尝试将外星人投射为外星人,我会得到一个 classCastException。
总而言之,我希望能够使资源管理器中的列表尽可能通用(Sprite),因为引擎只知道 Sprite,但是当我遍历它们时能够使用列表游戏特定类作为扩展 Sprite 的类(在本例中为 Alien)。
我曾尝试在资源管理器中使用像 E extends Sprite 这样的泛型,但我无法让它工作。我已经阅读了一些关于通配符(?)的内容,但我认为这不是我想要做的。我认为 E extends Sprite 是我想要的,因为该列表是一些扩展 Sprite 的通用类型,可以被视为 Sprite(在引擎中)或 E(SpaceInvaders 中的外星人)。
【问题讨论】:
-
其实我认为至少一个演员应该工作。如果并非总是如此,您的 getEnemies 会返回一个不仅包含 Alien 对象的列表。此外,如果您确实在列表中混合了子类型,那么如果您想调用特定于子类型的方法,则无法进行强制转换。泛型对此无济于事。
标签: list generics inheritance game-engine