将 GridPane 包装在 ScrollPane 中或以编程方式对其进行修改。最有效的方法?

Wrapping a GridPane in a ScrollPane or programatically modifying it. Most efficient approach?

在一个游戏中,我有一个 GridPane,在方形单元格中显示世界的 Tiles。玩家可以使用键盘移动 column\row 显示的内容。我想到的方法是: 让 GridPane 以编程方式更改显示的图块,方法是根据玩家输入将所有内容移动 x 步。 将 GridPane 包装在 ScrollPane 中并将 ScrollPane 的滚动绑定到键盘输入。

我的问题是,假设始终加载在同一张地图上但看不见的东西,每种方法在效率方面的优缺点是什么?最具体地说,我想知道将 GridPane 包装在 ScrollPane 中是否会保持图像加载,即使它们不在屏幕上,从而影响性能,如果在这种情况下最好只在需要时重新加载它们。我也想知道是否有第三种更有效的方法我没有想过。

我正在使用 JavaFX8

一般做法

为非常大的世界提供有限视口的最有效方法是为世界使用 tile based model 并且仅加载图形资源并显示当前视口所需的图块。

基于示例 canvas 的实施

eppleton JavaFX tile 引擎很好地概述了如何实现这一点,它在 eppleton blog post. That particular implementation uses a Canvas 基于直接绘制的方法而不是面向场景图节点的方法中进行了描述。

基于示例场景图节点的实现

基于场景图的方法依赖于所谓的虚拟控件;其中控件向基础数据模型提供 windows 的单元格。 JavaFX ListView and TableView 是虚拟化控件的示例。这些虚拟控件可以支持我的数据结构,其中包含数千个项目,但实际上只有当前可见的数十个项目的可视项目显示在屏幕上。当控件滚动或修改其底层数据结构时,将调用回调来刷新每个显示单元格的图形节点。

基于场景图的网格虚拟控件的一个示例是 ControlsFX GridView。请注意,与基于 canvas 的 eppleton Tile Engine 不同,ControlsFX GridView 并非专门为游戏引擎的基于核心图块的渲染器而构建和优化,因此如果您以这种方式使用 GridView,您会需要向 GridView 的分支或扩展添加更多功能,以使其在功能上与完整的游戏图块引擎相提并论。

现有规范和工具集

请注意,现有的 Tile 地图格式规范(例如 TMX and existing editors)可以创建符合此类格式的文件。 tilemap 的使用适用于实时游戏和回合制游戏,甚至在游戏类型之外也很有用,尽管它的传统用法是用于创建视频游戏。

其他问题的答案

would you mind elaborating, even if just slightly about what you mean with GridView is not optimized?

您的主要应用程序似乎是在编写基于图块的游戏引擎。这样的引擎通常支持读取瓦片地图数据、瓦片图像数据、将动画精灵叠加到瓦片上等。这些功能不在 ControlsFX GridView 中,因为它具有不同的焦点(例如显示缩略图的视口)文件目录的图像)。关键不是 GridView 没有优化性能(因为它是),关键是 GridView 不会为您提供特定应用程序(基于图块的游戏)可能需要的最佳开箱即用功能集).

I forgot to mention in my case the Entities move Tile by Tile and not Pixel by Pixel

这使得实现更简单,因为您只需担心离散坐标处的图块,并且实体可以是精确的图块坐标,没有当前位置的偏移和图块之间的渲染。然而,它并没有真正改变使用仅在世界上的虚拟化视口的整个方法,它只渲染您当前可以看到的内容,而不是一直渲染整个世界。

Had I know all this a year ago I would had taken a very different route in my delevopment.

有时做研究是值得的,有时你会从错误中学习 :-) 我相信如果约翰卡马克当时知道他现在所知道的,他会以不同的方式写出最初的毁灭战士。我不会让这些事情让你太担心。只需评估您现在所处的位置,然后从那里出发。