有关 Swing 优化和实现的信息,请参阅其他答案,因为我的答案是特定于 JavaFX 的。
如果您坚持使用JavaFX实现,可以尝试以下几种方法:
- 使用 node.setCache(true) 打开节点缓存。
- 使用 node.setCacheHint(CacheHint.SPEED) 启用高速节点转换。
- 提供一个没有效果的实现和另一个有效果的实现,看看没有效果的实现是否表现得更好。(如果是这种情况,您可能需要使用更有效的效果链或完全放弃某些效果)。
- 检查 JavaFX 系统要求,以确保您的设置在硬件/操作系统/驱动程序组合方面满足硬件加速的最低要求。
- 如果您使用的是区域和基于 css 的处理,请注意 css 系统不会造成太多开销(例如,通过拥有不使用 css 的代码版本并比较其性能)。
- 如果需要,实现一定程度的细节缩放(例如,当缩小时,为整个房屋提供单个图像,而不是为每个房屋瓷砖提供单独的图像)。
- 确保只加载一次给定的图像,并在多个图像视图中重复使用它。
- 使用探查器识别瓶颈。
- 更换测试 CPU 或图形卡,以查看其中任何一个是否是瓶颈。
- 尝试 Java 8 预览版,它具有许多针对 JavaFX 的内部性能优化功能。
- 如果要加载大量图像,请使用后台加载,并在加载图像时在前面播放动画或进度条。
- 如果要加载大量图像,请在Image构造函数中预先缩放它们,以便它们不会占用太多内存或(可能)需要额外的像素的额外处理能力(只有在使用许多不同的非常高分辨率的纹理时才真正需要考虑 - 您似乎没有这样做)。
例如:
Image tile = new Image("tile.png");
Group house = new Group();
house.setCache(true);
house.setCacheHint(CacheHint.SPEED);
Effect lighting = new Lighting();
for (int i = 0; i < houseWidth; i++) {
// here is the critical part => don't do new ImageView(new Image("tile.png"))
ImageView tileView = new ImageView(tile));
tileView.setEffect(lighting);
tileView.setCache(true);
tileView.setCacheHint(CacheHint.SPEED);
house.add(tileView);
}
曼特里德的建议很有趣。我相信,使用JavaFX,您不需要自己实现脏矩形算法(因为底层平台能够为您处理脏区域处理)。可能是这样,因为它是一种通用机制,它没有提供特定情况所需的优化级别,在这种情况下,您需要自己处理脏处理(例如,通过从场景图中删除节点并根据需要重新添加它们)。
此外,通过在 JavaFX 中定义效果,将效果应用于屏幕外 ImageView 节点,然后拍摄屏幕外 ImageView 节点的快照以获得预先计算的图像,可以预先计算图像上的模糊/亮度/等。此技术将允许您重用现有的 JavaFX 效果管道,而无需使用 ConvolveOp 机制重新实现它。也许您可以通过在ImageView节点上将缓存设置为true并将cacheHint设置为速度来获得相同的性能级别,因为我相信这在幕后做了类似的事情(即以增加内存使用为代价来提高速度)。
JavaFX 场景图非常高效,可以处理数千个节点。但是,您的应用程序中可能有多个。如果上述优化点对您没有帮助,您可能需要计算节点数量,并将对您的问题(也许还有一些来源)的引用发布到open-jfx邮件列表中,其中了解JavaFX应用程序优化细节的JavaFX开发人员就在那里。
JavaFX 8对3D场景图的支持远远优于JavaFX 2.2中的(大部分无用的)3D场景图。您当前的应用程序似乎是伪3D,您可以在其中转换2D对象,单独应用照明效果并调整每个图块的亮度以获得3D外观。如果是这种情况,使用具有统一3D照明模型的完全硬件加速的3D场景图最终可能会表现得更好,看起来更好,更易于使用 - 您必须在应用程序的上下文中对其进行评估,以查看是否值得将您的应用程序从2D JavaFX场景图切换到3D JavaFX场景图,或者从JavaFX切换到Swing或其他一些技术,如libgdx。
补遗
对Mizur的一些其他问题的回答:
那么,为什么它们如此耗电呢?
从我的回答中可以看出,性能涉及许多方面,因此,对于为什么某些东西耗电的原因,挑出一个特定的原因有时很困难,而且通常是不可能的。有时,它是导致性能问题的各种因素的组合。最大的胜利通常来自优化在内部大多数循环中执行的东西,或者通过改变用于解决问题的策略。
如果他们需要这么多,请让我移动瓷砖,或者请只是显示,不是吗?
就仅消耗资源来存储您移动的内容而言,JavaFX 场景图对此进行了一些优化,而像缓存之类的东西可以进一步提高性能。也许它们对于您的特定用例或您使用系统的方式还不够。您可能需要更改算法以减少系统负载。
有没有办法使用这种 Imageview 技术生成每个建筑物的图像,然后将这些建筑物的图像集成到最终场景中?
是 - 您可以使用许多图像和节点将建筑物渲染到屏幕外场景,拍摄屏幕外场景的快照以创建单个图像,然后将该图像叠加在最终场景上。