JMonkey Engine 3 Loading State
For my racing game, the location the cars spawn has been a problem - because most of my worlds generate dynamically and the start pos and rotation aren’t known before hand.
So finally after like 3 years of this and working around it in various ways, I have finally created a
LoadingState to use where I please.
A reminder how
AppStates work in JME3: they designed to be separate modules which can be add/removed and disabled/enabled whenever they are required.
These are the recommended way to add things list terrain/cars/game logic/etc..
So say you want a car game, where you race against another car through checkpoints. You need something that can start the race, place you both at the start line and be able to detect who wins.
This usually involves adding a
RaceAppState which contains at least (these are all that is required for this example):
CarAppStateswhich define the car and how it moves(*1)
WorldStatefor the terrain and checkpoints
So when the
RaceAppState loads it creates a
WorldState (first), and then creates 2
It calls on the
WorldState to find the starting position but because its only just been added it hasn’t actually loaded yet.
This is because the only place to add
AppState is in an AppStates’ initialisation method, add adding it here means the sub
AppState and its initialisation occurs the frame after.
This is fine if the ‘WorldState` terrain is static so that the start locations can be computed before the game is even built. However if the world is dynamic there is a problem, which is the case here…
RaceAppState is trying to position the cars on the terrain, but the
WorldState doesn’t even know what the terrain looks like yet.
So I have created a
LoadingState, which is an appstate itself. It has arguments of:
LoadingStates= states which we want to wait on loading
PausedStates= states that we want to pause while loading is occuring
Callback= a function that we call when we are finished loading
LoadingState displays a loading message on the screen while loading, and the on loaded removes itself and calls the callback.
This is used in the class that creates the
RaceAppState to preload the world so that it doesn’t even get it in a state thats invalid.
*1 I use a CarManager AppState which you can add and remove cars whenever, as its easier to keep them more like game objects than states