问题
In a game I have a GridPane displaying the Tiles of the world in square cells. The player can, using the keyboard, move what is displayed by a column\row. The approaches I've thought of are: Having the GridPane change programmatically the displayed tiles by moving everything by x steps on player input. Wrapping the GridPane in a ScrollPane and tying the ScrollPane's scroll to Keyboard input.
My question is, assuming that things that are off-sight but on the same map are always loaded, what are the pros and cons of each approach efficiency-wise? Most specifically, I'm wondering if wrapping the GridPane in a ScrollPane would keep the Images loaded even if they are off-screen, thus impacting performance and if in that case it would be better to just reload them when needed. I'm also wondering if there's a third, more efficient way I haven't thought about.
I'm using JavaFX8
回答1:
General approach
The most efficient approach for providing a limited viewport onto a very large world is to use a tile based model for the world and to only load the graphics resources and display the tiles that are required for the current viewport.
Sample canvas based implementation
A nice overview of how to accomplish this is the eppleton JavaFX tile engine which is described in an eppleton blog post. That particular implementation uses a Canvas direct draw based approach rather than a scene graph node oriented approach.
Sample scene graph node based implementation
A scene graph based approach relies on what is termed a virtual control; where the control provides cells which are windows on to the underlying data model. The JavaFX ListView and TableView are examples of virtualized controls. These virtual controls can be backed my data structures which contain thousands of items but only visual items for the currently visible tens of items are actually shown on the screen. As the control is scrolled or its underlying data structure is modified, callbacks are invoked to refresh the graphical nodes for each displayed cell.
An example of a scene graph based virtual control for a grid is the ControlsFX GridView. Note that, unlike the canvas based eppleton Tile Engine, the ControlsFX GridView is not specifically built for and optimized to be the core tile based renderer for a game engine, so if you would use GridView in such a way, you would need to add significantly more features to a fork or extension of the GridView to bring it functionally on par with a full gameplay tile engine.
Existing specifications and toolsets
Note that there are existing specifications for Tile map formats such as TMX and existing editors to create files which conform to such formats. Usage of a tilemap is appropriate for both realtime and turn based games and may even be useful outside the gaming genre, though it's traditional usage is in the creation of video games.
Answers to additional questions
would you mind elaborating, even if just slightly about what you mean with GridView is not optimized?
Your primary application seems to be writing tile based game engine. Such an engine usually provides support for reading tile map data, tile image data, overlaying animated sprites on to the tiles, etc. Those kind of features aren't in a ControlsFX GridView because that has a different focus (e.g. displaying a viewport of thumbnail images for a file directory). The point is not that GridView is not optimized performance wise (because it is), the point is that GridView won't provide you with the optimal set of out of the box features which you might need for your particular application (a tile based game).
I forgot to mention in my case the Entities move Tile by Tile and not Pixel by Pixel
That makes implementation simpler as you only have to worry about tiles at discrete co-ordinates and the entity can be an exact tile co-ordinate without an offset for current location and rendering between tiles. However it doesn't really change the whole approach of using a virtualized viewport of only onto the world which only renders what you can currently see rather than rendering the entire world all the time.
Had I know all this a year ago I would had taken a very different route in my delevopment.
Sometimes it pays to do research and sometimes you learn by mistakes :-) I'm sure John Carmack would have written the original Doom differently if he knew then what he knows now. I wouldn't let such things worry you too much. Just assess where you are now and go from there.
来源:https://stackoverflow.com/questions/28250416/wrapping-a-gridpane-in-a-scrollpane-or-programatically-modifying-it-most-effici