A UE-style (Unreal Engine-inspired) game engine built on top of the JavaFX framework, providing a robust foundation for 2D game development in Java.
FXGE (JavaFX Game Engine) is a comprehensive game engine framework that brings Unreal Engine's actor-component architecture to JavaFX. It provides a modular and extensible system for building interactive 2D games with a focus on performance, maintainability, and ease of use.
- Actor-Component Architecture: Inspired by Unreal Engine, the engine uses actors as game objects and components to define their behavior and appearance
- Level Management: Organize game content into levels with support for multiple game worlds
- Event System: Keyboard and mouse event handling with broadcaster-subscriber pattern
- Transform System: 2D transformation support with position and rotation management
- Collision Detection: Built-in collision interface for detecting interactions between objects
- Scene Management: Seamless scene navigation and management using JavaFX
- Performance Monitoring: Built-in FPS counter for performance tracking
- Asset Management: Image registry for efficient resource management
The main game loop controller that manages the lifecycle of the game. It handles:
- Game loop timing with delta time calculation
- Level loading and initialization
- Input event registration and distribution
- FPS monitoring
GameObject (GameObject.java)
- Abstract base class for all objects in the game world
- Manages scene components and their lifecycle
- Implements keyboard and mouse event subscription
Actor (Actor.java)
- Extends
GameObjectfor dynamic, interactive objects - Supports 2D transformation (position and rotation)
- Implements collision detection interface
- Designed for game entities that update and move
Level (Level.java)
- Extends
GameObjectand acts as a container for actors - Manages actor collections and lifecycle
- Broadcasts keyboard and mouse events to subscribers
- Provides the JavaFX SubScene for rendering
Spectator (Spectator.java)
- Non-interactive observer objects in the game world
- Useful for static visual elements or environmental objects
SceneComponent (SceneComponent.java)
- Abstract base class for visual and behavioral components
- Wraps JavaFX Node objects for flexibility
- Supports parent binding and transform propagation
- Can be attached to game objects to extend their functionality
Attachable (Attachable.java)
- Interface defining attachment behavior to JavaFX scenes
KeyboardEventSubscriber/Broadcaster
- Pattern for handling keyboard input
- Objects can subscribe to keyboard events
- Events are broadcasted throughout the level
MouseEventSubscriber/Broadcaster
- Pattern for handling mouse input
- Supports mouse movement, drag, press, release, and enter events
- Integrates with JavaFX mouse event system
- Transform2D: Manages 2D position and rotation for actors
- Rotation: Handles rotational mathematics and transformations
- RotationMatrix: Matrix operations for rotation calculations
- MathUtils: Common mathematical utilities
- Collidable: Interface for collision detection between objects
- AnimationUtils: Helper functions for animations
- FpsCounter: Monitors and tracks frame rate
- ImageRegistry: Centralized asset management for images
SceneNavigator (SceneNavigator.java)
- Manages scene transitions and navigation
- Maintains a history stack for back navigation
- Supports multiple named scenes for UI management
ControllerBase (ControllerBase.java)
- Base class for FXML scene controllers
GameplayModel (GameplayModel.java)
- Bridges the engine and UI systems
- Provides a model for gameplay interactions
- Java 21 or higher
- JavaFX 17.0.6
- Gradle
./gradlew buildOn Windows:
gradlew.bat buildTo start the demo application:
./gradlew runOn Windows:
gradlew.bat runThe application will launch with a main menu and demo gameplay level. Use the menu to navigate between different scenes and play the demo level.
Here's a basic structure for creating a game using FXGE:
// Create a level
public class MyLevel extends Level {
private int levelWidth;
private int levelHeight;
public MyLevel() {
super(levelName, preferredWidth, preferredHeight);
this.levelWidth = preferredWidth;
this.levelHeight = preferredHeight;
}
@Override
protected void beginPlay() throws Exception {
// Initialize game objects
ExampleCharacter player = new ExampleCharacter(this);
super.beginPlay();
}
}
// Create a custom actor
public class ExampleCharacter extends Actor {
public ExampleCharacter(Level level) {
super(level);
}
@Override
protected void tickActor(double deltaTime) {
// Update actor logic
}
@Override
public void onKeyPressed(KeyEvent event) {
// Handle keyboard input
super.onKeyPressed(keyEvent);
switch (keyEvent.getCode()){
case D -> {
isDPressed = true;
if (isAPressed){
this.currentVelocity = new Point2D(0, currentVelocity.getY());
}
else{
this.currentVelocity = currentVelocity.add(new Point2D(1, 0));
}
}
case A -> {
isAPressed = true;
if (isDPressed){
this.currentVelocity = new Point2D(0, currentVelocity.getY());
}
else{
this.currentVelocity = currentVelocity.add(new Point2D(-1, 0));
}
}
}
}
}src/main/java/com/e613/fxge/engine/
├── Engine.java # Main game loop controller
├── component/ # Scene components system
│ ├── SceneComponent.java
│ └── Attachable.java
├── gameobject/ # Core game objects
│ ├── GameObject.java
│ ├── Actor.java
│ ├── Level.java
│ └── Spectator.java
├── controller/ # Game control layer
│ ├── ControllerBase.java
│ └── GameplayModel.java
├── event/ # Event system
│ ├── KeyboardEventSubscriber.java
│ ├── KeyboardEventBroadcaster.java
│ ├── MouseEventSubscriber.java
│ └── MouseEventBroadcaster.java
├── ui/ # UI management
│ └── SceneNavigator.java
└── util/ # Utility classes
├── Transform2D.java
├── Rotation.java
├── RotationMatrix.java
├── MathUtils.java
├── Collidable.java
├── AnimationUtils.java
├── FpsCounter.java
└── ImageRegistry.java
The engine uses JavaFX's AnimationTimer for the main game loop. It calculates delta time and propagates it to the current level, which distributes it to all actors for physics updates.
Similar to Unreal Engine, actors are containers for components. Each actor has a transform (position and rotation) and can contain multiple scene components that define its visual representation and behavior.
Input events flow from JavaFX through the engine to the current level, which broadcasts them to subscribed actors. This decoupled architecture makes it easy to manage complex input scenarios.
The ImageRegistry provides centralized management of game assets, ensuring efficient resource usage and preventing duplicate loading.
Actors implementing the Collidable interface can participate in collision detection. The framework supports checking collisions between actors at runtime.
- Java Version: 21+
- JavaFX Version: 17.0.6
- Build System: Gradle
This project is shared as a reference implementation for studying JavaFX along with game designing. It is provided as-is for learning and experimentation.
PRs/issues are highly welcomed, feel free to contribute! For general questions regarding the engine usage, you may refer to the documents, or reach out via GitHub Discussions or open an issue.