java如何正确删除JavaFX中动画的图像
我试图创建一个简单的太空入侵者游戏。这是我第一次参加比赛,所以我有一些问题。入侵者是一个矩形的物体,上面有一个老式入侵者的图像。在每一帧中,我将这些框向右绘制15个像素,然后使用root。getChildren()。remove(),以删除每个帧中的精灵。但它会导致一些奇怪的行为。它看起来好像没有足够快地被移除,所以就在我启动应用程序的时候,它有点爆炸,之后似乎有一点延迟,导致两个图像不断显示
我想这可能会帮助你看到它自己,所以我会张贴我的所有文件在这里
public class Main extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) throws Exception {
primaryStage.setTitle("Space invaders");
primaryStage.setResizable(false);
Group root = new Group();
Scene game = new Scene(root, Color.BLACK);
primaryStage.setFullScreen(true);
Images images = new Images();
// Make canvas and add it to primaryStage
Canvas canvas = new Canvas(1280,720);
root.getChildren().add(canvas);
GraphicsContext gc = canvas.getGraphicsContext2D();
new AnimationTimer() {
int move = 0;
private long lastUpdate = 0;
ArrayList<Sprite> enemies = new ArrayList<>();
@Override
public void handle(long now) {
if (now - lastUpdate >= 150_000_000) {
int spacing = 0;
try {
for (int i = 0; i < enemies.size(); i++) {
root.getChildren().remove(enemies.get(i));
enemies.remove(i);
}
} catch (IndexOutOfBoundsException ioobe) {
System.out.println(ioobe.toString());
}
for (int i = 0; i < 12; i++) {
for (int j = 0; j < 6; j++) {
Sprite enemy = new Sprite(60 * i + spacing + move, 43 * j, 60, 43, "enemy", true, images.getEnemy1());
enemies.add(enemy);
root.getChildren().add(enemy);
}
spacing += 15;
}
move += 5;
lastUpdate = now;
}
}
}.start();
primaryStage.setScene(game);
primaryStage.show();
}
}
如果您想自己运行该程序,则她是Sprite类:
public class Sprite extends Rectangle {
private String type;
private Boolean alive;
public Sprite(int x, int y, int w, int h, String type, boolean alive, Image image) {
this.setTranslateX(x);
this.setTranslateY(y);
this.setWidth(w);
this.setHeight(h);
this.type = type;
this.alive = alive;
this.setFill(new ImagePattern(image));
}
public String getType() {
return type;
}
public Boolean getAlive() {
return alive;
}
}
# 1 楼答案
正确的实现不需要捕获
IndexOutOfBoundsException
。我不知道为什么会抛出这样的异常,因为检查i < enemies.size()
应该确保索引是有效的但是请注意,这会跳过其他每个列表元素:
首先,从两个列表中删除
enemies
的第一个元素(索引0处的元素)。这将导致enemies
列表中剩余的所有元素向左移动,即删除之前位于索引1的元素现在位于索引0
。由于在每次循环迭代后增加索引,因此将跳过奇数索引处的所有元素顺便说一句,有一种更简单的实现方法:
注
应该避免在每个帧中重新创建精灵。如果可以避免的话,
Node
的内存需求不会使它们成为您应该扔掉的对象。否则,垃圾收集器最多只能忙于清理您“扔掉”的对象,最坏的情况是发生OutOfMemoryException
重新使用精灵并修改属性
我还建议使用
ImageView
而不是用ImagePattern
填充的Rectangle
。您可以使用fitWidth
和fitHeight
属性调整大小# 2 楼答案
这不是场景图应该使用的方式。为什么你总是移除并重新添加你的精灵?你为什么不通过你已经在使用的setTranslateX/Y更新他们的位置呢