Skip to content

Commit

Permalink
Merge pull request #29 from fastjengine/examples
Browse files Browse the repository at this point in the history
Examples 1

Related to #20 

Adds the following example programs:
- `engineconfig`
- `keyboard`
- `logging`
- `polygon2d`
- `text2d`
- `model2d`
- `modelreadwrite`


## Bug Fixes
_In a list, briefly describe each bug you fixed. A link to the issue/pr where this bug is referenced is highly recommended._
- fixed issue with trying to close display without it being displayed
- fixed issue with `keyChecker` trying to start after shutting down
  • Loading branch information
lucasstarsz authored Jun 27, 2021
2 parents 784a0e6 + a214f1f commit 3e02e71
Show file tree
Hide file tree
Showing 14 changed files with 587 additions and 8 deletions.
7 changes: 2 additions & 5 deletions src/example/java/module-info.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
/**
* An example game made for <a href="https://github.com/lucasstarsz/FastJ" target="_blank">The FastJ Game
* Library</a>.
*/
/** Examples for <a href="https://github.com/lucasstarsz/FastJ" target="_blank">The FastJ Game Library</a>. */
module fastj.game {
requires fastj.library; // allows us to use fastj
requires fastj.library;
}
93 changes: 93 additions & 0 deletions src/example/java/tech/fastj/example/engineconfig/Main.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
package tech.fastj.example.engineconfig;

import tech.fastj.engine.FastJEngine;
import tech.fastj.engine.HWAccel;
import tech.fastj.math.Point;
import tech.fastj.math.Pointf;
import tech.fastj.graphics.Display;
import tech.fastj.graphics.game.Polygon2D;
import tech.fastj.graphics.util.DrawUtil;

import tech.fastj.systems.control.SimpleManager;

