All Downloads are FREE. Search and download functionalities are using the official Maven repository.

de.lessvoid.nifty.slick2d.NiftyOverlayGameState Maven / Gradle / Ivy

There is a newer version: 1.4.3
Show newest version
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