Package com.thecherno.cherno.engine

Source Code of com.thecherno.cherno.engine.Cherno

package com.thecherno.cherno.engine;

import com.thecherno.cherno.engine.graphics.Color;
import com.thecherno.cherno.engine.graphics.Display;
import com.thecherno.cherno.engine.graphics.Screen;
import com.thecherno.cherno.engine.graphics.Texture;
import com.thecherno.cherno.engine.graphics.Window;
import com.thecherno.cherno.engine.input.Keyboard;
import com.thecherno.cherno.engine.input.Mouse;
import com.thecherno.cherno.engine.interfaces.Renderable;

/**
* {@code Cherno} engine template class. This class should be the superclass of your main game class. All of the methods
* required for the main game loop, rendering and creating graphics, as well as creating a context for the graphics to
* run inside of are in this class.
*
* <p>
*
* Methods to override: <br>
* <ul>
* <li>{@code init()}</li>
* <li>{@code update()}</li>
* <li>{@code render()}</li>
* </ul>
* Make sure you call {@code show()} at the end of your {@code render()} method to push the graphics to the screen!
* <p>
* Your implementation of the {@code init()} method should contain the following calls, in the specified order:
* <ol>
* <li>{@code createDisplay(title, width, height)}</li>
* <li>{@code setInput(device(s))}</li>
* <li>{@code start()}</li>
* </ol>
* This will create the display with the appropriate input, and start the main game loop.
*
* @version 0.1a
* @author Yan Chernikov
*
*/
public abstract class Cherno implements Runnable {

  // Whether or not the game is running, which dictates whether the main game loop runs or not.
  private boolean running = false;
  // The Screen object, for rendering.
  public Screen screen;
  // The Display object, for pushing Screen elements to the Window.
  private Display display;

  // The Thread object for handling the main game loop thread.
  private Thread thread;
  // A long to track how long it takes to load the engine when the game starts.
  private long startTimer = 0L;

  // The byte code for the keyboard.
  protected final byte KEYBOARD = Keyboard.CODE;
  // The byte code for the mouse.
  protected final byte MOUSE = Mouse.CODE;

  /**
   * Starts the main game loop on a new thread, called "Cherno".
   */
  protected final void start() {
    running = true;
    thread = new Thread(this, "Cherno");
    thread.start();
  }

  /**
   * Creates a new Display and Window with the given name and size.
   *
   * @param name
   *            The title of the window.
   * @param width
   *            The width of the display (and window) in pixels.
   * @param height
   *            The height of the display (and window) in pixels.
   */
  protected final void createDisplay(String name, int width, int height) {
    startTimer = System.currentTimeMillis();
    display = new Display(new Window(name, width, height));
    screen = new Screen(width, height, 1.0);
  }

  protected final void createDisplay(String name, int width, int height, double scale) {
    startTimer = System.currentTimeMillis();
    display = new Display(new Window(name, width, height));
    display.setScale(scale);
    screen = new Screen(width, height, scale);
  }

  /**
   * Sets which devices the engine will use for input. Rather than running this method twice, you can specify two (or
   * more) devices, separated by a bitwise or ("|").
   *
   * <p>
   * <strong>eg.</strong> {@code setInput(KEYBOARD | MOUSE);}
   *
   * @param device
   *            The device(s) code (grab this from the {@link Cherno} or relevant device class.
   *
   */
  protected final void setInput(int device) {
    display.enable((byte) device);
  }

  /**
   * The {@code run()} method: this contains the main game loop (and various timers) of the engine.
   */
  public final void run() {
    long lastTime = System.nanoTime();
    double delta = 0;
    double ns = 1000000000.0 / 60.0;
    long timer = System.currentTimeMillis();
    int frames = 0;
    int updates = 0;
    System.out.println("Took " + ((System.currentTimeMillis() - startTimer) / 1000.0) + " seconds to load!");
    while (running) {
      long now = System.nanoTime();
      delta += (now - lastTime) / ns;
      lastTime = now;
      if (delta >= 1) {
        update();
        updates++;
        delta--;
      }
      render();
      frames++;
      if (System.currentTimeMillis() - timer > 1000) {
        timer += 1000;
        System.out.println(updates + "ups, " + frames + " fps");
        updates = 0;
        frames = 0;
      }
    }
  }

  /**
   * Returns the {@code Screen}'s pixel array.
   *
   * @return The array of pixels that get rendered onto the screen.
   */
  protected final int[] getPixels() {
    return screen.getPixels();
  }

  /**
   * Pushes the pixel array to the screen and swaps buffers. Use this at the <strong>end</strong> of your
   * {@code render()} method to show what you've rendered on the screen!
   */
  protected final void show() {
    screen.copy();
    display.drawImage(screen.getImage());
    display.drawBufferedObjects(screen.getBufferedObjects());
    display.show();
  }

  protected Screen getScreen() {
    return screen;
  }

  /**
   * Clears the pixel array (and thus the screen). This method will clear the screen to black; use the
   * {@link #clear(Color) clear(Color)} method to specify a custom color to clear to.
   */
  protected final void clear() {
    screen.clear();
  }

  /**
   * Clears the pixel array (and thus the screen) to the specified {@link Color}.
   *
   * @param col
   */
  protected final void clear(Color col) {
    screen.clear(col);
  }

  protected final void render(int x, int y, Renderable renderable) {
    renderable.render(x, y, screen);
  }

  /**
   * Renders a texture onto the screen.
   *
   * @param texture
   *            The {@link Texture} to render.
   * @param x
   *            The x-coordinate (in pixels) of where to start rendering the texture (top left corner).
   * @param y
   *            The y-coordinate (in pixels) of where to start rendering the texture (top left corner).
   */
  protected final void renderTexture(Texture texture, int x, int y) {
    screen.renderTexture(texture, x, y);
  }

  /**
   * Fills a rectangle of pixels onto the screen, at the specified position with the specified size and color.
   *
   * @param x
   *            The x-coordinate (in pixels) of the rectangle.
   * @param y
   *            The y-coordinate (in pixels) of the rectangle.
   * @param width
   *            The width of the rectangle.
   * @param height
   *            The height of the rectangle.
   * @param color
   *            The {@link Color} of the rectangle.
   */
  protected final void fillRect(int x, int y, int width, int height, Color color) {
    screen.fillRect(x, y, width, height, color);
  }

  /**
   * Override this method to initialise the game.
   */
  protected abstract void init();

  /**
   * Override this method to update the game.
   */
  protected abstract void update();

  /**
   * Override this method to render the game.
   */
  protected abstract void render();

}
TOP

Related Classes of com.thecherno.cherno.engine.Cherno

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.