public class Main extends SimpleManager {
@Override
public void init(Display display) {
/* As a small aside, this is a small inclusion in order to show how configuring FastJ
* affects rendering.
* The code is not the primary focus of the example -- this is just to give a visual. */
Pointf[] squareMesh = DrawUtil.createBox(50f, 50f, 100f);
Polygon2D square = new Polygon2D(squareMesh);
drawableManager.addGameObject(square);
}

@Override
public void update(Display display) {
// Empty -- this example does not make use of this method.
}

public static void main(String[] args) {
FastJEngine.init("Hello, Configuration!", new Main());


/* FastJEngine Configuration */

/* When using the other examples or FastJ in general, you may have noticed that the game
* engine defaults to a 1280*720 window. This is part of FastJEngine's default
* configuration.
*
* With that said, let's get started with the first two types of configuration:
* 1. configureViewerResolution
* 2. configureInternalResolution
*
* Note 1: Both of these configurations require use of a Point. A Point is similar to that
* of a Pointf, but it only allows integer values.
* Note 2: Configurations should always be done after initializing the game engine.
*/


/* "FastJEngine#configureViewerResolution" configures the viewer resolution -- the size of
* the window that the player plays in.
* By default, this is configured to 720p -- 1280*720. Of course, you can change this to
* any set of values you would like, as long as both values are at least 1.
*
* For this example, I've set it to 640*480. Feel free to mess around with the numbers! */
FastJEngine.configureViewerResolution(new Point(640, 480));

/* "FastJEngine#configureInternalResolution" configures the internal resolution -- the size
* of the actual game canvas (where the game gets rendered).
* By default, this is also configured to 720p -- 1280*720. Like the viewer resolution,
* this can be set to any values that are at least 1.
*
* For this example, I've set this to 640*480. Feel free to mess around with the numbers! */
FastJEngine.configureInternalResolution(new Point(640, 480));


/* Now, we'll move onto configureHardwareAcceleration.
* By making use of java2d, FastJ supports a few hardware-accelerated graphics APIs:
* - OpenGL
* - Direct3D
*
* With that in mind, "FastJEngine#configureHardwareAcceleration" allows you to configure
* the type of hardware acceleration your game uses. This is set using the "HWAccel" enum.
*
* For this example, we're going to set the hardware acceleration to OpenGL. */
FastJEngine.configureHardwareAcceleration(HWAccel.OpenGL);


/* Lastly, FPS and UPS configuration.
*
* - FPS: Frames Per Second (how many times the game renders to the screen in a second)
* - UPS: Updates Per Second (how many times the game updates in a second)
*
* FPS can be configured with "FastJEngine#setTargetFPS".
* UPS can be configured with "FastJEngine#setTargetUPS".
*
* FPS defaults to the refresh rate of your default monitor -- check your monitor's specifications to determine
* what this value is. On the other hand, UPS defaults to 60. */
FastJEngine.setTargetFPS(60);
FastJEngine.setTargetUPS(30);

FastJEngine.run();
}
}
28 changes: 28 additions & 0 deletions src/example/java/tech/fastj/example/hellofastj/Main.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,41 @@ public class Main extends SimpleManager {

@Override
public void init(Display display) {
// Empty -- this example does not make use of this method.
}

@Override
public void update(Display display) {
// Empty -- this example does not make use of this method.
}

public static void main(String[] args) {
/* Hello, FastJ! */

/* Welcome, travelers. it seems you've wandered far enough off the beaten path to find this
* game engine. For that, I thank you for coming and I commend your efforts in finding us.
* My name is Andrew, and I'll be your guide through these examples. It's a pleasure to
* meet you!
*
* Introductions aside, FastJ's very simple to start off with. This entire source file is
* all you'd need in order to create an empty screen for FastJ.
*
* "FastJEngine#init" initializes the game engine with a name (String) and a logic manager.
* The name is fairly self-explanatory, and the logic manager is the class used to handle
* all of the things you'd expect a game application to have:
*
* - Loading the Game Logic (handled in the "init" method)
* - Receiving/Processing Input
* - Updating the Game (handled in the "update" method)
* - Rendering the Game
* - Resetting the Game
*
* Note: This example has the Main class (this source file) also be a SimpleManager,
* which is a type of LogicManager where you handle all the game loading and updating in
* the manager itself.
* As such, it's very easy to add an application entrypoint (the main method) here,
* allowing us to contain an entire game in one source file. */

FastJEngine.init("Hello, FastJ!", new Main());
FastJEngine.run();
}
Expand Down
133 changes: 133 additions & 0 deletions src/example/java/tech/fastj/example/keyboard/Main.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
package tech.fastj.example.keyboard;

import tech.fastj.engine.FastJEngine;
import tech.fastj.graphics.Display;

import tech.fastj.systems.control.SimpleManager;
import tech.fastj.systems.input.keyboard.Keyboard;
import tech.fastj.systems.input.keyboard.KeyboardActionListener;
import tech.fastj.systems.input.keyboard.Keys;

import java.awt.event.KeyEvent;

public class Main extends SimpleManager {

@Override
public void init(Display display) {
/* Keyboard */

/* Keyboard controls in FastJ can be achieved through a few different methods.
* - Creating a KeyboardActionListener to do actions when a key is pressed/released/etc
* - key listeners can be added to the manager at any time. With that said, most use cases would add the
* listener when the game is being loaded.
* - Polling the Keyboard class directly for key state
* - This tactic works best in methods called often -- such as the update method.
*
* For this example, we'll work with the KeyboardActionListener in the init method, and working with polling in
* the update method. */


/* KeyboardActionListener */

/* The KeyboardActionListener class is designed to set up actions depending on keyboard actions from the player.
* It has 4 main methods:
*
* - onKeyDown: this method is called when a key is held down.
* - onKeyRecentlyPressed: this method is called when a key is first pressed.
* - onKeyReleased: this method is called when a key is released.
* - onKeyTyped: this method is called when a key is typed -- first pressed or held down.
*
* To demonstrate each method, I've chosen to log whenever any of the methods is called. Run the program to see
* this in action. */

inputManager.addKeyboardActionListener(new KeyboardActionListener() {
@Override
public void onKeyDown() {
FastJEngine.log("Key(s) held down");
}

@Override
public void onKeyRecentlyPressed(KeyEvent keyEvent) {
FastJEngine.log("Key " + keyEvent.getKeyChar() + " pressed.");
}

@Override
public void onKeyReleased(KeyEvent keyEvent) {
FastJEngine.log("Key " + keyEvent.getKeyChar() + " released.");
}

@Override
public void onKeyTyped(KeyEvent keyEvent) {
FastJEngine.log("Key " + keyEvent.getKeyChar() + " typed.");
}
});
}

@Override
public void update(Display display) {
/* Polling Keyboard for key state */

/* The Keyboard class has a plethora of methods for checking a key's state.
*
* - Keyboard#isKeyDown: check whether a key is held down.
* - Keyboard#isKeyRecentlyPressed: check whether a key was recently pressed.
* - Keyboard#isKeyRecentlyReleased: check whether a key was recently released.
* - Keyboard#getLastKeyPressed: get the string representation of the last key pressed.
*
* To demonstrate each of these, I've added if statements to check if the key "W" is held, pressed, released, or is the last key pressed.
* */

// Furthermore, the Keys class represents the possible keys on the keyboard.
// Make sure to use it when checking for a key's state.
if (Keyboard.isKeyDown(Keys.W)) {
FastJEngine.log("W key is held down");
}

if (Keyboard.isKeyRecentlyPressed(Keys.W)) {
FastJEngine.log("W key was pressed");
}

if (Keyboard.isKeyRecentlyReleased(Keys.W)) {
FastJEngine.log("W key was released");
}

if ("W".equals(Keyboard.getLastKeyPressed())) {
FastJEngine.log("Last key pressed was W");
}

/* Checking keys on the keyboard multiple times */

/* This system is fine, but is not by itself able to handle keys that exist on the keyboard multiple times, such
* as Shift or Control.
* To account for this, there are versions of the first three methods that take a second parameter that states
* where the key is on the keyboard.
* This extra parameter is the KeyLocation class, and it contains a few options:
*
* - KeyLocation#Standard: keys that only appear on the keyboard once.
* - KeyLocation#Left: keys that appear twice -- specifying the key on the left side of the keyboard.
* - KeyLocation#Right: keys that appear twice -- specifying the key on the right side of the keyboard.
* - KeyLocation#Numpad: keys that appear on the numpad.
*
* To demonstrate this, I've added checks for when:
* - the left shift key is held down
* - the right control key is recently pressed
* - the numpad 4 key is recently released */

if (Keyboard.isKeyDown(Keys.Shift, Keyboard.KeyLocation.Left)) {
FastJEngine.log("Left Shift key is held down");
}

if (Keyboard.isKeyRecentlyPressed(Keys.Shift, Keyboard.KeyLocation.Right)) {
FastJEngine.log("Right Control key was pressed");
}

if (Keyboard.isKeyRecentlyReleased(Keys.Numpad4, Keyboard.KeyLocation.Numpad)) {
FastJEngine.log("Numpad 4 key was released");
}
}

public static void main(String[] args) {
FastJEngine.init("Hello, Keyboard Controls!", new Main());
FastJEngine.run();
}
}
34 changes: 34 additions & 0 deletions src/example/java/tech/fastj/example/logging/Main.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package tech.fastj.example.logging;

import tech.fastj.engine.FastJEngine;

public class Main {
public static void main(String[] args) {
/* FastJ Logging */

/* FastJ's logging solution is not very robust just yet. It currently makes use of the
* standard out/err streams (System.out and System.err). While not performant, it is currently sufficient for the engine's usage. */

/* First up, "FastJEngine#log". This method prints out in this style:
* "INFO: <your message here, without the braces>" */

FastJEngine.log("Hello! This is an informational logging statement.");

/* Next, "FastJEngine#warning". This method prints out in this style:
* "WARNING: <your message here, without the braces>" */

FastJEngine.warning("Be careful now! This is a warning.");

/* Lastly, "FastJEngine#error". This method is special, because it not only prints out the
* error -- it crashes the engine with an exception as well.
* This method prints in this style:
* "ERROR: <your message here, without the braces>"
* "Exception <the rest of the stack trace would be here>" */

/* Under normal circumstances, this method also requires that you add an exception -- the
* exception that caused a need to call "FastJEngine#error".
* For the sake of demonstration, we will create an exception ourselves. */
IllegalStateException exampleException = new IllegalStateException("This is an example exception.");
FastJEngine.error("Oh dear, looks like something went wrong. This is an error message.", exampleException);
}
}
53 changes: 53 additions & 0 deletions src/example/java/tech/fastj/example/model2d/Main.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package tech.fastj.example.model2d;

import tech.fastj.engine.FastJEngine;
import tech.fastj.math.Pointf;
import tech.fastj.graphics.Display;
import tech.fastj.graphics.game.Model2D;
import tech.fastj.graphics.game.Polygon2D;
import tech.fastj.graphics.util.DrawUtil;

import tech.fastj.systems.control.SimpleManager;

public class Main extends SimpleManager {

@Override
public void init(Display display) {
/* Model2D */

/* WARNING: If you're not familiar with FastJ, you'll need to read through the
* "polygon2d" example first.
*
* In order to create a Model2D, you'll need an array of Polygon2D objects.
* A Model2D is essentially a collection of Polygon2D objects, and it treats those objects
* as one game object. */

// We'll create two squares -- just like the ones from the "hellopolygon2d" example.
Pointf[] smallSquareMesh1 = DrawUtil.createBox(0f, 0f, 50f);
Polygon2D smallSquare1 = new Polygon2D(smallSquareMesh1);

// To visualize the two squares as different, we'll change the second one up a bit.
Pointf[] smallSquareMesh2 = DrawUtil.createBox(50f, 50f, 25f);
Polygon2D smallSquare2 = new Polygon2D(smallSquareMesh2);

// In order to create our Model2D, we need those squares in an array.
Polygon2D[] smallSquaresArray = {smallSquare1, smallSquare2};

// Now, we can create our Model2D object.
Model2D smallSquares = new Model2D(smallSquaresArray);

/* Super simple! Now, this alone does not cause the model to render to the screen. In order
* for it to be rendered, you need to add it as a game object to the drawable manager. */
drawableManager.addGameObject(smallSquares);
}

@Override
public void update(Display display) {
// Empty -- this example does not make use of this method.
}

public static void main(String[] args) {
FastJEngine.init("Hello, Model2D!", new Main());
FastJEngine.run();
}
}
Loading

0 comments on commit 3e02e71

Please sign in to comment.