场合
我使用以下技术使用JavaFX创建了一个粒子系统:
每个粒子都是一个ImageView,它包含一个带有径向渐变的图像:
粒子处理循环是一个AnimationTimer,其中粒子列表是通过列表的stream()。parallel()方法处理的,它实际上为整个系统提供了一个提升。像这样:
loop = new AnimationTimer() {
@Override
public void handle(long now) {
addParticle();
// apply force: gravity
allParticles.stream().parallel().forEach(Particle::applyForceGravity);
// move particle
allParticles.stream().parallel().forEach(Particle::move);
// update position in fx scene
allParticles.forEach(Particle::display);
// remove all particles that aren't visible anymore
removeDeadParticles();
}
};
粒子的颜色在其生命周期中通过ColorAdjust发生变化。我用火色进行测试,这样的东西包含1700个粒子:
我学到了什么:
问题
在性能方面,有没有更好的方法在JavaFX(其他节点类型,线程等)中实现粒子系统?
如果有人想玩玩具,我可以发布一些代码。
非常感谢您的专业知识!
编辑:自问询以来,您可以获得使用this gist coloradjust的粒子作为粒子的完整代码。顺便说一句,即使您预先渲染图像并且不使用coloradjust,性能也会很低。
然而,问题更多的是理论上的问题,因此挖掘代码并不是必需的。
答案 0 :(得分:4)
我想我可以添加回答我自己的问题。但我希望有经验丰富的人可以分享他们的知识,因为我想出的只是玩弄的结果:
在Canvas上绘画而不是使用JavaFX ImageView节点令人惊讶地导致速度增加至少10倍。这基本上就是我做的:
如果有人有兴趣,您可以从this gist获取完整代码。只需单击“Download Zip”并将zip代码放在JavaFX项目的“application”包中,然后启动Main类。问题中代码的不同之处在于Particle.java类。在问题中,粒子被用作节点并在动画计时器中移动,但在此答案中,只有数据用于在动画计时器中的画布上绘制图像,节点本身不会放在场景中。
您可以使用“设置”类来指定分辨率,每帧新粒子数等等。
此屏幕截图以全高清分辨率显示屏幕上的3个驱逐者和 25400 粒子,运行速度为60fps:
答案 1 :(得分:0)
我认为将这两行结合起来也可能有所帮助:
// apply force: gravity
allParticles.stream().parallel().forEach(Particle::applyForceGravity);
// move particle
allParticles.stream().parallel().forEach(Particle::move);
有点像这样:
allParticles.stream().parallel().forEach(particle -> {
particle.applyForceGravity();
particle.move();
});
这样你就不会有两倍的开销。