diff --git a/assets/test.groovy b/assets/test.groovy index fba075e..70f8420 100644 --- a/assets/test.groovy +++ b/assets/test.groovy @@ -2,7 +2,7 @@ import com.badlogic.gdx.Gdx import com.badlogic.gdx.Input import com.badlogic.gdx.graphics.Color import me.stringdotjar.flixelgdx.Flixel -import me.stringdotjar.flixelgdx.graphics.screen.FlixelScreen +import me.stringdotjar.flixelgdx.graphics.FlixelScreen import me.stringdotjar.flixelgdx.backend.FlixelPaths import me.stringdotjar.flixelgdx.graphics.sprite.FlixelSprite import me.stringdotjar.polyverse.script.type.SystemScript @@ -46,8 +46,8 @@ class TestScreen extends FlixelScreen { private FlixelSprite test @Override - void show() { - super.show() + void create() { + super.create() test = new FlixelSprite().loadGraphic(FlixelPaths.sharedImageAsset('NOTE_hold_assets')) add(test) @@ -58,7 +58,7 @@ class TestScreen extends FlixelScreen { } @Override - void render(float delta) { - super.render(delta) + void update(float delta) { + super.update(delta) } } diff --git a/flixelgdx/src/main/java/me/stringdotjar/flixelgdx/Flixel.java b/flixelgdx/src/main/java/me/stringdotjar/flixelgdx/Flixel.java index 615053f..e78ff25 100644 --- a/flixelgdx/src/main/java/me/stringdotjar/flixelgdx/Flixel.java +++ b/flixelgdx/src/main/java/me/stringdotjar/flixelgdx/Flixel.java @@ -3,12 +3,14 @@ import com.badlogic.gdx.Gdx; import com.badlogic.gdx.assets.AssetManager; import com.badlogic.gdx.files.FileHandle; +import com.badlogic.gdx.math.Vector2; import com.badlogic.gdx.scenes.scene2d.Stage; import games.rednblack.miniaudio.MAGroup; import games.rednblack.miniaudio.MASound; import games.rednblack.miniaudio.MiniAudio; import games.rednblack.miniaudio.loader.MASoundLoader; -import me.stringdotjar.flixelgdx.graphics.screen.FlixelScreen; +import me.stringdotjar.flixelgdx.graphics.FlixelScreen; +import me.stringdotjar.flixelgdx.graphics.FlixelViewport; import me.stringdotjar.flixelgdx.util.FlixelConstants; import me.stringdotjar.flixelgdx.signal.FlixelSignal; import me.stringdotjar.flixelgdx.signal.FlixelSignalData.MusicPlayedSignalData; @@ -88,12 +90,13 @@ public static void setScreen(FlixelScreen newScreen) { if (newScreen == null) { throw new IllegalArgumentException("Screen cannot be null!"); } - if (Flixel.screen != null) { - Flixel.screen.hide(); - Flixel.screen.dispose(); + if (screen != null) { + screen.hide(); + screen.dispose(); } - Flixel.screen = newScreen; - Flixel.screen.show(); + game.resetViewports(); + screen = newScreen; + screen.create(); Signals.postScreenSwitch.dispatch(new ScreenSwitchSignalData(newScreen)); } @@ -377,6 +380,10 @@ public static MASound getMusic() { return music; } + public static Vector2 getWindowSize() { + return game.windowSize; + } + public static MiniAudio getAudioEngine() { return engine; } @@ -397,6 +404,14 @@ public static float getDelta() { return Gdx.graphics.getDeltaTime(); } + public static FlixelViewport getViewport() { + return game.getViewport(); + } + + public static boolean isFullscreen() { + return Gdx.graphics.isFullscreen(); + } + /** * Contains all the global events that get dispatched when something happens in the game. * diff --git a/flixelgdx/src/main/java/me/stringdotjar/flixelgdx/FlixelGame.java b/flixelgdx/src/main/java/me/stringdotjar/flixelgdx/FlixelGame.java index 8d1b17a..faa04b5 100644 --- a/flixelgdx/src/main/java/me/stringdotjar/flixelgdx/FlixelGame.java +++ b/flixelgdx/src/main/java/me/stringdotjar/flixelgdx/FlixelGame.java @@ -3,24 +3,21 @@ import com.badlogic.gdx.Application; import com.badlogic.gdx.ApplicationListener; import com.badlogic.gdx.Gdx; -import com.badlogic.gdx.Input; import com.badlogic.gdx.graphics.Color; -import com.badlogic.gdx.graphics.OrthographicCamera; import com.badlogic.gdx.graphics.Pixmap; import com.badlogic.gdx.graphics.Texture; import com.badlogic.gdx.graphics.g2d.SpriteBatch; import com.badlogic.gdx.math.Vector2; import com.badlogic.gdx.scenes.scene2d.Stage; import com.badlogic.gdx.utils.ScreenUtils; -import com.badlogic.gdx.utils.viewport.FitViewport; -import me.stringdotjar.flixelgdx.graphics.screen.FlixelScreen; -import me.stringdotjar.flixelgdx.graphics.sprite.FlixelObject; +import com.badlogic.gdx.utils.SnapshotArray; +import me.stringdotjar.flixelgdx.graphics.FlixelObject; +import me.stringdotjar.flixelgdx.graphics.FlixelScreen; +import me.stringdotjar.flixelgdx.graphics.FlixelViewport; +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 java.awt.EventQueue; - import static me.stringdotjar.flixelgdx.signal.FlixelSignalData.RenderSignalData; /** @@ -41,26 +38,23 @@ public abstract class FlixelGame implements ApplicationListener { protected FlixelScreen initialScreen; /** Is the game's window currently focused? */ - protected boolean isFocused = true; + private boolean isFocused = true; /** Is the game's window currently minimized? */ - protected boolean isMinimized = false; + private boolean isMinimized = false; /** The main stage used for rendering all screens and sprites on screen. */ protected Stage stage; - /** The main viewport used to fit the world no matter the screen size. */ - protected FitViewport viewport; - - /** The main camera used to see the world. */ - protected OrthographicCamera camera; - /** The main sprite batch used for rendering all sprites on screen. */ protected SpriteBatch batch; /** The 1x1 texture used to draw the background color of the current screen. */ protected Texture bgTexture; + /** Where all the global viewports are stored. */ + protected SnapshotArray viewports; + /** * Creates a new game instance with the specified title, window width/height, and initial screen. This configures * the game's core parts, such as the viewport, stage, etc. @@ -81,13 +75,10 @@ public void create() { configureCrashHandler(); // This should ALWAYS be called first no matter what! batch = new SpriteBatch(); - viewport = new FitViewport(windowSize.x, windowSize.y); - viewport.apply(); - - camera = new OrthographicCamera(); - camera.setToOrtho(false, windowSize.x, windowSize.y); + viewports = new SnapshotArray<>(FlixelViewport.class); + viewports.add(new FlixelViewport((int) windowSize.x, (int) windowSize.y)); - stage = new Stage(viewport, batch); + stage = new Stage(getViewport(), batch); Pixmap pixmap = new Pixmap(1, 1, Pixmap.Format.RGBA8888); pixmap.setColor(Color.WHITE); @@ -101,8 +92,14 @@ public void create() { @Override public void resize(int width, int height) { - windowSize.set(width, height); - viewport.update(width, height, true); + FlixelViewport[] viewportsArray = viewports.begin(); + for (int i = 0; i < viewports.size; i++) { + FlixelViewport viewport = viewportsArray[i]; + if (viewport != null) { + viewport.update(width, height, true); + } + } + viewports.end(); } @Override @@ -112,34 +109,60 @@ public void render() { Flixel.Signals.preRender.dispatch(new RenderSignalData(delta)); + stage.act(delta); + FlixelTween.getGlobalManager().update(delta); + // Update and render the current screen that's active. ScreenUtils.clear(Color.BLACK); - viewport.apply(); - batch.setProjectionMatrix(camera.combined); - batch.begin(); if (screen != null) { - batch.setColor(screen.getBgColor()); - batch.draw(bgTexture, 0, 0, viewport.getWorldWidth(), viewport.getWorldHeight()); - batch.setColor(Color.WHITE); // Set color back to white so display objects aren't affected. - screen.render(delta); - var members = screen.members.begin(); - for (FlixelObject object : members) { - if (object == null) { + screen.update(delta); + + // Loop through all viewports and draw the current screen's members onto their set viewports. + FlixelViewport[] vps = viewports.begin(); + SnapshotArray members = screen.getMembers(); + for (int i = 0; i < viewports.size; i++) { + FlixelViewport viewport = vps[i]; + if (viewport == null) { continue; } - object.update(delta); - object.draw(batch); + + viewport.apply(); + var camera = viewport.getCamera(); + camera.update(); + batch.setProjectionMatrix(camera.combined); + batch.begin(); + + // Draw the background color first. + batch.setColor(screen.getBgColor()); + batch.draw(bgTexture, 0, 0, getViewport().getWorldWidth(), getViewport().getWorldHeight()); + batch.setColor(Color.WHITE); // Set the batch color back to white so display objects aren't affected. + // Draw all the current screens members. + FlixelObject[] mbrs = members.begin(); + for (int j = 0; j < members.size; j++) { + FlixelObject member = mbrs[j]; + if (member == null) { + continue; + } + member.update(delta); + if (member instanceof FlixelSprite s) { + // Check if the current sprite is in the visible part of the viewport. + // If it cannot be seen, then we don't draw the sprite to save performance. + if (camera.frustum.boundsInFrustum(s.getX(), s.getY(), 0, s.getWidth(), s.getHeight(), 0)) { + s.draw(batch); + } + } else { + member.draw(batch); + } + } + batch.end(); + members.end(); } - screen.members.end(); + viewports.end(); + screen.draw(batch); } - - batch.end(); - stage.act(delta); stage.draw(); - FlixelTween.getGlobalManager().update(delta); - Flixel.Signals.postRender.dispatch(new RenderSignalData(delta)); } @@ -170,7 +193,7 @@ public void onWindowUnfocused() { * Called when the user minimizes the game's window. * * @param iconified Whether the window is iconified (minimized) or not. This parameter is provided - * for compatibility with the window listener in the LWJGL3 (desktop) launcher. + * for compatibility with the window listener in the LWJGL3 (desktop) launcher. */ public void onWindowMinimized(boolean iconified) { isMinimized = iconified; @@ -182,18 +205,29 @@ public void onWindowMinimized(boolean iconified) { Flixel.info("Game window has been minimized."); } - /** Toggles fullscreen mode on or off, depending on the current state. */ - public void toggleFullscreen() { - boolean isFullscreen = Gdx.graphics.isFullscreen(); - if (isFullscreen) { - Gdx.graphics.setWindowedMode((int) windowSize.x, (int) windowSize.y); - Flixel.info("Exiting fullscreen mode."); - } else { + /** + * Sets fullscreen mode for the game's window. + * + * @param enabled If the game's window should be in fullscreen mode. + */ + public void setFullscreen(boolean enabled) { + if (enabled) { + if (!Flixel.isFullscreen()) { + windowSize.set(Gdx.graphics.getWidth(), Gdx.graphics.getHeight()); + } Gdx.graphics.setFullscreenMode(Gdx.graphics.getDisplayMode()); - Flixel.info("Entering fullscreen mode."); + Flixel.info("Entered fullscreen mode."); + } else { + Gdx.graphics.setWindowedMode((int) windowSize.x, (int) windowSize.y); + Flixel.info("Exited fullscreen mode."); } } + /** Toggles fullscreen mode on or off, depending on the current state. */ + public void toggleFullscreen() { + setFullscreen(!Flixel.isFullscreen()); + } + @Override public void dispose() { Flixel.warn("SHUTTING DOWN GAME AND DISPOSING ALL RESOURCES."); @@ -214,8 +248,6 @@ public void dispose() { Flixel.getSoundsGroup().dispose(); Flixel.getAudioEngine().dispose(); - Flixel.info("Disposing and shutting down scripts..."); - Flixel.Signals.postGameClose.dispatch(); } @@ -226,7 +258,7 @@ protected void configureCrashHandler() { Thread.setDefaultUncaughtExceptionHandler((thread, throwable) -> { String logs = FlixelRuntimeUtil.getFullExceptionMessage(throwable); String msg = "There was an uncaught exception on thread \"" + thread.getName() + "\"!\n" + logs; - Flixel.error(FlixelConstants.System.LOG_TAG, msg); + Flixel.error(msg); FlixelRuntimeUtil.showErrorAlert("Uncaught Exception", msg); dispose(); // Only use Gdx.app.exit() on non-iOS platforms to avoid App Store guideline violations! @@ -252,12 +284,26 @@ public Stage getStage() { return stage; } - public FitViewport getViewport() { - return viewport; + public FlixelViewport getViewport() { + Vector2 windowSize = Flixel.getWindowSize(); + if (viewports == null) { + Flixel.warn("Viewport list is null. Resigning with fresh array..."); + viewports = new SnapshotArray<>(); + } + if (viewports.isEmpty()) { + Flixel.warn("Viewport list is empty. Adding new fresh default viewport..."); + viewports.add(new FlixelViewport((int) windowSize.x, (int) windowSize.y)); + } + return viewports.first(); } - public OrthographicCamera getCamera() { - return camera; + public void resetViewports() { + viewports.clear(); + viewports.add(new FlixelViewport((int) windowSize.x, (int) windowSize.y)); + } + + public SnapshotArray getViewports() { + return viewports; } public SpriteBatch getBatch() { @@ -271,4 +317,10 @@ public Texture getBgTexture() { public boolean isMinimized() { return isMinimized; } + + public void setWindowSize(Vector2 windowSize) { + this.windowSize = windowSize; + Gdx.graphics.setWindowedMode((int) windowSize.x, (int) windowSize.y); + Flixel.info("Set window size. (WIDTH=" + windowSize.x + ", HEIGHT=" + windowSize.y + ")"); + } } diff --git a/flixelgdx/src/main/java/me/stringdotjar/flixelgdx/graphics/sprite/FlixelObject.java b/flixelgdx/src/main/java/me/stringdotjar/flixelgdx/graphics/FlixelObject.java similarity index 67% rename from flixelgdx/src/main/java/me/stringdotjar/flixelgdx/graphics/sprite/FlixelObject.java rename to flixelgdx/src/main/java/me/stringdotjar/flixelgdx/graphics/FlixelObject.java index 6ebd5c2..489ba9d 100644 --- a/flixelgdx/src/main/java/me/stringdotjar/flixelgdx/graphics/sprite/FlixelObject.java +++ b/flixelgdx/src/main/java/me/stringdotjar/flixelgdx/graphics/FlixelObject.java @@ -1,10 +1,10 @@ -package me.stringdotjar.flixelgdx.graphics.sprite; +package me.stringdotjar.flixelgdx.graphics; 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); + void destroy(); } diff --git a/flixelgdx/src/main/java/me/stringdotjar/flixelgdx/graphics/FlixelScreen.java b/flixelgdx/src/main/java/me/stringdotjar/flixelgdx/graphics/FlixelScreen.java new file mode 100644 index 0000000..6957ec6 --- /dev/null +++ b/flixelgdx/src/main/java/me/stringdotjar/flixelgdx/graphics/FlixelScreen.java @@ -0,0 +1,96 @@ +package me.stringdotjar.flixelgdx.graphics; + +import com.badlogic.gdx.Screen; +import com.badlogic.gdx.graphics.Color; +import com.badlogic.gdx.graphics.g2d.Batch; +import com.badlogic.gdx.utils.SnapshotArray; +import me.stringdotjar.flixelgdx.group.FlixelGroup; + +/** + * Base class for creating a better screen display with more functionality than the default {@link + * com.badlogic.gdx.Screen} interface. + */ +public abstract class FlixelScreen extends FlixelGroup implements Screen { + + /** Should {@code this} screen update its logic even when a substate is currently opened? */ + public boolean persistentUpdate = false; + + /** Should {@code this} screen draw its members even when a substate is currently opened? */ + public boolean persistentDraw = true; + + /** The background color of {@code this} current screen. */ + protected Color bgColor; + + public FlixelScreen() { + members = new SnapshotArray<>(FlixelObject.class); + } + + @Override + public final void show() {} + + @Override + public final void render(float delta) {} + + /** + * Called when the screen is first created. This is where you want to assign your + * sprites and setup everything your screen uses! + */ + public void create() {} + + /** + * Updates the logic of {@code this} screen. + * + * @param delta The amount of time that occurred since the last frame. + */ + public void update(float delta) { + if (!persistentUpdate) { + return; + } + + forEachMember(object -> { + object.update(delta); + }); + } + + /** + * Draws its members onto the screen. + * + * @param batch The batch that's used to draw the + */ + public void draw(Batch batch) { + if (!persistentDraw) { + return; + } + } + + @Override + public void resize(int width, int height) {} + + @Override + public void pause() {} + + @Override + public void resume() {} + + @Override + public void hide() {} + + @Override + public void dispose() {} + + /** + * Adds a new sprite to {@code this} screen. If it is {@code null}, it will not be added and + * simply ignored. + * + * @param object The sprite to add to the screen. + */ + public void add(FlixelObject object) { + if (object != null) { + members.add(object); + } + } + + public Color getBgColor() { + return (bgColor != null) ? bgColor : Color.BLACK; + } +} diff --git a/flixelgdx/src/main/java/me/stringdotjar/flixelgdx/graphics/FlixelViewport.java b/flixelgdx/src/main/java/me/stringdotjar/flixelgdx/graphics/FlixelViewport.java new file mode 100644 index 0000000..be9b225 --- /dev/null +++ b/flixelgdx/src/main/java/me/stringdotjar/flixelgdx/graphics/FlixelViewport.java @@ -0,0 +1,22 @@ +package me.stringdotjar.flixelgdx.graphics; + +import com.badlogic.gdx.graphics.Camera; +import com.badlogic.gdx.graphics.OrthographicCamera; +import com.badlogic.gdx.utils.viewport.FitViewport; + +import static me.stringdotjar.flixelgdx.Flixel.getWindowSize; + +public class FlixelViewport extends FitViewport { + + public FlixelViewport() { + this((int)getWindowSize().x, (int)getWindowSize().y, new OrthographicCamera(getWindowSize().x, getWindowSize().y)); + } + + public FlixelViewport(int width, int height) { + this(width, height, new OrthographicCamera(width, height)); + } + + public FlixelViewport(int width, int height, Camera camera) { + super(width, height, camera); + } +} diff --git a/flixelgdx/src/main/java/me/stringdotjar/flixelgdx/graphics/screen/FlixelScreen.java b/flixelgdx/src/main/java/me/stringdotjar/flixelgdx/graphics/screen/FlixelScreen.java deleted file mode 100644 index 8f00693..0000000 --- a/flixelgdx/src/main/java/me/stringdotjar/flixelgdx/graphics/screen/FlixelScreen.java +++ /dev/null @@ -1,56 +0,0 @@ -package me.stringdotjar.flixelgdx.graphics.screen; - -import com.badlogic.gdx.Screen; -import com.badlogic.gdx.graphics.Color; -import com.badlogic.gdx.utils.SnapshotArray; -import me.stringdotjar.flixelgdx.graphics.sprite.FlixelObject; - -/** - * Base class for creating a better screen display with more functionality than the default {@link - * com.badlogic.gdx.Screen} interface. - */ -public abstract class FlixelScreen implements Screen { - - /** The background color of {@code this} current screen. */ - protected Color bgColor; - - /** All display objects that are shown in {@code this} screen. */ - public final SnapshotArray members = new SnapshotArray<>(FlixelObject.class); - - @Override - public void show() {} - - @Override - public void render(float delta) {} - - @Override - public void resize(int width, int height) {} - - @Override - public void pause() {} - - @Override - public void resume() {} - - @Override - public void hide() {} - - @Override - public void dispose() {} - - /** - * Adds a new sprite to {@code this} screen. If it is {@code null}, it will not be added and - * simply ignored. - * - * @param object The sprite to add to the screen. - */ - public void add(FlixelObject object) { - if (object != null) { - members.add(object); - } - } - - public Color getBgColor() { - return (bgColor != null) ? bgColor : Color.BLACK; - } -} diff --git a/flixelgdx/src/main/java/me/stringdotjar/flixelgdx/graphics/sprite/FlixelSprite.java b/flixelgdx/src/main/java/me/stringdotjar/flixelgdx/graphics/sprite/FlixelSprite.java index ca82924..30b5946 100644 --- a/flixelgdx/src/main/java/me/stringdotjar/flixelgdx/graphics/sprite/FlixelSprite.java +++ b/flixelgdx/src/main/java/me/stringdotjar/flixelgdx/graphics/sprite/FlixelSprite.java @@ -5,13 +5,15 @@ 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; import com.badlogic.gdx.utils.Array; import com.badlogic.gdx.utils.Pool; import com.badlogic.gdx.utils.XmlReader; +import me.stringdotjar.flixelgdx.Flixel; +import me.stringdotjar.flixelgdx.graphics.FlixelObject; +import me.stringdotjar.flixelgdx.graphics.FlixelViewport; import java.util.Comparator; import java.util.HashMap; @@ -30,6 +32,9 @@ public class FlixelSprite extends Sprite implements FlixelObject, Pool.Poolable /** The hitbox used for collision detection and angling. */ protected Rectangle hitbox; + /** The viewports that {@code this} sprite is projected onto. */ + protected FlixelViewport[] viewports; + /** The atlas regions used in this sprite (used for animations). */ protected Array atlasRegions; @@ -43,10 +48,10 @@ public class FlixelSprite extends Sprite implements FlixelObject, Pool.Poolable protected float stateTime = 0; /** The name of the current animation playing. */ - protected String currentAnim = ""; + private String currentAnim = ""; /** Is {@code this} sprites current animation looping indefinitely? */ - protected boolean looping = true; + private boolean looping = true; /** * Where all the image frames are stored. This is also where the main image is stored when using @@ -56,6 +61,7 @@ public class FlixelSprite extends Sprite implements FlixelObject, Pool.Poolable public FlixelSprite() { animations = new HashMap<>(); + viewports = new FlixelViewport[]{Flixel.getViewport()}; } /** @@ -86,7 +92,7 @@ public FlixelSprite loadGraphic(FileHandle path) { /** * Load's a texture and automatically resizes the size of {@code this} sprite. * - * @param path The directory of the {@code .png} to load onto {@code this} sprite. + * @param path The directory of the {@code .png} to load onto {@code this} sprite. * @param frameWidth How wide the sprite should be. * @return {@code this} sprite for chaining. */ @@ -98,8 +104,8 @@ public FlixelSprite loadGraphic(FileHandle path, int frameWidth) { /** * Load's a texture and automatically resizes the size of {@code this} sprite. * - * @param path The directory of the {@code .png} to load onto {@code this} sprite. - * @param frameWidth How wide the sprite should be. + * @param path The directory of the {@code .png} to load onto {@code this} sprite. + * @param frameWidth How wide the sprite should be. * @param frameHeight How tall the sprite should be. * @return {@code this} sprite for chaining. */ @@ -120,9 +126,9 @@ public FlixelSprite loadGraphic(Texture texture, int frameWidth, int frameHeight * Loads an {@code .xml} spritesheet with {@code SubTexture} data inside of it. * * @param texture The path to the {@code .png} texture file for slicing and extracting the - * different frames from. + * different frames from. * @param xmlFile The path to the {@code .xml} file which contains the data for each subtexture of - * the sparrow atlas. + * the sparrow atlas. * @return {@code this} sprite for chaining. */ public FlixelSprite loadSparrowFrames(FileHandle texture, FileHandle xmlFile) { @@ -133,9 +139,9 @@ public FlixelSprite loadSparrowFrames(FileHandle texture, FileHandle xmlFile) { * Loads an {@code .xml} spritesheet with {@code SubTexture} data inside of it. * * @param texture The {@code .png} texture file for slicing and extracting the different frames - * from. + * from. * @param xmlFile The {@link XmlReader.Element} data which contains the data for each subtexture - * of the sparrow atlas. + * of the sparrow atlas. * @return {@code this} sprite for chaining. */ public FlixelSprite loadSparrowFrames(Texture texture, XmlReader.Element xmlFile) { @@ -189,10 +195,10 @@ public FlixelSprite loadSparrowFrames(Texture texture, XmlReader.Element xmlFile /** * Adds an animation by looking for sub textures that start with the prefix passed down. * - * @param name The name of the animation (e.g., "confirm"). - * @param prefix The prefix in the {@code .xml} file (e.g., "left confirm"). + * @param name The name of the animation (e.g., "confirm"). + * @param prefix The prefix in the {@code .xml} file (e.g., "left confirm"). * @param frameRate How fast the animation should play in frames-per-second. Standard is 24. - * @param loop Should the new animation loop indefinitely? + * @param loop Should the new animation loop indefinitely? */ public void addAnimationByPrefix(String name, String prefix, int frameRate, boolean loop) { Array frames = new Array<>(); @@ -209,17 +215,17 @@ public void addAnimationByPrefix(String name, String prefix, int frameRate, bool animations.put( name, - new Animation<>( - 1f / frameRate, frames, loop ? Animation.PlayMode.LOOP : Animation.PlayMode.NORMAL)); + new Animation<>(1f / frameRate, frames, loop ? Animation.PlayMode.LOOP : Animation.PlayMode.NORMAL) + ); } } /** * Adds a new animation to the animations list, if it doesn't exist already. * - * @param name The name of the animation. This is what you'll use every time you use {@code - * playAnimation()}. - * @param frameIndices An array of integers used for animation frame indices. + * @param name The name of the animation. This is what you'll use every time you use {@code + * playAnimation()}. + * @param frameIndices An array of integers used for animation frame indices. * @param frameDuration How long each frame lasts for in seconds. */ public void addAnimation(String name, int[] frameIndices, float frameDuration) { @@ -258,8 +264,8 @@ public void playAnimation(String name, boolean loop) { /** * Plays an animation {@code this} sprite has, if it exists. * - * @param name The name of the animation to play. - * @param loop Should this animation loop indefinitely? + * @param name The name of the animation to play. + * @param loop Should this animation loop indefinitely? * @param forceRestart Should the animation automatically restart regardless if its playing? */ public void playAnimation(String name, boolean loop, boolean forceRestart) { @@ -302,6 +308,11 @@ public void draw(Batch batch) { getRotation()); } + @Override + public void destroy() { + reset(); + } + public boolean isAnimationFinished() { Animation anim = animations.get(currentAnim); if (anim == null) return true; @@ -349,6 +360,10 @@ public Array getAtlasRegions() { return atlasRegions; } + public FlixelViewport[] getViewports() { + return viewports; + } + public TextureAtlas.AtlasRegion getCurrentFrame() { return currentFrame; } diff --git a/flixelgdx/src/main/java/me/stringdotjar/flixelgdx/group/FlixelGroup.java b/flixelgdx/src/main/java/me/stringdotjar/flixelgdx/group/FlixelGroup.java new file mode 100644 index 0000000..40eadec --- /dev/null +++ b/flixelgdx/src/main/java/me/stringdotjar/flixelgdx/group/FlixelGroup.java @@ -0,0 +1,60 @@ +package me.stringdotjar.flixelgdx.group; + +import com.badlogic.gdx.utils.SnapshotArray; + +import java.util.function.Consumer; + +/** + * Base class for creating groups with a list of members inside of it. + */ +public abstract class FlixelGroup implements FlixelGroupable { + + /** + * The list of members that {@code this} group contains. + */ + protected SnapshotArray members; + + public FlixelGroup() { + members = new SnapshotArray<>(); + } + + @Override + public void add(T member) { + members.add(member); + } + + @Override + public void remove(T member) { + members.removeValue(member, true); + } + + @Override + public void clear() { + members.clear(); + } + + @Override + public void forEachMember(Consumer callback) { + for (T member : members.begin()) { + if (member == null) { + continue; + } + callback.accept(member); + } + } + + public void forEachMemberType(Class type, Consumer callback) { + T[] items = members.begin(); + for (int i = 0, n = members.size; i < n; i++) { + T member = items[i]; + if (type.isInstance(member)) { + callback.accept(type.cast(member)); + } + } + members.end(); + } + + public SnapshotArray getMembers() { + return members; + } +} diff --git a/flixelgdx/src/main/java/me/stringdotjar/flixelgdx/group/FlixelGroupable.java b/flixelgdx/src/main/java/me/stringdotjar/flixelgdx/group/FlixelGroupable.java new file mode 100644 index 0000000..c464452 --- /dev/null +++ b/flixelgdx/src/main/java/me/stringdotjar/flixelgdx/group/FlixelGroupable.java @@ -0,0 +1,13 @@ +package me.stringdotjar.flixelgdx.group; + +import java.util.function.Consumer; + +/** + * Interface for creating new groups with members inside of them. + */ +public interface FlixelGroupable { + void add(T member); + void remove(T member); + void clear(); + void forEachMember(Consumer callback); +} diff --git a/flixelgdx/src/main/java/me/stringdotjar/flixelgdx/input/FlixelKey.java b/flixelgdx/src/main/java/me/stringdotjar/flixelgdx/input/FlixelKey.java new file mode 100644 index 0000000..963a94b --- /dev/null +++ b/flixelgdx/src/main/java/me/stringdotjar/flixelgdx/input/FlixelKey.java @@ -0,0 +1,8 @@ +package me.stringdotjar.flixelgdx.input; + +import com.badlogic.gdx.Input; + +/** + * A simple extension of {@link Input.Keys} to simplify accessing key constants. + */ +public class FlixelKey extends Input.Keys {} diff --git a/flixelgdx/src/main/java/me/stringdotjar/flixelgdx/signal/FlixelSignalData.java b/flixelgdx/src/main/java/me/stringdotjar/flixelgdx/signal/FlixelSignalData.java index 84f010b..0da3e0d 100644 --- a/flixelgdx/src/main/java/me/stringdotjar/flixelgdx/signal/FlixelSignalData.java +++ b/flixelgdx/src/main/java/me/stringdotjar/flixelgdx/signal/FlixelSignalData.java @@ -1,7 +1,7 @@ package me.stringdotjar.flixelgdx.signal; import games.rednblack.miniaudio.MASound; -import me.stringdotjar.flixelgdx.graphics.screen.FlixelScreen; +import me.stringdotjar.flixelgdx.graphics.FlixelScreen; import me.stringdotjar.flixelgdx.Flixel; /** diff --git a/flixelgdx/src/main/java/me/stringdotjar/flixelgdx/util/FlixelConstants.java b/flixelgdx/src/main/java/me/stringdotjar/flixelgdx/util/FlixelConstants.java index 149dda7..3d4a1df 100644 --- a/flixelgdx/src/main/java/me/stringdotjar/flixelgdx/util/FlixelConstants.java +++ b/flixelgdx/src/main/java/me/stringdotjar/flixelgdx/util/FlixelConstants.java @@ -42,4 +42,6 @@ public static final class AsciiCodes { private AsciiCodes() {} } + + private FlixelConstants() {} } diff --git a/flixelgdx/src/main/java/me/stringdotjar/flixelgdx/util/FlixelReflectUtil.java b/flixelgdx/src/main/java/me/stringdotjar/flixelgdx/util/FlixelReflectUtil.java index 2c0ec5c..9fdc8b3 100644 --- a/flixelgdx/src/main/java/me/stringdotjar/flixelgdx/util/FlixelReflectUtil.java +++ b/flixelgdx/src/main/java/me/stringdotjar/flixelgdx/util/FlixelReflectUtil.java @@ -13,7 +13,9 @@ * Backend utility class for obtaining and manipulating fields on objects through the usage of Java * reflection. */ -public class FlixelReflectUtil { +public final class FlixelReflectUtil { + + private FlixelReflectUtil() {} /** * Checks if a field exists on a given object. diff --git a/funkin/src/main/java/me/stringdotjar/funkin/FunkinGame.java b/funkin/src/main/java/me/stringdotjar/funkin/FunkinGame.java index 9f424ae..62e2258 100644 --- a/funkin/src/main/java/me/stringdotjar/funkin/FunkinGame.java +++ b/funkin/src/main/java/me/stringdotjar/funkin/FunkinGame.java @@ -4,7 +4,7 @@ import me.stringdotjar.flixelgdx.Flixel; import me.stringdotjar.flixelgdx.FlixelGame; import me.stringdotjar.flixelgdx.backend.FlixelPaths; -import me.stringdotjar.flixelgdx.graphics.screen.FlixelScreen; +import me.stringdotjar.flixelgdx.graphics.FlixelScreen; import me.stringdotjar.polyverse.Polyverse; import me.stringdotjar.polyverse.script.type.Script; import me.stringdotjar.polyverse.script.type.SystemScript; @@ -40,6 +40,7 @@ public void render() { @Override public void dispose() { super.dispose(); + Flixel.info("Funkin", "Disposing scripts..."); Polyverse.forAllScripts(Script::onDispose); } diff --git a/funkin/src/main/java/me/stringdotjar/funkin/InitScreen.java b/funkin/src/main/java/me/stringdotjar/funkin/InitScreen.java index e90d619..a9ccf3f 100644 --- a/funkin/src/main/java/me/stringdotjar/funkin/InitScreen.java +++ b/funkin/src/main/java/me/stringdotjar/funkin/InitScreen.java @@ -1,14 +1,14 @@ package me.stringdotjar.funkin; -import me.stringdotjar.flixelgdx.graphics.screen.FlixelScreen; +import me.stringdotjar.flixelgdx.graphics.FlixelScreen; import me.stringdotjar.flixelgdx.Flixel; import me.stringdotjar.funkin.menus.TitleScreen; public class InitScreen extends FlixelScreen { @Override - public void show() { - super.show(); + public void create() { + super.create(); Flixel.setScreen(new TitleScreen()); } } diff --git a/funkin/src/main/java/me/stringdotjar/funkin/menus/TitleScreen.java b/funkin/src/main/java/me/stringdotjar/funkin/menus/TitleScreen.java index 99c78e2..79fab0a 100644 --- a/funkin/src/main/java/me/stringdotjar/funkin/menus/TitleScreen.java +++ b/funkin/src/main/java/me/stringdotjar/funkin/menus/TitleScreen.java @@ -1,11 +1,11 @@ package me.stringdotjar.funkin.menus; -import com.badlogic.gdx.Input; import games.rednblack.miniaudio.MASound; import me.stringdotjar.flixelgdx.Flixel; import me.stringdotjar.flixelgdx.backend.FlixelPaths; -import me.stringdotjar.flixelgdx.graphics.screen.FlixelScreen; +import me.stringdotjar.flixelgdx.graphics.FlixelScreen; import me.stringdotjar.flixelgdx.graphics.sprite.FlixelSprite; +import me.stringdotjar.flixelgdx.input.FlixelKey; import me.stringdotjar.flixelgdx.tween.FlixelEase; import me.stringdotjar.flixelgdx.tween.FlixelTween; import me.stringdotjar.flixelgdx.tween.settings.FlixelTweenSettings; @@ -19,8 +19,8 @@ public class TitleScreen extends FlixelScreen { private MASound tickleFight; @Override - public void show() { - super.show(); + public void create() { + super.create(); var t = FlixelPaths.sharedImageAsset("noteStrumline"); var xml = FlixelPaths.shared("images/noteStrumline.xml"); @@ -46,36 +46,36 @@ public void show() { } @Override - public void render(float elapsed) { - super.render(elapsed); + public void update(float elapsed) { + super.update(elapsed); float speed = 500 * elapsed; - if (Flixel.keyPressed(Input.Keys.W)) { + if (Flixel.keyPressed(FlixelKey.W)) { logo.changeY(speed); } - if (Flixel.keyPressed(Input.Keys.S)) { + if (Flixel.keyPressed(FlixelKey.S)) { logo.changeY(-speed); } - if (Flixel.keyPressed(Input.Keys.A)) { + if (Flixel.keyPressed(FlixelKey.A)) { logo.changeX(-speed); } - if (Flixel.keyPressed(Input.Keys.D)) { + if (Flixel.keyPressed(FlixelKey.D)) { logo.changeX(speed); } - if (Flixel.keyJustPressed(Input.Keys.SPACE)) { + if (Flixel.keyJustPressed(FlixelKey.SPACE)) { logo.playAnimation("test", true); } - if (Flixel.keyJustPressed(Input.Keys.T)) { + if (Flixel.keyJustPressed(FlixelKey.T)) { tween.start(); } - if (Flixel.keyJustPressed(Input.Keys.R)) { + if (Flixel.keyJustPressed(FlixelKey.R)) { tween.reset(); } - if (Flixel.keyJustPressed(Input.Keys.Y)) { + if (Flixel.keyJustPressed(FlixelKey.Y)) { if (tween.paused) { tween.resume(); } else { @@ -83,7 +83,7 @@ public void render(float elapsed) { } } - if (Flixel.keyJustPressed(Input.Keys.Z)) { + if (Flixel.keyJustPressed(FlixelKey.Z)) { tickleFight.play(); } }