de.lessvoid.nifty.slick2d.NiftyOverlayGameState Maven / Gradle / Ivy
package de.lessvoid.nifty.slick2d;
import de.lessvoid.nifty.Nifty;
import de.lessvoid.nifty.render.batch.BatchRenderDevice;
import de.lessvoid.nifty.slick2d.input.ForwardingInputSystem;
import de.lessvoid.nifty.slick2d.input.SlickInputSystem;
import de.lessvoid.nifty.slick2d.input.SlickSlickInputSystem;
import de.lessvoid.nifty.slick2d.render.batch.SlickBatchRenderBackendFactory;
import de.lessvoid.nifty.slick2d.sound.SlickSoundDevice;
import de.lessvoid.nifty.slick2d.time.LWJGLTimeProvider;
import de.lessvoid.nifty.spi.render.RenderDevice;
import de.lessvoid.nifty.spi.sound.SoundDevice;
import de.lessvoid.nifty.spi.time.TimeProvider;
import org.newdawn.slick.*;
import org.newdawn.slick.state.GameState;
import org.newdawn.slick.state.StateBasedGame;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.logging.Logger;
public abstract class NiftyOverlayGameState implements GameState,
NiftyCarrierUser,
NiftyInputForwarding,
NiftyOrderControl {
/**
* The logger for this class.
*/
@Nonnull
private static final Logger LOGGER = Logger.getLogger(NiftyOverlayGameState.class.getName());
/**
* The input system that is used by this game state.
*/
@Nullable
private SlickInputSystem inSystem = null;
/**
* The carrier of the Nifty-GUI.
*/
@Nullable
private NiftyCarrier niftyCarrier;
/**
* This variable is switched to {@code true} once the GUI is initialized for this game state.
*/
private boolean guiPrepared;
/**
* This variable provides the control over the forwarding implementations.
*/
@Nullable
private ForwardingInputSystem inputForwardingControl;
/**
* The render order that is used in this game.
*/
@Nonnull
private NiftyRenderOrder renderOrder;
/**
* The update order that is used in this game.
*/
@Nonnull
private NiftyUpdateOrder updateOrder;
/**
* The last reported screen height.
*/
private int lastHeight;
/**
* The last reported screen width.
*/
private int lastWidth;
/**
* Default constructor.
*/
protected NiftyOverlayGameState() {
setRenderOrder(NiftyRenderOrder.NiftyOverlay);
setUpdateOrder(NiftyUpdateOrder.NiftyLast);
}
@Override
public final void setRenderOrder(@Nonnull final NiftyRenderOrder order) {
renderOrder = order;
}
@Override
public final void setUpdateOrder(@Nonnull final NiftyUpdateOrder order) {
updateOrder = order;
}
/**
* Enter the game state.
*/
@Override
public final void enter(@Nonnull final GameContainer container, final StateBasedGame game) throws SlickException {
final Input input = container.getInput();
input.removeListener(inSystem);
input.addListener(inSystem);
if (niftyCarrier != null && niftyCarrier.isUsingRelayInputSystem()) {
niftyCarrier.setInputSystem(inSystem);
}
enterState(container, game);
}
/**
* Enter the game state. This function is called during the default {@link #enter(GameContainer, StateBasedGame)}
* function call.
*
* @param container the container that displays the game
* @param game the state based game this state is a part of
*/
protected abstract void enterState(GameContainer container, StateBasedGame game);
@Nullable
@Override
public final ForwardingInputSystem getInputForwardingControl() {
return inputForwardingControl;
}
@Nonnull
@Override
public final NiftyRenderOrder getRenderOrder() {
return renderOrder;
}
@Nonnull
@Override
public final NiftyUpdateOrder getUpdateOrder() {
return updateOrder;
}
/**
* Initialize the game and the GUI.
*/
@Override
public final void init(@Nonnull final GameContainer container, @Nonnull final StateBasedGame game)
throws SlickException {
if (niftyCarrier == null) {
//noinspection HardCodedStringLiteral
LOGGER.warning("Better use the Nifty-GameState implementations with the NiftyStateBasedGame.");
niftyCarrier = new NiftyCarrier(false);
}
initGameAndGUI(container, game);
if (!niftyCarrier.isInitialized()) {
throw new IllegalStateException("NiftyGUI was not initialized.");
}
container.getInput().removeListener(game);
}
/**
* Initialize the game. This function is called during {@link #init(GameContainer, StateBasedGame)}. During this call
* its needed to initialize the Nifty GUI with own options by calling {@link #initNifty(GameContainer, StateBasedGame,
* RenderDevice, SoundDevice, SlickInputSystem, TimeProvider)} .
*
* @param container the game container that displays the game
* @param game the state based game this state is part of
*/
protected abstract void initGameAndGUI(@Nonnull GameContainer container, @Nonnull StateBasedGame game);
@Override
public final boolean isInputForwardingSupported() {
return inputForwardingControl != null;
}
/**
* Leave this game state.
*/
@Override
public final void leave(@Nonnull final GameContainer container, @Nonnull final StateBasedGame game)
throws SlickException {
final Input input = container.getInput();
input.removeListener(inSystem);
leaveState(container, game);
}
/**
* Leave the game state. This function is called during the default {@link #leave(GameContainer, StateBasedGame)}
* function call.
*
* @param container the container that displays the game
* @param game the state based game this state is a part of
*/
protected abstract void leaveState(@Nonnull GameContainer container, @Nonnull StateBasedGame game);
/**
* Render the game.
*/
@Override
public final void render(
@Nonnull final GameContainer container,
@Nonnull final StateBasedGame game,
@Nonnull final Graphics g) throws SlickException {
if (niftyCarrier != null && niftyCarrier.isInitialized()) {
Nifty nifty = niftyCarrier.getNifty();
assert nifty != null; // checked by isInitialized
switch (renderOrder) {
case NiftyOverlay:
renderGame(container, game, g);
nifty.render(false);
break;
case NiftyBackground:
nifty.render(true);
renderGame(container, game, g);
break;
}
} else {
renderGame(container, game, g);
}
}
/**
* This function is supposed to be used to render the game. It is called during the call of the {@link
* #render(GameContainer, StateBasedGame, Graphics)} function.
*
* @param container the container that displays the game
* @param game the state based game this state is part of
* @param g the graphics instance that is used to draw the game
*/
protected abstract void renderGame(
@Nonnull GameContainer container,
@Nonnull StateBasedGame game,
@Nonnull Graphics g);
/**
* Update the game.
*/
@Override
public final void update(
@Nonnull final GameContainer container,
@Nonnull final StateBasedGame game,
final int delta) throws SlickException {
if (niftyCarrier != null && niftyCarrier.isInitialized()) {
Nifty nifty = niftyCarrier.getNifty();
assert nifty != null; // checked by isInitialized()
final int currentHeight = container.getHeight();
final int currentWidth = container.getWidth();
if ((currentHeight != lastHeight) || (currentWidth != lastWidth)) {
lastHeight = currentHeight;
lastWidth = currentWidth;
nifty.resolutionChanged();
}
switch (updateOrder) {
case NiftyLast:
updateGame(container, game, delta);
nifty.update();
break;
case NiftyFirst:
nifty.update();
updateGame(container, game, delta);
break;
}
} else {
updateGame(container, game, delta);
}
}
/**
* This function is supposed to be used to update the state of the game. It called during the call of the {@link
* #update(GameContainer, StateBasedGame, int)} function.
*
* @param container the container that displays the game
* @param game the state based game this state is part of
* @param delta the time since the last update
*/
protected abstract void updateGame(@Nonnull GameContainer container, @Nonnull StateBasedGame game, int delta);
@Override
public void setCarrier(@Nonnull final NiftyCarrier carrier) {
niftyCarrier = carrier;
}
/**
* Initialize the Nifty GUI for this game. This function will use the default {@link TimeProvider}. Also it will use
* the render and sound devices that are provided with this library. As for the input it will forward all input to the
* Slick {@link InputListener} that is implemented in this class.
*
* @param container the container used to display the game
* @param game the game this state is part of
* @throws IllegalStateException in case this function was called before
* @see SlickSoundDevice
* @see SlickSlickInputSystem
*/
protected final void initNifty(@Nonnull final GameContainer container, @Nonnull final StateBasedGame game) {
initNifty(container, game, new SlickSlickInputSystem(this));
}
/**
* Initialize the Nifty GUI for this game. This function will use the default {@link TimeProvider}. Also it will use
* the render and sound devices that are provided with this library.
*
* @param container the container used to display the game
* @param game the game this state is part of
* @param inputSystem the input system that is supposed to be used
* @throws IllegalStateException in case this function was called before
* @see SlickSoundDevice
*/
protected final void initNifty(
@Nonnull final GameContainer container,
@Nonnull final StateBasedGame game,
@Nonnull final SlickInputSystem inputSystem) {
initNifty(container, game, new BatchRenderDevice(SlickBatchRenderBackendFactory.create(container)), new SlickSoundDevice(), inputSystem);
}
/**
* Initialize the Nifty GUI for this game. This function will use the default {@link TimeProvider}.
*
* @param container the container used to display the game
* @param game the game this state is part of
* @param renderDevice the render device that is supposed to be used to render the GUI
* @param soundDevice the sound device that is supposed to be used
* @param inputSystem the input system that is supposed to be used
* @throws IllegalStateException in case this function was called before
*/
protected final void initNifty(
@Nonnull final GameContainer container,
@Nonnull final StateBasedGame game,
@Nonnull final RenderDevice renderDevice,
@Nonnull final SoundDevice soundDevice,
@Nonnull final SlickInputSystem inputSystem) {
initNifty(container, game, renderDevice, soundDevice, inputSystem, new LWJGLTimeProvider());
}
/**
* Initialize the Nifty GUI for this game.
*
* @param container the container used to display the game
* @param game the game this state is part of
* @param renderDevice the render device that is supposed to be used to render the GUI
* @param soundDevice the sound device that is supposed to be used
* @param inputSystem the input system that is supposed to be used
* @param timeProvider the time provider that is supposed to be used
* @throws IllegalStateException in case this function was called before
*/
protected final void initNifty(
@Nonnull @SuppressWarnings("TypeMayBeWeakened") final GameContainer container,
@Nonnull final StateBasedGame game,
@Nonnull final RenderDevice renderDevice,
@Nonnull final SoundDevice soundDevice,
@Nonnull final SlickInputSystem inputSystem,
@Nonnull final TimeProvider timeProvider) {
if (guiPrepared) {
throw new IllegalStateException("The NiftyGUI was already initialized. Its illegal to do so twice.");
}
guiPrepared = true;
inputSystem.setInput(container.getInput());
if (niftyCarrier != null) {
if (niftyCarrier.isInitialized()) {
if (!niftyCarrier.isUsingRelayInputSystem()) {
throw new IllegalStateException("Detected carrier that was already initialized without relay.");
}
} else {
niftyCarrier.initNifty(renderDevice, soundDevice, inputSystem, timeProvider);
}
} else {
throw new IllegalStateException("Carrier for Nifty is not set yet.");
}
if (inputSystem instanceof ForwardingInputSystem) {
inputForwardingControl = (ForwardingInputSystem) inputSystem;
}
inSystem = inputSystem;
Nifty nifty = niftyCarrier.getNifty();
if (nifty == null) {
throw new IllegalStateException("Nifty is not properly initialized.");
}
prepareNifty(nifty, game);
}
/**
* This function should be used to prepare the actual GUI and the controllers of the Nifty GUI. It is called right
* after the Nifty GUI got initialized.
*
* @param nifty the Nifty GUI that got initialized
* @param game the game this state is part of
*/
protected abstract void prepareNifty(@Nonnull Nifty nifty, @Nonnull StateBasedGame game);
/**
* Get the instance of the NiftyGUI that is used to render this screen.
*
* @return the instance of the NiftyGUI
*/
@Nullable
public final Nifty getNifty() {
if (niftyCarrier == null) {
return null;
}
return niftyCarrier.getNifty();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy