diff --git a/.gitignore b/.gitignore index 54ac2f5..2096da3 100644 --- a/.gitignore +++ b/.gitignore @@ -2,9 +2,10 @@ .gradle/ gradle-app.setting /build/ +/funkin/build/ +/flixelgdx/build/ +/polyverse/build/ /android/build/ -/core/build/ -/lwjgl2/build/ /lwjgl3/build/ /html/build/ /teavm/build/ diff --git a/COMPILING.md b/COMPILING.md index 7c5f7be..465f4d7 100644 --- a/COMPILING.md +++ b/COMPILING.md @@ -1,7 +1,7 @@ # How to Compile FNF:JE > [!TIP] -> If you want some helpful info about the Gradle tasks (or the framework FNF:JE uses), consider taking a look at [LIBGDX.md](LIBGDX.md)! +> If you want some helpful info about the Gradle tasks (or the framework FNF:JE uses), consider taking a look at [LIBGDX.md](PROJECT.md)! There are two main ways you can download and compile the game's code: with GitHub Desktop or the terminal. @@ -12,13 +12,13 @@ In this guide, we'll use the GitHub Desktop method, since it the most user-frien - A [Java Development Kit (JDK)](https://www.oracle.com/java/technologies/javase/jdk17-archive-downloads.html) to compile the game's code. - An integrated development environment. - We recommend either one of the options listed below: - - [Intellij IDEA](https://www.jetbrains.com/idea/download/) + - [IntelliJ IDEA](https://www.jetbrains.com/idea/download/) - [Eclipse](https://www.eclipse.org/downloads/) - [VS Code](https://code.visualstudio.com/) - Some basic knowledge of programming (especially Gradle) and how to navigate an IDE. > [!TIP] -> Although every IDE listed is great for Java, we STRONGLY recommend Intellij IDEA, due to how beginner friendly and integrated it is with FNF:JE! +> Although every IDE listed is great for Java, we STRONGLY recommend IntelliJ IDEA, due to how beginner-friendly and integrated it is with FNF:JE! # Step-by-Step Guide diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 8df22cc..a67cc45 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -28,7 +28,7 @@ hard to understand in general, then they won't be any use. Even too many comments are unnecessary, since your code should be self documented and easily readable. -***Formatting MUST match the [Google Java Style Guide](https://google.github.io/styleguide/javaguide.html).*** +***Formatting MUST match the configurations set in the [editor config file](.editorconfig), with the formatting based on the [Google Java Style Guide](https://google.github.io/styleguide/javaguide.html).*** ### Example of GOOD Comments (With Good Formatting) diff --git a/LIBGDX.md b/PROJECT.md similarity index 80% rename from LIBGDX.md rename to PROJECT.md index d0e041a..6681816 100644 --- a/LIBGDX.md +++ b/PROJECT.md @@ -4,8 +4,10 @@ FNF:JE is designed to run on multiple different platforms. Below are the different modules that hold the code for each one. -- `core`: Main module with the game's logic shared by all platforms. This is where you want to write your source code! -- `lwjgl3`: Primary desktop platform using [LWJGL3](https://www.lwjgl.org/). This is what launches the desktop versions of the game! +- `funkin`: The core part of the game's code. This is where all the game logic is implemented. +- `flixelgdx`: Custom framework that bridges [HaxeFlixel](https://haxeflixel.com/) and is based on libGDX. This is where the HaxeFlixel-like API is implemented. +- `polyverse`: Custom library for adding modding capabilities to the game. +- `lwjgl3`: Primary desktop platform using [LWJGL3](https://www.lwjgl.org/). This is what launches the desktop versions of the game! - `android`: Android mobile platform. This requires the Android SDK, which can be downloaded and configured simply by running the universal [setup file](setup/android_setup.sh)! > [!IMPORTANT] @@ -32,6 +34,7 @@ The Gradle wrapper was included, so you can run Gradle tasks using `gradlew.bat` - `clean`: removes `build` folders, which store compiled classes and built archives. - `eclipse`: generates Eclipse project data. - `idea`: generates IntelliJ project data. +- `funkin:exportModSDK`: Exports the game's API and its dependencies as `.jar` files to the assets folder. - `lwjgl3:jar`: builds the game's runnable jar, which can be found at `lwjgl3/build/libs`. - `lwjgl3:run`: starts the desktop version of the game. - `test`: runs unit tests (if any). diff --git a/README.md b/README.md index f72641c..fb8eac7 100644 --- a/README.md +++ b/README.md @@ -2,4 +2,21 @@ Welcome to the official GitHub repository for the Java edition of Friday Night Funkin'! -### Please note that this unofficial version of the game is NOT completed! This has a long way to go, but with YOUR help, we can make this project come alive! <3 +> [!NOTICE] +> This is a fan-made project and is not affiliated with the original developers. You can play the original game [here](https://ninja-muffin24.itch.io/funkin). + +## Please note that this unofficial version of the game is NOT completed! This has a long way to go, but with YOUR help, we can make this project come alive! <3 + +# About the Project +Friday Night Funkin': Java Edition is an open-source project that aims to recreate the popular rhythm game [Friday Night Funkin'](https://github.com/FunkinCrew/Funkin) using Java. +It is built using its own custom framework based on libGDX, called FlixelGDX: a Java port of the HaxeFlixel framework used in the original game. + +The project is designed to have practically endless modding capabilities, empowering developers to use features for mods +which otherwise would be impossible to accomplish in the original game and HaxeFlixel. + +# Project Navigation + +- [Contributing](CONTRIBUTING.md) +- [Project Structure and Gradle Tasks](PROJECT.md) +- [Compiling the Game](COMPILING.md) +- [License](LICENSE.md) diff --git a/android/build.gradle b/android/build.gradle index f1e7e80..76f8983 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -63,7 +63,7 @@ configurations { natives } dependencies { coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.1.5' implementation "com.badlogicgames.gdx:gdx-backend-android:$gdxVersion" - implementation project(':core') + implementation project(':funkin') api "games.rednblack.miniaudio:gdx-miniaudio-platform:$miniaudioVersion:natives-armeabi-v7a" api "games.rednblack.miniaudio:gdx-miniaudio-platform:$miniaudioVersion:natives-arm64-v8a" diff --git a/android/src/main/java/me/stringdotjar/funkin/android/AndroidLauncher.java b/android/src/main/java/me/stringdotjar/funkin/android/AndroidLauncher.java index 08aa5d8..999621a 100644 --- a/android/src/main/java/me/stringdotjar/funkin/android/AndroidLauncher.java +++ b/android/src/main/java/me/stringdotjar/funkin/android/AndroidLauncher.java @@ -4,7 +4,7 @@ import com.badlogic.gdx.backends.android.AndroidApplication; import com.badlogic.gdx.backends.android.AndroidApplicationConfiguration; import me.stringdotjar.funkin.FunkinGame; -import me.stringdotjar.funkin.init.InitScreen; +import me.stringdotjar.funkin.InitScreen; import me.stringdotjar.funkin.util.FunkinConstants; /** Launches the Android application. */ diff --git a/core/src/main/java/me/stringdotjar/flixelgdx/graphics/sprite/FlixelObject.java b/core/src/main/java/me/stringdotjar/flixelgdx/graphics/sprite/FlixelObject.java deleted file mode 100644 index 9d576f9..0000000 --- a/core/src/main/java/me/stringdotjar/flixelgdx/graphics/sprite/FlixelObject.java +++ /dev/null @@ -1,9 +0,0 @@ -package me.stringdotjar.flixelgdx.graphics.sprite; - -import me.stringdotjar.flixelgdx.graphics.screen.FlixelScreen; - -/** - * An interface which allows any class that implements it to be added to a {@link - * FlixelScreen}. - */ -public interface FlixelObject {} diff --git a/core/src/main/java/me/stringdotjar/polyverse/script/type/SystemScript.java b/core/src/main/java/me/stringdotjar/polyverse/script/type/SystemScript.java deleted file mode 100644 index acc8b98..0000000 --- a/core/src/main/java/me/stringdotjar/polyverse/script/type/SystemScript.java +++ /dev/null @@ -1,8 +0,0 @@ -package me.stringdotjar.polyverse.script.type; - -public abstract class SystemScript extends Script { - - public SystemScript(String id) { - super(id); - } -} diff --git a/flixelgdx/build.gradle b/flixelgdx/build.gradle new file mode 100644 index 0000000..474d702 --- /dev/null +++ b/flixelgdx/build.gradle @@ -0,0 +1,17 @@ +[compileJava, compileTestJava]*.options*.encoding = 'UTF-8' +eclipse.project.name = appName + '-flixelgdx' + +dependencies { + api "com.badlogicgames.gdx:gdx-freetype:$gdxVersion" + api "com.badlogicgames.gdx:gdx:$gdxVersion" + api "com.github.tommyettinger:anim8-gdx:$anim8Version" + api "com.github.tommyettinger:libgdx-utils:$utilsVersion" + api "io.github.libktx:ktx-freetype:$ktxVersion" + api "games.rednblack.miniaudio:miniaudio:$miniaudioVersion" + + implementation "org.jetbrains:annotations:26.0.2-1" + + if (enableGraalNative == 'true') { + implementation "io.github.berstanio:gdx-svmhelper-annotations:$graalHelperVersion" + } +} diff --git a/core/src/main/java/me/stringdotjar/flixelgdx/Flixel.java b/flixelgdx/src/main/java/me/stringdotjar/flixelgdx/Flixel.java similarity index 98% rename from core/src/main/java/me/stringdotjar/flixelgdx/Flixel.java rename to flixelgdx/src/main/java/me/stringdotjar/flixelgdx/Flixel.java index 5a3d895..615053f 100644 --- a/core/src/main/java/me/stringdotjar/flixelgdx/Flixel.java +++ b/flixelgdx/src/main/java/me/stringdotjar/flixelgdx/Flixel.java @@ -40,15 +40,12 @@ public final class Flixel { private static MAGroup soundsGroup; /** The sound for playing music throughout the game. */ - public static MASound music; + private static MASound music; /** The current master volume that is set. */ private static float masterVolume = 1; - /** - * The static instance used to access the core elements of the game. This includes the main loop, - * setting the current screen, and more. - */ + /** The static instance used to access the core elements of the game. */ private static FlixelGame game; /** Has the global manager been initialized yet? */ @@ -323,7 +320,7 @@ public static void playMusic(String path, float volume, boolean looping, boolean * @param volume The new master volume to set. */ public static void setMasterVolume(float volume) { - engine.setMasterVolume(volume); + engine.setMasterVolume(!(volume > 1.0) ? volume : 1.0f); masterVolume = volume; } @@ -458,7 +455,7 @@ private static void outputLog(String tag, Object message, FlixelLogLevel level) false, underline); String formattedTag = colorText("[" + level + "] [" + tag + "] [" + file + "] [" + method + "] ", color, true, false, underline); - String formattedMessage = colorText(message.toString(), color, false, true, underline); + String formattedMessage = colorText((message != null) ? message.toString() : null, color, false, true, underline); System.out.println(timeAndDate + formattedTag + formattedMessage); } diff --git a/core/src/main/java/me/stringdotjar/flixelgdx/FlixelGame.java b/flixelgdx/src/main/java/me/stringdotjar/flixelgdx/FlixelGame.java similarity index 90% rename from core/src/main/java/me/stringdotjar/flixelgdx/FlixelGame.java rename to flixelgdx/src/main/java/me/stringdotjar/flixelgdx/FlixelGame.java index e3d526b..36b8078 100644 --- a/core/src/main/java/me/stringdotjar/flixelgdx/FlixelGame.java +++ b/flixelgdx/src/main/java/me/stringdotjar/flixelgdx/FlixelGame.java @@ -15,13 +15,9 @@ import com.badlogic.gdx.utils.viewport.FitViewport; import me.stringdotjar.flixelgdx.graphics.screen.FlixelScreen; import me.stringdotjar.flixelgdx.graphics.sprite.FlixelObject; -import me.stringdotjar.flixelgdx.graphics.sprite.FlixelSprite; import me.stringdotjar.flixelgdx.tween.FlixelTween; import me.stringdotjar.flixelgdx.util.FlixelConstants; import me.stringdotjar.flixelgdx.util.FlixelRuntimeUtil; -import me.stringdotjar.funkin.util.FunkinConstants; -import me.stringdotjar.polyverse.Polyverse; -import me.stringdotjar.polyverse.script.type.Script; import static me.stringdotjar.flixelgdx.signal.FlixelSignalData.RenderSignalData; @@ -37,11 +33,14 @@ public abstract class FlixelGame implements ApplicationListener { protected String title; /** The size of the game's starting window position and its viewport. */ - protected Vector2 size; + protected Vector2 windowSize; /** The entry point screen the game starts in (which becomes null after the game is done setting up!). */ protected FlixelScreen initialScreen; + /** Is the game's window currently focused? */ + protected boolean isFocused = true; + /** Is the game's window currently minimized? */ protected boolean isMinimized = false; @@ -71,7 +70,7 @@ public abstract class FlixelGame implements ApplicationListener { */ public FlixelGame(String title, int width, int height, FlixelScreen initialScreen) { this.title = title; - this.size = new Vector2(width, height); + this.windowSize = new Vector2(width, height); this.initialScreen = initialScreen; } @@ -80,11 +79,11 @@ public void create() { configureCrashHandler(); // This should ALWAYS be called first no matter what! batch = new SpriteBatch(); - viewport = new FitViewport(size.x, size.y); + viewport = new FitViewport(windowSize.x, windowSize.y); viewport.apply(); camera = new OrthographicCamera(); - camera.setToOrtho(false, size.x, size.y); + camera.setToOrtho(false, windowSize.x, windowSize.y); stage = new Stage(viewport, batch); @@ -127,10 +126,11 @@ public void render() { screen.render(delta); var members = screen.members.begin(); for (FlixelObject object : members) { - if (object instanceof FlixelSprite sprite) { - sprite.update(delta); - sprite.draw(batch); + if (object == null) { + continue; } + object.update(delta); + object.draw(batch); } screen.members.end(); } @@ -152,7 +152,7 @@ public void resume() {} /** Called when the user regains focus on the game's window. */ public void onWindowFocused() { - Flixel.setMasterVolume(1); + isFocused = true; Flixel.Signals.windowFocused.dispatch(); Flixel.info("Game window has regained focus."); } @@ -162,7 +162,7 @@ public void onWindowUnfocused() { if (isMinimized) { return; } - Flixel.setMasterVolume(0.008f); + isFocused = false; Flixel.Signals.windowUnfocused.dispatch(); Flixel.info("Game window has lost focus."); } @@ -178,7 +178,7 @@ public void onWindowMinimized(boolean iconified) { if (!isMinimized) { return; } - Flixel.setMasterVolume(0); + isFocused = false; Flixel.Signals.windowMinimized.dispatch(); Flixel.info("Game window has been minimized."); } @@ -187,7 +187,7 @@ public void onWindowMinimized(boolean iconified) { public void toggleFullscreen() { boolean isFullscreen = Gdx.graphics.isFullscreen(); if (isFullscreen) { - Gdx.graphics.setWindowedMode(FunkinConstants.WINDOW_WIDTH, FunkinConstants.WINDOW_HEIGHT); + Gdx.graphics.setWindowedMode((int) windowSize.x, (int) windowSize.y); Flixel.info("Exiting fullscreen mode."); } else { Gdx.graphics.setFullscreenMode(Gdx.graphics.getDisplayMode()); @@ -216,7 +216,6 @@ public void dispose() { Flixel.getAudioEngine().dispose(); Flixel.info("Disposing and shutting down scripts..."); - Polyverse.forAllScripts(Script::onDispose); Flixel.Signals.postGameClose.dispatch(); } @@ -225,8 +224,12 @@ public String getTitle() { return title; } - public int[] getWindowSize() { - return new int[]{(int) size.x, (int) size.y}; + public Vector2 getWindowSize() { + return windowSize; + } + + public boolean isFocused() { + return isFocused; } public Stage getStage() { diff --git a/core/src/main/java/me/stringdotjar/flixelgdx/backend/FlixelPaths.java b/flixelgdx/src/main/java/me/stringdotjar/flixelgdx/backend/FlixelPaths.java similarity index 100% rename from core/src/main/java/me/stringdotjar/flixelgdx/backend/FlixelPaths.java rename to flixelgdx/src/main/java/me/stringdotjar/flixelgdx/backend/FlixelPaths.java diff --git a/core/src/main/java/me/stringdotjar/flixelgdx/graphics/screen/FlixelScreen.java b/flixelgdx/src/main/java/me/stringdotjar/flixelgdx/graphics/screen/FlixelScreen.java similarity index 100% rename from core/src/main/java/me/stringdotjar/flixelgdx/graphics/screen/FlixelScreen.java rename to flixelgdx/src/main/java/me/stringdotjar/flixelgdx/graphics/screen/FlixelScreen.java diff --git a/flixelgdx/src/main/java/me/stringdotjar/flixelgdx/graphics/sprite/FlixelObject.java b/flixelgdx/src/main/java/me/stringdotjar/flixelgdx/graphics/sprite/FlixelObject.java new file mode 100644 index 0000000..6ebd5c2 --- /dev/null +++ b/flixelgdx/src/main/java/me/stringdotjar/flixelgdx/graphics/sprite/FlixelObject.java @@ -0,0 +1,10 @@ +package me.stringdotjar.flixelgdx.graphics.sprite; + +import com.badlogic.gdx.graphics.g2d.Batch; +import me.stringdotjar.flixelgdx.graphics.screen.FlixelScreen; + +/** An interface which allows any class that implements it to be added to a {@link FlixelScreen}. */ +public interface FlixelObject { + void update(float delta); + void draw(Batch batch); +} diff --git a/core/src/main/java/me/stringdotjar/flixelgdx/graphics/sprite/FlixelSprite.java b/flixelgdx/src/main/java/me/stringdotjar/flixelgdx/graphics/sprite/FlixelSprite.java similarity index 95% rename from core/src/main/java/me/stringdotjar/flixelgdx/graphics/sprite/FlixelSprite.java rename to flixelgdx/src/main/java/me/stringdotjar/flixelgdx/graphics/sprite/FlixelSprite.java index ea71acb..ca82924 100644 --- a/core/src/main/java/me/stringdotjar/flixelgdx/graphics/sprite/FlixelSprite.java +++ b/flixelgdx/src/main/java/me/stringdotjar/flixelgdx/graphics/sprite/FlixelSprite.java @@ -5,6 +5,7 @@ import com.badlogic.gdx.graphics.g2d.Animation; import com.badlogic.gdx.graphics.g2d.Batch; import com.badlogic.gdx.graphics.g2d.Sprite; +import com.badlogic.gdx.graphics.g2d.SpriteBatch; import com.badlogic.gdx.graphics.g2d.TextureAtlas; import com.badlogic.gdx.graphics.g2d.TextureRegion; import com.badlogic.gdx.math.Rectangle; @@ -62,11 +63,11 @@ public FlixelSprite() { * * @param delta The amount of time that has passed since the last frame update. */ + @Override public void update(float delta) { if (animations.containsKey(currentAnim)) { stateTime += delta; - currentFrame = - (TextureAtlas.AtlasRegion) animations.get(currentAnim).getKeyFrame(stateTime, looping); + currentFrame = (TextureAtlas.AtlasRegion) animations.get(currentAnim).getKeyFrame(stateTime, looping); setRegion(currentFrame); } } @@ -286,17 +287,14 @@ public void draw(Batch batch) { // Adjust drawing position by the Sparrow offsets float drawX = getX() + currentFrame.offsetX; - float drawY = - getY() - + (currentFrame.originalHeight - currentFrame.getRegionHeight() - currentFrame.offsetY); + float drawY = getY() + (currentFrame.originalHeight - currentFrame.getRegionHeight() - currentFrame.offsetY); batch.draw( currentFrame, drawX, drawY, originX - currentFrame.offsetX, - originY - - (currentFrame.originalHeight - currentFrame.getRegionHeight() - currentFrame.offsetY), + originY - (currentFrame.originalHeight - currentFrame.getRegionHeight() - currentFrame.offsetY), currentFrame.getRegionWidth(), currentFrame.getRegionHeight(), getScaleX(), @@ -335,6 +333,14 @@ public void reset() { frames = null; } + public void changeX(float x) { + setX(getX() + x); + } + + public void changeY(float y) { + setY(getY() + y); + } + public Map> getAnimations() { return animations; } diff --git a/core/src/main/java/me/stringdotjar/flixelgdx/graphics/text/FlixelText.java b/flixelgdx/src/main/java/me/stringdotjar/flixelgdx/graphics/text/FlixelText.java similarity index 100% rename from core/src/main/java/me/stringdotjar/flixelgdx/graphics/text/FlixelText.java rename to flixelgdx/src/main/java/me/stringdotjar/flixelgdx/graphics/text/FlixelText.java diff --git a/core/src/main/java/me/stringdotjar/flixelgdx/signal/FlixelSignal.java b/flixelgdx/src/main/java/me/stringdotjar/flixelgdx/signal/FlixelSignal.java similarity index 100% rename from core/src/main/java/me/stringdotjar/flixelgdx/signal/FlixelSignal.java rename to flixelgdx/src/main/java/me/stringdotjar/flixelgdx/signal/FlixelSignal.java diff --git a/core/src/main/java/me/stringdotjar/flixelgdx/signal/FlixelSignalData.java b/flixelgdx/src/main/java/me/stringdotjar/flixelgdx/signal/FlixelSignalData.java similarity index 100% rename from core/src/main/java/me/stringdotjar/flixelgdx/signal/FlixelSignalData.java rename to flixelgdx/src/main/java/me/stringdotjar/flixelgdx/signal/FlixelSignalData.java diff --git a/core/src/main/java/me/stringdotjar/flixelgdx/tween/FlixelEase.java b/flixelgdx/src/main/java/me/stringdotjar/flixelgdx/tween/FlixelEase.java similarity index 100% rename from core/src/main/java/me/stringdotjar/flixelgdx/tween/FlixelEase.java rename to flixelgdx/src/main/java/me/stringdotjar/flixelgdx/tween/FlixelEase.java diff --git a/core/src/main/java/me/stringdotjar/flixelgdx/tween/FlixelTween.java b/flixelgdx/src/main/java/me/stringdotjar/flixelgdx/tween/FlixelTween.java similarity index 51% rename from core/src/main/java/me/stringdotjar/flixelgdx/tween/FlixelTween.java rename to flixelgdx/src/main/java/me/stringdotjar/flixelgdx/tween/FlixelTween.java index 3c6652e..36e0430 100644 --- a/core/src/main/java/me/stringdotjar/flixelgdx/tween/FlixelTween.java +++ b/flixelgdx/src/main/java/me/stringdotjar/flixelgdx/tween/FlixelTween.java @@ -1,32 +1,25 @@ package me.stringdotjar.flixelgdx.tween; import com.badlogic.gdx.utils.Pool; -import me.stringdotjar.flixelgdx.Flixel; import me.stringdotjar.flixelgdx.tween.settings.FlixelTweenSettings; -import me.stringdotjar.flixelgdx.util.FlixelConstants; -import me.stringdotjar.flixelgdx.util.FlixelReflectUtil; +import me.stringdotjar.flixelgdx.tween.type.FlixelNumTween; +import me.stringdotjar.flixelgdx.tween.type.FlixelVarTween; import org.jetbrains.annotations.NotNull; -import java.lang.reflect.Field; -import java.util.Arrays; -import java.util.HashMap; -import java.util.Map; -import java.util.Set; -import java.util.stream.Collectors; - /** - * Core class for creating new tweens to add nice and smooth animations to visual objects. + * Core class for creating new tweens to add nice and smooth animations. + * + *

Please note that while this isn't an abstract class, it is advised to NOT create instances + * of this class, since it does not implement the actual tweening logic. Instead, you should use one of + * its subclasses, such as {@link FlixelVarTween}, or create your own subclass and add your own functionality. * - *

Note that this doesn't have to be used on sprites, it can be used on just about anything! + *

The only reason this class is not abstract is to allow pooling of generic tweens when needed to save memory. */ public class FlixelTween implements Pool.Poolable { /** The global tween manager for the entire game. */ protected static FlixelTweenManager globalManager = new FlixelTweenManager(); - /** The object to tween. */ - protected Object object; - /** The settings used for how the tween is handled and calculated (aka how it looks and animates). */ protected FlixelTweenSettings tweenSettings; @@ -36,9 +29,6 @@ public class FlixelTween implements Pool.Poolable { /** How far the tween is tweening itself. This is what's used to actually tween the object! */ protected float scale = 0.0f; - /** The update callback for {@code this} tween to change the objects values every update. */ - protected FlixelTween.FunkinTweenUpdateCallback updateCallback; - /** How many seconds has elapsed since {@code this} tween started. */ protected float secondsSinceStart = 0.0f; @@ -57,69 +47,63 @@ public class FlixelTween implements Pool.Poolable { /** Is {@code this} tween tweening backwards? */ protected boolean backward = false; - /** The initial values of the fields being tweened. */ - protected final Map initialValues = new HashMap<>(); - - /** - * Cache of the fields being tweened for faster access so they aren't accessed every time the - * {@link #start()} method is called. - */ - protected Field[] fieldsCache = null; - /** Default constructor for pooling purposes. */ protected FlixelTween() {} + protected FlixelTween(FlixelTweenSettings tweenSettings) { + this.tweenSettings = tweenSettings; + } + /** - * Constructs a new tween. - * - *

Note that this does NOT add the tween to the global manager, it just assigns its main - * values. That's it. If you wish to create a tween to automatically start working, you might want - * to see {@link FlixelTween#tween(Object object, FlixelTweenSettings tweenSettings, - * FunkinTweenUpdateCallback updateCallback)}. + * Creates a new tween with the provided settings and starts it in the global tween manager. * - * @param object The object to tween values. - * @param settings The settings that configure and determine how the tween should animate and last - * for. + * @param object The object to tween its values. + * @param tweenSettings The settings that configure and determine how the tween should animate. * @param updateCallback Callback function for updating the objects values when the tween updates. + * @return The newly created and started tween. */ - protected FlixelTween( - Object object, FlixelTweenSettings settings, FunkinTweenUpdateCallback updateCallback) { - this.object = object; - this.tweenSettings = settings; - this.updateCallback = updateCallback; + public static FlixelTween tween(Object object, FlixelTweenSettings tweenSettings, FlixelVarTween.FunkinVarTweenUpdateCallback updateCallback) { + return new FlixelVarTween(object, tweenSettings, updateCallback) + .setManager(globalManager) + .start(); + } + + public static FlixelTween num(float from, float to, FlixelTweenSettings tweenSettings, FlixelNumTween.FlixelNumTweenUpdateCallback updateCallback) { + return new FlixelNumTween(from, to, tweenSettings, updateCallback) + .setManager(globalManager) + .start(); } /** - * Creates a new tween with the provided settings and starts it in the global tween manager. + * Starts {@code this} tween and resets every value to its initial state. * - * @param object The object to tween its values. - * @param tweenSettings The settings that configure and determine how the tween should animate. - * @param updateCallback Callback function for updating the objects values when the tween updates. - * @return The newly created and started tween. + * @return {@code this} tween. */ - public static FlixelTween tween( - Object object, FlixelTweenSettings tweenSettings, FunkinTweenUpdateCallback updateCallback) { - return new FlixelTween(object, tweenSettings, updateCallback).setManager(globalManager).start(); + public FlixelTween start() { + resetBasic(); + running = true; + finished = false; + return this; } + /** + * Updates {@code this} tween by the given delta time. + * + * @param delta How much time has passed since the last update. + */ public void update(float delta) { - if (paused || finished) { - return; - } - if (object == null) { + if (paused || finished || !running) { return; } if (tweenSettings == null) { return; } - if (updateCallback == null) { - return; - } var ease = tweenSettings.getEase(); var duration = tweenSettings.getDuration(); var onStart = tweenSettings.getOnStart(); var onUpdate = tweenSettings.getOnUpdate(); + var onComplete = tweenSettings.getOnComplete(); var framerate = tweenSettings.getFramerate(); float preTick = secondsSinceStart; @@ -150,33 +134,13 @@ public void update(float delta) { } } - // Update the object's fields based on the tween progress. - var newValues = new HashMap(); - var goals = tweenSettings.getGoalFields(); - for (String field : goals) { - FlixelTweenSettings.FunkinTweenGoal goal = tweenSettings.getGoal(field); - if (goal == null) { - continue; - } - if (initialValues.isEmpty()) { - continue; - } - if (!initialValues.containsKey(field)) { - continue; - } - float startValue = initialValues.get(field); - float goalValue = goal.value(); - float newValue = startValue + (goalValue - startValue) * scale; - newValues.put(field, newValue); - } - if (!newValues.isEmpty() && initialValues.keySet().containsAll(newValues.keySet())) { - updateCallback.update(newValues); - } - // Check if the tween has finished. if (secondsSinceStart >= duration + delay) { scale = (backward) ? 0 : 1; finished = true; + if (onComplete != null) { + onComplete.run(this); + } } else { if (postTick > preTick && onUpdate != null) { onUpdate.run(this); @@ -184,63 +148,6 @@ public void update(float delta) { } } - /** - * Starts {@code this} tween and resets every value to its initial state. - * - * @return {@code this} tween. - */ - public FlixelTween start() { - resetBasic(); - running = true; - finished = false; - - if (tweenSettings == null) { - Flixel.warn("FlixelTween", "No tween settings were provided for the tween."); - return this; - } - var neededFields = tweenSettings.getGoalFields(); - if (neededFields == null || neededFields.isEmpty()) { - Flixel.warn("FlixelTween", "No fields were provided to tween on the object."); - return this; - } - - if (fieldsCache == null) { - fieldsCache = FlixelReflectUtil.getAllFieldsAsArray(object.getClass()); - } - - // Ensure that the fields provided actually exist on the object and are floating point values. - // If there are fields that the tween is trying to tween that don't exist, then throw an error. - Set fieldIds = - Arrays.stream(fieldsCache).map(Field::getName).collect(Collectors.toSet()); - for (String neededField : neededFields) { - if (!fieldIds.contains(neededField)) { - String message = "Field \"" + neededField + "\" does not exist on the given object."; - Flixel.error("FlixelTween", message); - throw new RuntimeException(message); - } - } - - for (Field field : fieldsCache) { - try { - String fName = field.getName(); - if (!field.trySetAccessible()) { - continue; - } - if (!neededFields.contains(fName)) { - continue; - } - if (field.getType() != float.class) { - continue; - } - initialValues.put(fName, field.getFloat(object)); - } catch (IllegalAccessException e) { - Flixel.error( - FlixelConstants.System.LOG_TAG, "Could not access field \"" + field.getName() + "\".", e); - } - } - return this; - } - /** * Resumes {@code this} tween if it was previously paused. * @@ -270,13 +177,11 @@ public FlixelTween pause() { */ public FlixelTween stop() { running = false; - finished = true; return this; } /** - * Cancels {@code this} tween and automatically defaults its values, removing it from the manager - * by default. + * Cancels {@code this} tween and automatically defaults its values, removing it from its manager by default. * * @return {@code this} tween. */ @@ -302,7 +207,6 @@ public FlixelTween cancel(boolean remove) { public void reset() { resetBasic(); manager = null; - fieldsCache = null; } /** @@ -317,7 +221,6 @@ public void resetBasic() { running = false; finished = false; backward = false; - initialValues.clear(); } public FlixelTweenSettings getTweenSettings() { @@ -333,6 +236,10 @@ public static FlixelTweenManager getGlobalManager() { return globalManager; } + public FlixelTweenManager getManager() { + return manager; + } + public FlixelTween setManager(FlixelTweenManager newManager) { if (newManager != null) { if (manager != null) { @@ -345,17 +252,4 @@ public FlixelTween setManager(FlixelTweenManager newManager) { } return this; } - - /** Callback interface for changing an objects values when a tween updates its values. */ - @FunctionalInterface - public interface FunkinTweenUpdateCallback { - - /** - * A callback method that is called when the tween updates its values during its tweening (or - * animating) process. - * - * @param values The new current values of the fields being tweened during the animation. - */ - void update(Map values); - } } diff --git a/core/src/main/java/me/stringdotjar/flixelgdx/tween/FlixelTweenManager.java b/flixelgdx/src/main/java/me/stringdotjar/flixelgdx/tween/FlixelTweenManager.java similarity index 100% rename from core/src/main/java/me/stringdotjar/flixelgdx/tween/FlixelTweenManager.java rename to flixelgdx/src/main/java/me/stringdotjar/flixelgdx/tween/FlixelTweenManager.java diff --git a/core/src/main/java/me/stringdotjar/flixelgdx/tween/settings/FlixelTweenSettings.java b/flixelgdx/src/main/java/me/stringdotjar/flixelgdx/tween/settings/FlixelTweenSettings.java similarity index 89% rename from core/src/main/java/me/stringdotjar/flixelgdx/tween/settings/FlixelTweenSettings.java rename to flixelgdx/src/main/java/me/stringdotjar/flixelgdx/tween/settings/FlixelTweenSettings.java index 70f22dd..1f202bb 100644 --- a/core/src/main/java/me/stringdotjar/flixelgdx/tween/settings/FlixelTweenSettings.java +++ b/flixelgdx/src/main/java/me/stringdotjar/flixelgdx/tween/settings/FlixelTweenSettings.java @@ -59,6 +59,8 @@ public FlixelTweenSettings( /** * Adds a new goal to tween an objects value to. * + *

Note that this is only used on a {@link me.stringdotjar.flixelgdx.tween.type.FlixelVarTween}. + * * @param field The field to tween. * @param value The value to tween the field to. * @return {@code this} tween settings object for chaining. @@ -165,6 +167,21 @@ public FlixelTweenSettings setType(@NotNull FlixelTweenType type) { return this; } + public FlixelTweenSettings setOnStart(FlixelEase.FunkinEaseStartCallback onStart) { + this.onStart = onStart; + return this; + } + + public FlixelTweenSettings setOnUpdate(FlixelEase.FunkinEaseUpdateCallback onUpdate) { + this.onUpdate = onUpdate; + return this; + } + + public FlixelTweenSettings setOnComplete(FlixelEase.FunkinEaseCompleteCallback onComplete) { + this.onComplete = onComplete; + return this; + } + /** * A record containing basic info for a tween goal (aka a field to tween a numeric value to). * diff --git a/core/src/main/java/me/stringdotjar/flixelgdx/tween/settings/FlixelTweenType.java b/flixelgdx/src/main/java/me/stringdotjar/flixelgdx/tween/settings/FlixelTweenType.java similarity index 100% rename from core/src/main/java/me/stringdotjar/flixelgdx/tween/settings/FlixelTweenType.java rename to flixelgdx/src/main/java/me/stringdotjar/flixelgdx/tween/settings/FlixelTweenType.java diff --git a/flixelgdx/src/main/java/me/stringdotjar/flixelgdx/tween/type/FlixelNumTween.java b/flixelgdx/src/main/java/me/stringdotjar/flixelgdx/tween/type/FlixelNumTween.java new file mode 100644 index 0000000..40cc7d1 --- /dev/null +++ b/flixelgdx/src/main/java/me/stringdotjar/flixelgdx/tween/type/FlixelNumTween.java @@ -0,0 +1,73 @@ +package me.stringdotjar.flixelgdx.tween.type; + +import me.stringdotjar.flixelgdx.tween.FlixelTween; +import me.stringdotjar.flixelgdx.tween.settings.FlixelTweenSettings; + +/** + * Tween type that tweens one numerical value to another. + */ +public class FlixelNumTween extends FlixelTween { + + /** The starting value of the tween. */ + protected float start; + + /** The target value of the tween. */ + protected float end; + + /** The current value of the tween. */ + protected float value; + + /** The range between the start and end values. */ + protected float range; + + /** Callback function for updating the value when the tween updates. */ + protected FlixelNumTweenUpdateCallback updateCallback; + + /** + * Constructs a new numerical tween, which will tween a simple starting number to an ending value. + * + * @param start The starting value. + * @param end The ending value. + * @param settings The settings that configure and determine how the tween should animate. + * @param updateCallback Callback function for updating any variable that needs the current value when the tween updates. + */ + public FlixelNumTween(float start, float end, FlixelTweenSettings settings, FlixelNumTweenUpdateCallback updateCallback) { + super(settings); + this.start = start; + this.end = end; + this.value = start; + this.range = end - start; + this.updateCallback = updateCallback; + } + + @Override + public void update(float delta) { + super.update(delta); + + if (paused || finished || !running) { + return; + } + if (updateCallback == null) { + return; + } + + value = start + range * scale; + + updateCallback.update(value); + } + + /** + * Functional interface for updating the numerical value when the tween updates. This is for updating any + * variable that needs the current value of the tween. + */ + @FunctionalInterface + public interface FlixelNumTweenUpdateCallback { + + /** + * A callback method that is called when the tween updates its value during its tweening (or animating) process. + * + * @param value The new current value of the numerical tween during the animation. + */ + void update(float value); + } +} diff --git a/flixelgdx/src/main/java/me/stringdotjar/flixelgdx/tween/type/FlixelVarTween.java b/flixelgdx/src/main/java/me/stringdotjar/flixelgdx/tween/type/FlixelVarTween.java new file mode 100644 index 0000000..3f14829 --- /dev/null +++ b/flixelgdx/src/main/java/me/stringdotjar/flixelgdx/tween/type/FlixelVarTween.java @@ -0,0 +1,165 @@ +package me.stringdotjar.flixelgdx.tween.type; + +import me.stringdotjar.flixelgdx.Flixel; +import me.stringdotjar.flixelgdx.tween.FlixelTween; +import me.stringdotjar.flixelgdx.tween.settings.FlixelTweenSettings; +import me.stringdotjar.flixelgdx.util.FlixelConstants; +import me.stringdotjar.flixelgdx.util.FlixelReflectUtil; + +import java.lang.reflect.Field; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; + +/** + * Tween type for tweening specific fields on an object using reflection. + */ +public class FlixelVarTween extends FlixelTween { + + /** The object to tween. */ + protected Object object; + + /** The initial values of the fields being tweened. */ + protected final Map initialValues = new HashMap<>(); + + /** + * Cache of the fields being tweened for faster access so they aren't accessed every time the + * {@link #start()} method is called. + */ + protected Field[] fieldsCache = null; + + /** The update callback for {@code this} tween to change the objects values every update. */ + protected FlixelVarTween.FunkinVarTweenUpdateCallback updateCallback; + + /** + * Constructs a new object tween using reflection. + * + *

Note that this does NOT add the tween to the global manager, it just assigns its main + * values. That's it. If you wish to create a tween to automatically start working, you might want + * to see {@link FlixelTween#tween(Object object, FlixelTweenSettings tweenSettings, + * FunkinVarTweenUpdateCallback updateCallback)}. + * + * @param object The object to tween values. + * @param settings The settings that configure and determine how the tween should animate and last for. + * @param updateCallback Callback function for updating the objects values when the tween updates. + */ + public FlixelVarTween(Object object, FlixelTweenSettings settings, FunkinVarTweenUpdateCallback updateCallback) { + super(settings); + this.object = object; + this.updateCallback = updateCallback; + } + + @Override + public FlixelTween start() { + super.start(); + + if (tweenSettings == null) { + Flixel.warn("FlixelTween", "No tween settings were provided for the tween."); + return this; + } + var neededFields = tweenSettings.getGoalFields(); + if (neededFields == null || neededFields.isEmpty()) { + Flixel.warn("FlixelTween", "No fields were provided to tween on the object."); + return this; + } + + if (fieldsCache == null) { + fieldsCache = FlixelReflectUtil.getAllFieldsAsArray(object.getClass()); + } + + // Ensure that the fields provided actually exist on the object and are floating point values. + // If there are fields that the tween is trying to tween that don't exist, then throw an error. + Set fieldIds = Arrays.stream(fieldsCache).map(Field::getName).collect(Collectors.toSet()); + for (String neededField : neededFields) { + if (!fieldIds.contains(neededField)) { + String message = "Field \"" + neededField + "\" does not exist on the given object."; + Flixel.error("FlixelTween", message); + throw new RuntimeException(message); + } + } + + for (Field field : fieldsCache) { + try { + String fName = field.getName(); + if (!field.trySetAccessible()) { + continue; + } + if (!neededFields.contains(fName)) { + continue; + } + if (field.getType() != float.class) { + continue; + } + initialValues.put(fName, field.getFloat(object)); + } catch (IllegalAccessException e) { + Flixel.error(FlixelConstants.System.LOG_TAG, "Could not access field \"" + field.getName() + "\".", e); + } + } + return this; + } + + @Override + public void update(float delta) { + super.update(delta); + + if (object == null) { + return; + } + if (paused || finished) { + return; + } + if (updateCallback == null) { + return; + } + + // Update the object's fields based on the tween progress. + var newValues = new HashMap(); + var goals = tweenSettings.getGoalFields(); + for (String field : goals) { + FlixelTweenSettings.FunkinTweenGoal goal = tweenSettings.getGoal(field); + if (goal == null) { + continue; + } + if (initialValues.isEmpty()) { + continue; + } + if (!initialValues.containsKey(field)) { + continue; + } + float startValue = initialValues.get(field); + float goalValue = goal.value(); + float newValue = startValue + (goalValue - startValue) * scale; + newValues.put(field, newValue); + } + if (!newValues.isEmpty() && initialValues.keySet().containsAll(newValues.keySet())) { + updateCallback.update(newValues); + } + } + + @Override + public void reset() { + super.reset(); + fieldsCache = null; + } + + @Override + public void resetBasic() { + super.resetBasic(); + initialValues.clear(); + } + + /** Callback interface for changing an objects values when a var tween updates its values. */ + @FunctionalInterface + public interface FunkinVarTweenUpdateCallback { + + /** + * A callback method that is called when the tween updates its values during its tweening (or + * animating) process. + * + * @param values The new current values of the fields being tweened during the animation. + */ + void update(Map values); + } +} diff --git a/core/src/main/java/me/stringdotjar/flixelgdx/util/FlixelConstants.java b/flixelgdx/src/main/java/me/stringdotjar/flixelgdx/util/FlixelConstants.java similarity index 100% rename from core/src/main/java/me/stringdotjar/flixelgdx/util/FlixelConstants.java rename to flixelgdx/src/main/java/me/stringdotjar/flixelgdx/util/FlixelConstants.java diff --git a/flixelgdx/src/main/java/me/stringdotjar/flixelgdx/util/FlixelMathUtil.java b/flixelgdx/src/main/java/me/stringdotjar/flixelgdx/util/FlixelMathUtil.java new file mode 100644 index 0000000..bd28994 --- /dev/null +++ b/flixelgdx/src/main/java/me/stringdotjar/flixelgdx/util/FlixelMathUtil.java @@ -0,0 +1,21 @@ +package me.stringdotjar.flixelgdx.util; + +/** + * Utility class for various math related functions used in FlixelGDX. + */ +public final class FlixelMathUtil { + + /** + * Rounds a float value to a specified number of decimal places. + * + * @param value The float value to round. + * @param decimalPlaces The number of decimal places to round to. + * @return The rounded float value. + */ + public static float round(float value, int decimalPlaces) { + float scale = (float) Math.pow(10, decimalPlaces); + return Math.round(value * scale) / scale; + } + + private FlixelMathUtil() {} +} diff --git a/core/src/main/java/me/stringdotjar/flixelgdx/util/FlixelReflectUtil.java b/flixelgdx/src/main/java/me/stringdotjar/flixelgdx/util/FlixelReflectUtil.java similarity index 100% rename from core/src/main/java/me/stringdotjar/flixelgdx/util/FlixelReflectUtil.java rename to flixelgdx/src/main/java/me/stringdotjar/flixelgdx/util/FlixelReflectUtil.java diff --git a/core/src/main/java/me/stringdotjar/flixelgdx/util/FlixelRuntimeUtil.java b/flixelgdx/src/main/java/me/stringdotjar/flixelgdx/util/FlixelRuntimeUtil.java similarity index 100% rename from core/src/main/java/me/stringdotjar/flixelgdx/util/FlixelRuntimeUtil.java rename to flixelgdx/src/main/java/me/stringdotjar/flixelgdx/util/FlixelRuntimeUtil.java diff --git a/core/build.gradle b/funkin/build.gradle similarity index 91% rename from core/build.gradle rename to funkin/build.gradle index 4dd5eed..b1991df 100644 --- a/core/build.gradle +++ b/funkin/build.gradle @@ -1,17 +1,16 @@ [compileJava, compileTestJava]*.options*.encoding = 'UTF-8' -eclipse.project.name = appName + '-core' +eclipse.project.name = appName + '-funkin' dependencies { - // libGDX. api "com.badlogicgames.gdx:gdx-freetype:$gdxVersion" api "com.badlogicgames.gdx:gdx:$gdxVersion" api "com.github.tommyettinger:anim8-gdx:$anim8Version" api "com.github.tommyettinger:libgdx-utils:$utilsVersion" api "io.github.libktx:ktx-freetype:$ktxVersion" api "games.rednblack.miniaudio:miniaudio:$miniaudioVersion" + api project(":flixelgdx") + api project(":polyverse") - // FNF:JE. - implementation "org.apache.groovy:groovy:5.0.3" implementation "org.jetbrains:annotations:26.0.2-1" if (enableGraalNative == 'true') { diff --git a/core/src/main/java/me/stringdotjar/funkin/FunkinGame.java b/funkin/src/main/java/me/stringdotjar/funkin/FunkinGame.java similarity index 59% rename from core/src/main/java/me/stringdotjar/funkin/FunkinGame.java rename to funkin/src/main/java/me/stringdotjar/funkin/FunkinGame.java index 0040de4..cfdce50 100644 --- a/core/src/main/java/me/stringdotjar/funkin/FunkinGame.java +++ b/funkin/src/main/java/me/stringdotjar/funkin/FunkinGame.java @@ -13,6 +13,8 @@ */ public class FunkinGame extends FlixelGame { + private float lastVolume = 1.0f; + public FunkinGame(String title, int width, int height, FlixelScreen initialScreen) { super(title, width, height, initialScreen); } @@ -26,10 +28,38 @@ public void create() { @Override public void render() { super.render(); - Polyverse.forAllScripts(script -> script.onRender(Flixel.getDelta())); } + @Override + public void dispose() { + super.dispose(); + Polyverse.forAllScripts(Script::onDispose); + } + + @Override + public void onWindowFocused() { + super.onWindowFocused(); + Flixel.setMasterVolume(lastVolume); + Polyverse.forEachScript(SystemScript.class, SystemScript::onWindowFocused); + } + + @Override + public void onWindowUnfocused() { + super.onWindowUnfocused(); + lastVolume = Flixel.getMasterVolume(); + Flixel.setMasterVolume(0.008f); + Polyverse.forEachScript(SystemScript.class, SystemScript::onWindowUnfocused); + } + + @Override + public void onWindowMinimized(boolean iconified) { + super.onWindowMinimized(iconified); + lastVolume = Flixel.getMasterVolume(); + Flixel.setMasterVolume(0); + Polyverse.forEachScript(SystemScript.class, script -> script.onWindowMinimized(iconified)); + } + private void configurePolyverse() { // Register Polyverse script types. Polyverse.registerScriptType(Script.class); // Master type, DO NOT REMOVE THIS! diff --git a/core/src/main/java/me/stringdotjar/funkin/init/InitScreen.java b/funkin/src/main/java/me/stringdotjar/funkin/InitScreen.java similarity index 89% rename from core/src/main/java/me/stringdotjar/funkin/init/InitScreen.java rename to funkin/src/main/java/me/stringdotjar/funkin/InitScreen.java index f73bf8c..e90d619 100644 --- a/core/src/main/java/me/stringdotjar/funkin/init/InitScreen.java +++ b/funkin/src/main/java/me/stringdotjar/funkin/InitScreen.java @@ -1,4 +1,4 @@ -package me.stringdotjar.funkin.init; +package me.stringdotjar.funkin; import me.stringdotjar.flixelgdx.graphics.screen.FlixelScreen; import me.stringdotjar.flixelgdx.Flixel; diff --git a/core/src/main/java/me/stringdotjar/funkin/menus/TitleScreen.java b/funkin/src/main/java/me/stringdotjar/funkin/menus/TitleScreen.java similarity index 94% rename from core/src/main/java/me/stringdotjar/funkin/menus/TitleScreen.java rename to funkin/src/main/java/me/stringdotjar/funkin/menus/TitleScreen.java index 5597818..99c78e2 100644 --- a/core/src/main/java/me/stringdotjar/funkin/menus/TitleScreen.java +++ b/funkin/src/main/java/me/stringdotjar/funkin/menus/TitleScreen.java @@ -51,16 +51,16 @@ public void render(float elapsed) { float speed = 500 * elapsed; if (Flixel.keyPressed(Input.Keys.W)) { - logo.setY(logo.getY() + speed); + logo.changeY(speed); } if (Flixel.keyPressed(Input.Keys.S)) { - logo.setY(logo.getY() - speed); + logo.changeY(-speed); } if (Flixel.keyPressed(Input.Keys.A)) { - logo.setX(logo.getX() - speed); + logo.changeX(-speed); } if (Flixel.keyPressed(Input.Keys.D)) { - logo.setX(logo.getX() + speed); + logo.changeX(speed); } if (Flixel.keyJustPressed(Input.Keys.SPACE)) { diff --git a/core/src/main/java/me/stringdotjar/funkin/util/FunkinConstants.java b/funkin/src/main/java/me/stringdotjar/funkin/util/FunkinConstants.java similarity index 100% rename from core/src/main/java/me/stringdotjar/funkin/util/FunkinConstants.java rename to funkin/src/main/java/me/stringdotjar/funkin/util/FunkinConstants.java diff --git a/lwjgl3/build.gradle b/lwjgl3/build.gradle index aedb396..2038bf9 100644 --- a/lwjgl3/build.gradle +++ b/lwjgl3/build.gradle @@ -29,7 +29,8 @@ dependencies { implementation "com.badlogicgames.gdx:gdx-backend-lwjgl3:$gdxVersion" implementation "com.badlogicgames.gdx:gdx-freetype-platform:$gdxVersion:natives-desktop" implementation "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-desktop" - implementation project(':core') + implementation project(':funkin') + implementation project(":flixelgdx") if (enableGraalNative == 'true') { implementation "io.github.berstanio:gdx-svmhelper-backend-lwjgl3:$graalHelperVersion" diff --git a/lwjgl3/src/main/java/me/stringdotjar/funkin/lwjgl3/Lwjgl3Launcher.java b/lwjgl3/src/main/java/me/stringdotjar/funkin/lwjgl3/Lwjgl3Launcher.java index 6a84013..7222c22 100644 --- a/lwjgl3/src/main/java/me/stringdotjar/funkin/lwjgl3/Lwjgl3Launcher.java +++ b/lwjgl3/src/main/java/me/stringdotjar/funkin/lwjgl3/Lwjgl3Launcher.java @@ -5,7 +5,7 @@ import com.badlogic.gdx.backends.lwjgl3.Lwjgl3WindowAdapter; import me.stringdotjar.flixelgdx.Flixel; import me.stringdotjar.funkin.FunkinGame; -import me.stringdotjar.funkin.init.InitScreen; +import me.stringdotjar.funkin.InitScreen; import me.stringdotjar.funkin.util.FunkinConstants; /** Launches the desktop (LWJGL3) application. */ @@ -26,12 +26,13 @@ private static void createApplication() { new InitScreen() ); Flixel.initialize(game); // This is VERY important to do before creating the application! - new Lwjgl3Application(game, createWindowConfiguration()); + var size = game.getWindowSize(); + new Lwjgl3Application(game, createWindowConfiguration(game.getTitle(), (int) size.x, (int) size.y)); } - private static Lwjgl3ApplicationConfiguration createWindowConfiguration() { + private static Lwjgl3ApplicationConfiguration createWindowConfiguration(String title, int width, int height) { Lwjgl3ApplicationConfiguration configuration = new Lwjgl3ApplicationConfiguration(); - configuration.setTitle("Friday Night Flixel': Java Edition"); + configuration.setTitle(title); // Vsync limits the frames per second to what your hardware can display, and helps eliminate // screen tearing. This setting doesn't always work on Linux, so the line after is a safeguard. configuration.useVsync(true); @@ -41,7 +42,7 @@ private static Lwjgl3ApplicationConfiguration createWindowConfiguration() { // If you remove the above line and set Vsync to false, you can get unlimited FPS, which can be // useful for testing performance, but can also be very stressful to some hardware. // You may also need to configure GPU drivers to fully disable Vsync; this can cause screen tearing. - configuration.setWindowedMode(FunkinConstants.WINDOW_WIDTH, FunkinConstants.WINDOW_HEIGHT); + configuration.setWindowedMode(width, height); // You can change these files; they are in lwjgl3/src/main/resources/ . // They can also be loaded from the root of assets/ . configuration.setWindowIcon("icon128.png", "icon64.png", "icon32.png", "icon16.png"); diff --git a/polyverse/build.gradle b/polyverse/build.gradle new file mode 100644 index 0000000..cc873dd --- /dev/null +++ b/polyverse/build.gradle @@ -0,0 +1,9 @@ +[compileJava, compileTestJava]*.options*.encoding = 'UTF-8' +eclipse.project.name = appName + '-polyverse' + +dependencies { + api project(":flixelgdx") + + implementation "org.apache.groovy:groovy:5.0.3" + implementation "org.jetbrains:annotations:26.0.2-1" +} diff --git a/core/src/main/java/me/stringdotjar/polyverse/Polyverse.java b/polyverse/src/main/java/me/stringdotjar/polyverse/Polyverse.java similarity index 100% rename from core/src/main/java/me/stringdotjar/polyverse/Polyverse.java rename to polyverse/src/main/java/me/stringdotjar/polyverse/Polyverse.java diff --git a/core/src/main/java/me/stringdotjar/polyverse/script/type/Script.java b/polyverse/src/main/java/me/stringdotjar/polyverse/script/type/Script.java similarity index 100% rename from core/src/main/java/me/stringdotjar/polyverse/script/type/Script.java rename to polyverse/src/main/java/me/stringdotjar/polyverse/script/type/Script.java diff --git a/polyverse/src/main/java/me/stringdotjar/polyverse/script/type/SystemScript.java b/polyverse/src/main/java/me/stringdotjar/polyverse/script/type/SystemScript.java new file mode 100644 index 0000000..1024e0e --- /dev/null +++ b/polyverse/src/main/java/me/stringdotjar/polyverse/script/type/SystemScript.java @@ -0,0 +1,17 @@ +package me.stringdotjar.polyverse.script.type; + +public abstract class SystemScript extends Script { + + public SystemScript(String id) { + super(id); + } + + /** Called when the game window gains focus. */ + public void onWindowFocused() {} + + /** Called when the game window loses focus. */ + public void onWindowUnfocused() {} + + /** Called when the game window is minimized. */ + public void onWindowMinimized(boolean iconified) {} +} diff --git a/settings.gradle b/settings.gradle index bf5968d..b3a82d8 100644 --- a/settings.gradle +++ b/settings.gradle @@ -5,4 +5,4 @@ plugins { // A list of which subprojects to load as part of the same larger project. // You can remove Strings from the list and reload the Gradle project // if you want to temporarily disable a subproject. -include 'lwjgl3', 'android', 'core' +include 'funkin', 'flixelgdx', 'polyverse', 'lwjgl3', 'android'