diff --git a/res/img/gui1.png b/res/img/gui1.png new file mode 100644 index 0000000..950b24f Binary files /dev/null and b/res/img/gui1.png differ diff --git a/res/img/gui1.xcf b/res/img/gui1.xcf new file mode 100644 index 0000000..8cc075a Binary files /dev/null and b/res/img/gui1.xcf differ diff --git a/res/img/map.png b/res/img/map.png new file mode 100644 index 0000000..45f9358 Binary files /dev/null and b/res/img/map.png differ diff --git a/res/img/rogue_tiles.xcf b/res/img/rogue_tiles.xcf new file mode 100644 index 0000000..743fc90 Binary files /dev/null and b/res/img/rogue_tiles.xcf differ diff --git a/src/mightypork/gamecore/input/InputSystem.java b/src/mightypork/gamecore/input/InputSystem.java index c6260e7..220513e 100644 --- a/src/mightypork/gamecore/input/InputSystem.java +++ b/src/mightypork/gamecore/input/InputSystem.java @@ -158,7 +158,7 @@ public class InputSystem extends RootBusNode implements Updateable, KeyBinder { getEventBus().send(new MouseButtonEvent(pos.freeze(), button, down, wheeld)); } - moveSum.add(move); + moveSum.setTo(moveSum.add(move)); lastPos.setTo(pos); } diff --git a/src/mightypork/gamecore/render/Render.java b/src/mightypork/gamecore/render/Render.java index 30025e6..a632efb 100644 --- a/src/mightypork/gamecore/render/Render.java +++ b/src/mightypork/gamecore/render/Render.java @@ -5,6 +5,7 @@ import static org.lwjgl.opengl.GL11.*; import java.io.IOException; +import mightypork.gamecore.render.textures.FilterMode; import mightypork.gamecore.render.textures.TxQuad; import mightypork.util.constraints.rect.Rect; import mightypork.util.constraints.rect.caching.RectDigest; @@ -296,14 +297,14 @@ public class Render { * @param resourcePath * @return the loaded texture */ - public synchronized static Texture loadTexture(String resourcePath) + public synchronized static Texture loadTexture(String resourcePath, FilterMode filtering) { try { final String ext = FileUtils.getExtension(resourcePath).toUpperCase(); - final Texture texture = TextureLoader.getTexture(ext, ResourceLoader.getResourceAsStream(resourcePath)); + final Texture texture = TextureLoader.getTexture(ext, ResourceLoader.getResourceAsStream(resourcePath), false, filtering.num); if (texture == null) { Log.w("Texture " + resourcePath + " could not be loaded."); diff --git a/src/mightypork/gamecore/render/textures/DeferredTexture.java b/src/mightypork/gamecore/render/textures/DeferredTexture.java index bd8c9b1..0b108db 100644 --- a/src/mightypork/gamecore/render/textures/DeferredTexture.java +++ b/src/mightypork/gamecore/render/textures/DeferredTexture.java @@ -21,8 +21,7 @@ import org.newdawn.slick.opengl.Texture; public class DeferredTexture extends DeferredResource implements FilteredTexture { private Texture backingTexture; - private FilterMode filter_min = FilterMode.LINEAR; - private FilterMode filter_mag = FilterMode.NEAREST; + private FilterMode filter = FilterMode.NEAREST; private WrapMode wrap = WrapMode.CLAMP; @@ -49,7 +48,7 @@ public class DeferredTexture extends DeferredResource implements FilteredTexture @Override protected synchronized void loadResource(String path) { - backingTexture = Render.loadTexture(path); + backingTexture = Render.loadTexture(path, filter); } @@ -86,8 +85,8 @@ public class DeferredTexture extends DeferredResource implements FilteredTexture GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, wrap.num); GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, wrap.num); - GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, filter_min.num); - GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, filter_mag.num); + GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, filter.num); + GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, filter.num); bindRaw(); } @@ -200,10 +199,9 @@ public class DeferredTexture extends DeferredResource implements FilteredTexture @Override - public void setFilter(FilterMode filterMin, FilterMode filterMag) + public void setFilter(FilterMode filterMin) { - this.filter_min = filterMin; - this.filter_mag = filterMag; + this.filter = filterMin; } @@ -213,11 +211,4 @@ public class DeferredTexture extends DeferredResource implements FilteredTexture this.wrap = wrapping; } - - @Override - public void setFilter(FilterMode filter) - { - setFilter(filter, filter); - } - } diff --git a/src/mightypork/gamecore/render/textures/FilteredTexture.java b/src/mightypork/gamecore/render/textures/FilteredTexture.java index eef8d32..f9cad9d 100644 --- a/src/mightypork/gamecore/render/textures/FilteredTexture.java +++ b/src/mightypork/gamecore/render/textures/FilteredTexture.java @@ -11,17 +11,9 @@ import org.newdawn.slick.opengl.Texture; */ public interface FilteredTexture extends Texture { - /** - * Set filter for scaling - * - * @param filterMin downscale filter - * @param filterMag upscale filter - */ - void setFilter(FilterMode filterMin, FilterMode filterMag); - /** - * Set filter for scaling (both up and down) + * Set filter for scaling * * @param filter filter */ diff --git a/src/mightypork/gamecore/render/textures/TextureBank.java b/src/mightypork/gamecore/render/textures/TextureBank.java index bd8d31b..d220bce 100644 --- a/src/mightypork/gamecore/render/textures/TextureBank.java +++ b/src/mightypork/gamecore/render/textures/TextureBank.java @@ -54,14 +54,13 @@ public class TextureBank extends AppAdapter { * * @param key texture key * @param resourcePath texture resource path - * @param filter_min min filter (when rendered smaller) - * @param filter_mag mag filter (when rendered larger) + * @param filter filter * @param wrap texture wrapping */ - public void loadTexture(String key, String resourcePath, FilterMode filter_min, FilterMode filter_mag, WrapMode wrap) + public void loadTexture(String key, String resourcePath, FilterMode filter, WrapMode wrap) { final DeferredTexture texture = new DeferredTexture(resourcePath); - texture.setFilter(filter_min, filter_mag); + texture.setFilter(filter); texture.setWrap(wrap); loadTexture(key, texture); @@ -90,7 +89,7 @@ public class TextureBank extends AppAdapter { * Create a {@link TxQuad} in the last loaded texture * * @param quadKey quad key - * @param quad quad rectangle (absolute pixel coordinates) + * @param quad quad rectangle (0-1) */ public void makeQuad(String quadKey, Rect quad) { diff --git a/src/mightypork/rogue/App.java b/src/mightypork/rogue/App.java index 9e9747c..2408cbe 100644 --- a/src/mightypork/rogue/App.java +++ b/src/mightypork/rogue/App.java @@ -6,6 +6,7 @@ import java.util.Locale; import mightypork.gamecore.control.BaseApp; import mightypork.gamecore.control.GameLoop; +import mightypork.gamecore.control.events.ScreenRequestEvent; import mightypork.gamecore.gui.screens.ScreenRegistry; import mightypork.gamecore.input.InputSystem; import mightypork.gamecore.input.KeyStroke; @@ -14,12 +15,16 @@ import mightypork.gamecore.loading.AsyncResourceLoader; import mightypork.gamecore.render.DisplaySystem; import mightypork.rogue.events.ActionRequest; import mightypork.rogue.events.ActionRequest.RequestType; +import mightypork.rogue.screens.CrossfadeOverlay; +import mightypork.rogue.screens.CrossfadeRequest; import mightypork.rogue.screens.FpsOverlay; +import mightypork.rogue.screens.ingame.ScreenGame; import mightypork.rogue.screens.main_menu.ScreenMainMenu; import mightypork.rogue.screens.test_bouncyboxes.ScreenTestBouncy; import mightypork.rogue.screens.test_cat_sound.ScreenTestCat; import mightypork.rogue.screens.test_render.ScreenTestRender; import mightypork.util.control.eventbus.EventBus; +import mightypork.util.control.eventbus.events.Event; import mightypork.util.logging.Log; import mightypork.util.logging.writers.LogWriter; @@ -69,10 +74,12 @@ public class App extends BaseApp { screens.addScreen(new ScreenTestCat(this)); screens.addScreen(new ScreenTestRender(this)); screens.addScreen(new ScreenMainMenu(this)); + screens.addScreen(new ScreenGame(this)); screens.addOverlay(new FpsOverlay(this)); + screens.addOverlay(new CrossfadeOverlay(this)); - screens.showScreen("rogue.menu"); + screens.showScreen("main_menu"); } @@ -110,33 +117,22 @@ public class App extends BaseApp { @Override protected void initInputSystem(InputSystem input) { - // Go fullscreen - input.bindKey(new KeyStroke(Keys.F11), new Runnable() { - - @Override - public void run() - { - getEventBus().send(new ActionRequest(RequestType.FULLSCREEN)); - } - }); - - // Take screenshot - input.bindKey(new KeyStroke(Keys.F2), new Runnable() { - - @Override - public void run() - { - getEventBus().send(new ActionRequest(RequestType.SCREENSHOT)); - } - }); - - // Exit - input.bindKey(new KeyStroke(Keys.L_CONTROL, Keys.Q), new Runnable() { + // this will work only with reusable events (such as requests) + bindToKey(new ActionRequest(RequestType.FULLSCREEN), Keys.F11); + bindToKey(new ActionRequest(RequestType.SCREENSHOT), Keys.F2); + bindToKey(new ActionRequest(RequestType.SHUTDOWN), Keys.L_CONTROL, Keys.Q); + bindToKey(new CrossfadeRequest("main_menu"), Keys.L_CONTROL, Keys.M); + } + + + private void bindToKey(final Event event, int... keys) + { + getInput().bindKey(new KeyStroke(keys), new Runnable() { @Override public void run() { - getEventBus().send(new ActionRequest(RequestType.SHUTDOWN)); + getEventBus().send(event); } }); } diff --git a/src/mightypork/rogue/Res.java b/src/mightypork/rogue/Res.java index 8108783..2b443b7 100644 --- a/src/mightypork/rogue/Res.java +++ b/src/mightypork/rogue/Res.java @@ -15,6 +15,7 @@ import mightypork.gamecore.render.textures.FilterMode; import mightypork.gamecore.render.textures.TextureBank; import mightypork.gamecore.render.textures.TxQuad; import mightypork.gamecore.render.textures.WrapMode; +import mightypork.util.constraints.rect.Rect; import org.newdawn.slick.opengl.Texture; @@ -78,6 +79,27 @@ public class Res { texture.setWrap(WrapMode.CLAMP); textures.loadTexture("test.kitten", texture); + texture = new DeferredTexture("/res/img/gui1.png"); + texture.setFilter(FilterMode.NEAREST); + texture.setWrap(WrapMode.CLAMP); + textures.loadTexture("gui1", texture); + + final double p16 = 0.25D; + final double p8 = 0.125D; + + //@formatter:off + textures.makeQuad("item_frame", Rect.make(0, 0, p16, p16)); + textures.makeQuad("sword", Rect.make(p16, 0, p16, p16)); + textures.makeQuad("meat", Rect.make(p16*2, 0, p16, p16)); + + textures.makeQuad("heart_on", Rect.make(0, p16, p8, p8)); + textures.makeQuad("heart_off", Rect.make(p8, p16, p8, p8)); + + textures.makeQuad("xp_on", Rect.make(0, p16+p8, p8, p8)); + textures.makeQuad("xp_off", Rect.make(p8, p16+p8, p8, p8)); + + textures.makeQuad("panel", Rect.make(0, p16*4-p8/2, p16*4, p8/2)); + //@formatter:off } diff --git a/src/mightypork/rogue/screens/CrossfadeOverlay.java b/src/mightypork/rogue/screens/CrossfadeOverlay.java new file mode 100644 index 0000000..09137d8 --- /dev/null +++ b/src/mightypork/rogue/screens/CrossfadeOverlay.java @@ -0,0 +1,77 @@ +package mightypork.rogue.screens; + + +import mightypork.gamecore.control.AppAccess; +import mightypork.gamecore.control.events.ScreenRequestEvent; +import mightypork.gamecore.gui.components.painters.QuadPainter; +import mightypork.gamecore.gui.screens.Overlay; +import mightypork.util.constraints.num.mutable.NumAnimated; +import mightypork.util.control.timing.TimedTask; +import mightypork.util.math.Easing; +import mightypork.util.math.color.Color; + + +public class CrossfadeOverlay extends Overlay implements CrossfadeRequest.Listener { + + private static final double T_IN = 0.5; + private static final double T_OUT = 0.7; + + NumAnimated level = new NumAnimated(0); + + Color color = Color.dark(level); + String requestedScreenName; + + TimedTask tt = new TimedTask() { + + @Override + public void run() + { + if(requestedScreenName == null) shutdown(); + getEventBus().send(new ScreenRequestEvent(requestedScreenName)); + } + }; + + TimedTask tt2 = new TimedTask() { + + @Override + public void run() + { + level.setEasing(Easing.SINE_OUT); + level.fadeOut(T_OUT); + } + }; + + + public CrossfadeOverlay(AppAccess app) { + super(app); + + QuadPainter qp = new QuadPainter(color); + qp.setRect(root); + root.add(qp); + + updated.add(level); + updated.add(tt); + updated.add(tt2); + } + + + @Override + public int getPriority() + { + return Integer.MAX_VALUE - 1; // let FPS go on top + } + + + @Override + public void goToScreen(String screen) + { + tt.start(T_IN); + tt2.start(T_IN); + + level.setEasing(Easing.SINE_IN); + level.fadeIn(T_IN); + + requestedScreenName = screen; + } + +} diff --git a/src/mightypork/rogue/screens/CrossfadeRequest.java b/src/mightypork/rogue/screens/CrossfadeRequest.java new file mode 100644 index 0000000..9e13f36 --- /dev/null +++ b/src/mightypork/rogue/screens/CrossfadeRequest.java @@ -0,0 +1,35 @@ +package mightypork.rogue.screens; + + +import mightypork.util.control.eventbus.events.Event; + + +/** + * @author MightyPork + */ +public class CrossfadeRequest implements Event { + + private String screen; + + + /** + * @param screen screen key to show. Null = exit the app. + */ + public CrossfadeRequest(String screen) { + super(); + this.screen = screen; + } + + public interface Listener { + + void goToScreen(String screen); + } + + + @Override + public void handleBy(Listener handler) + { + handler.goToScreen(screen); + } + +} diff --git a/src/mightypork/rogue/screens/ingame/GameGui.java b/src/mightypork/rogue/screens/ingame/GameGui.java new file mode 100644 index 0000000..0ee95d3 --- /dev/null +++ b/src/mightypork/rogue/screens/ingame/GameGui.java @@ -0,0 +1,62 @@ +package mightypork.rogue.screens.ingame; + + +import mightypork.gamecore.gui.AlignX; +import mightypork.gamecore.gui.components.Component; +import mightypork.gamecore.gui.components.layout.HorizontalFixedFlowLayout; +import mightypork.gamecore.gui.components.painters.ImagePainter; +import mightypork.gamecore.gui.components.painters.QuadPainter; +import mightypork.gamecore.gui.screens.Screen; +import mightypork.gamecore.gui.screens.ScreenLayer; +import mightypork.rogue.Res; +import mightypork.util.constraints.num.Num; +import mightypork.util.constraints.rect.Rect; +import mightypork.util.math.color.PAL16; + + +public class GameGui extends ScreenLayer { + + public GameGui(Screen screen) { + super(screen); + + Num h = root.height(); + Num w = root.width(); + Num minWH = w.min(h).max(700); // avoid too small shrinking + + Component qp = new QuadPainter(PAL16.VOID); + qp.setRect(root); + root.add(qp); + + ImagePainter nav = new ImagePainter(Res.getTxQuad("panel")); + nav.setRect(root.bottomEdge().growUp(minWH.perc(7))); + root.add(nav); + + HorizontalFixedFlowLayout itemSlots = new HorizontalFixedFlowLayout(root, nav.height().mul(1.8), AlignX.LEFT); + itemSlots.setRect(nav.growUp(nav.height()).move(nav.height().mul(0.2), nav.height().mul(-0.2))); + root.add(itemSlots); + + itemSlots.add(new NavItemSlot(Res.getTxQuad("meat"))); + itemSlots.add(new NavItemSlot(Res.getTxQuad("sword"))); + + Rect shrunk = root.shrink(minWH.perc(3)); + Num displays_height = minWH.perc(6); + + HeartBar hearts = new HeartBar(6, 3, Res.getTxQuad("heart_on"), Res.getTxQuad("heart_off"), AlignX.LEFT); + Rect hearts_box = shrunk.topLeft().startRect().growDown(displays_height); + hearts.setRect(hearts_box); + root.add(hearts); + + HeartBar experience = new HeartBar(6, 2, Res.getTxQuad("xp_on"), Res.getTxQuad("xp_off"), AlignX.RIGHT); + Rect xp_box = shrunk.topRight().startRect().growDown(displays_height); + experience.setRect(xp_box); + root.add(experience); + } + + + @Override + public int getPriority() + { + return 100; + } + +} diff --git a/src/mightypork/rogue/screens/ingame/HeartBar.java b/src/mightypork/rogue/screens/ingame/HeartBar.java new file mode 100644 index 0000000..bd94b96 --- /dev/null +++ b/src/mightypork/rogue/screens/ingame/HeartBar.java @@ -0,0 +1,66 @@ +package mightypork.rogue.screens.ingame; + + +import mightypork.gamecore.gui.AlignX; +import mightypork.gamecore.gui.components.VisualComponent; +import mightypork.gamecore.render.Render; +import mightypork.gamecore.render.textures.TxQuad; +import mightypork.util.constraints.num.Num; +import mightypork.util.constraints.num.mutable.NumVar; +import mightypork.util.constraints.rect.Rect; + + +public class HeartBar extends VisualComponent { + + private TxQuad img_on; + private TxQuad img_off; + private int total; + private int active; + + NumVar index = new NumVar(0); + Rect heart; + + + /** + * @param total + * @param active + * @param img_on + * @param img_off + * @param align + */ + public HeartBar(int total, int active, TxQuad img_on, TxQuad img_off, AlignX align) { + super(); + this.total = total; + this.active = active; + this.img_on = img_on; + this.img_off = img_off; + + Num h = height(); + Num w = width(); + + switch (align) { + case LEFT: + heart = leftEdge().growRight(h).moveX(index.mul(h)); + break; + case RIGHT: + heart = rightEdge().growLeft(h).moveX(h.mul(-total+1).add(index.mul(h))); + break; + case CENTER: + heart = leftEdge().moveX(w.half().add(h.mul(-total/2D))).growRight(h).moveX(index.mul(h)); + break; + } + + } + + + @Override + protected void renderComponent() + { + for (int i = 0; i < total; i++) { + index.setTo(i); + + Render.quadTextured(heart, (i < active ? img_on : img_off)); + } + } + +} diff --git a/src/mightypork/rogue/screens/ingame/NavItemSlot.java b/src/mightypork/rogue/screens/ingame/NavItemSlot.java new file mode 100644 index 0000000..bbddf25 --- /dev/null +++ b/src/mightypork/rogue/screens/ingame/NavItemSlot.java @@ -0,0 +1,88 @@ +package mightypork.rogue.screens.ingame; + + +import mightypork.gamecore.gui.components.ClickableComponent; +import mightypork.gamecore.gui.components.InputComponent; +import mightypork.gamecore.render.Render; +import mightypork.gamecore.render.textures.TxQuad; +import mightypork.rogue.Res; +import mightypork.util.constraints.num.Num; +import mightypork.util.constraints.num.mutable.NumAnimated; +import mightypork.util.constraints.rect.Rect; +import mightypork.util.constraints.rect.caching.RectCache; +import mightypork.util.constraints.vect.Vect; +import mightypork.util.control.timing.Updateable; +import mightypork.util.math.Easing; +import mightypork.gamecore.control.events.MouseMotionEvent; + + +public class NavItemSlot extends ClickableComponent implements MouseMotionEvent.Listener, Updateable { + + private TxQuad image; + private TxQuad frame; + private RectCache paintBox; + private NumAnimated yOffset; + private boolean wasInside = false; + + + public NavItemSlot(TxQuad image) { + this.image = image; + this.frame = Res.getTxQuad("item_frame"); + + Rect ref = shrink(height().perc(8)); + yOffset = new NumAnimated(0, Easing.LINEAR); + yOffset.setDefaultDuration(0.05); + + Num h = ref.width().min(ref.height()); + this.paintBox = ref.bottomLeft().startRect().grow(Num.ZERO, h, h, Num.ZERO).moveY(yOffset.mul(h.perc(-5))).cached(); + } + + + @Override + protected void renderComponent() + { + Render.quadTextured(paintBox, frame); + + Render.pushMatrix(); + Render.translateXY(paintBox.center()); + Render.scaleXY(0.7); + Render.rotateZ(45); + Render.quadTextured(Rect.make(paintBox.height()).centerTo(Vect.ZERO), image); + Render.popMatrix(); + } + + + @Override + public void updateLayout() + { + paintBox.poll(); + } + + + @Override + public void receive(MouseMotionEvent event) + { + if (event.getPos().isInside(this) != wasInside) { + if (wasInside) { + // left + yOffset.fadeOut(); + } else { + // entered + yOffset.fadeIn(); + } + + wasInside = !wasInside; + } + } + + + @Override + public void update(double delta) + { + if (yOffset.isInProgress()) { + yOffset.update(delta); + paintBox.poll(); + } + } + +} diff --git a/src/mightypork/rogue/screens/ingame/ScreenGame.java b/src/mightypork/rogue/screens/ingame/ScreenGame.java new file mode 100644 index 0000000..3acb8f1 --- /dev/null +++ b/src/mightypork/rogue/screens/ingame/ScreenGame.java @@ -0,0 +1,21 @@ +package mightypork.rogue.screens.ingame; + +import mightypork.gamecore.control.AppAccess; +import mightypork.gamecore.gui.screens.LayeredScreen; + + +public class ScreenGame extends LayeredScreen { + + public ScreenGame(AppAccess app) { + super(app); + + addLayer(new GameGui(this)); + } + + @Override + public String getName() + { + return "game_screen"; + } + +} diff --git a/src/mightypork/rogue/screens/main_menu/MenuLayer.java b/src/mightypork/rogue/screens/main_menu/MenuLayer.java index 7772a5f..f813825 100644 --- a/src/mightypork/rogue/screens/main_menu/MenuLayer.java +++ b/src/mightypork/rogue/screens/main_menu/MenuLayer.java @@ -11,6 +11,7 @@ import mightypork.gamecore.gui.screens.ScreenLayer; import mightypork.rogue.Res; import mightypork.rogue.events.ActionRequest; import mightypork.rogue.events.ActionRequest.RequestType; +import mightypork.rogue.screens.CrossfadeRequest; import mightypork.util.constraints.num.Num; import mightypork.util.constraints.rect.Rect; import mightypork.util.control.Action; @@ -28,7 +29,7 @@ class MenuLayer extends ScreenLayer { private void init() { - final Rect menuBox = root.shrink(Num.ZERO, root.height().mul(0.18)).moveY(root.height().mul(-0.03)); + final Rect menuBox = root.shrink(Num.ZERO, root.height().mul(0.18)); //.moveY(root.height().mul(-0.03)) final GridLayout layout = new GridLayout(root, menuBox, 17, 1); layout.enableCaching(true); @@ -40,25 +41,39 @@ class MenuLayer extends ScreenLayer { root.add(layout); TextPainter tp; - MenuButton b1, b2, b3, b4; - tp = new TextPainter(Res.getFont("main_menu_title"), AlignX.CENTER, PAL16.SLIMEGREEN, "Rogue!"); + MenuButton b0, b1, b2, b3, b4; + tp = new TextPainter(Res.getFont("main_menu_title"), AlignX.CENTER, PAL16.ZORNSKIN, "Rogue!"); + b0 = new MenuButton("Ingame", PAL16.SLIMEGREEN); b1 = new MenuButton("Gradientz", PAL16.BLAZE); b2 = new MenuButton("Bouncy Cubes", PAL16.NEWPOOP); b3 = new MenuButton("Flying Cat", PAL16.PIGMEAT); b4 = new MenuButton("Bye!", PAL16.BLOODRED); - layout.put(tp, 1, 0, 4, 1); - layout.put(b1, 6, 0, 2, 1); - layout.put(b2, 8, 0, 2, 1); - layout.put(b3, 10, 0, 2, 1); - layout.put(b4, 13, 0, 2, 1); + int r=0; + + layout.put(tp, r, 0, 4, 1); r += 5; + layout.put(b0, r, 0, 2, 1); r += 3; + layout.put(b1, r, 0, 2, 1); r += 2; + layout.put(b2, r, 0, 2, 1); r += 2; + layout.put(b3, r, 0, 2, 1); r += 3; + layout.put(b4, r, 0, 2, 1); + root.add(layout); + b0.setAction(new Action() { + + @Override + protected void execute() + { + getEventBus().send(new CrossfadeRequest("game_screen")); + } + }); + b1.setAction(new Action() { @Override protected void execute() { - getEventBus().send(new ScreenRequestEvent("test.render")); + getEventBus().send(new CrossfadeRequest("test.render")); } }); @@ -67,7 +82,7 @@ class MenuLayer extends ScreenLayer { @Override protected void execute() { - getEventBus().send(new ScreenRequestEvent("test.bouncy")); + getEventBus().send(new CrossfadeRequest("test.bouncy")); } }); @@ -76,7 +91,7 @@ class MenuLayer extends ScreenLayer { @Override protected void execute() { - getEventBus().send(new ScreenRequestEvent("test.cat")); + getEventBus().send(new CrossfadeRequest("test.cat")); } }); @@ -86,7 +101,7 @@ class MenuLayer extends ScreenLayer { @Override protected void execute() { - getEventBus().send(new ActionRequest(RequestType.SHUTDOWN)); + getEventBus().send(new CrossfadeRequest(null)); // null -> fade and halt } }); } diff --git a/src/mightypork/rogue/screens/main_menu/ScreenMainMenu.java b/src/mightypork/rogue/screens/main_menu/ScreenMainMenu.java index f11a514..a185908 100644 --- a/src/mightypork/rogue/screens/main_menu/ScreenMainMenu.java +++ b/src/mightypork/rogue/screens/main_menu/ScreenMainMenu.java @@ -17,7 +17,7 @@ public class ScreenMainMenu extends LayeredScreen { @Override public String getName() { - return "rogue.menu"; + return "main_menu"; } } diff --git a/src/mightypork/rogue/screens/test_bouncyboxes/LayerBouncyBoxes.java b/src/mightypork/rogue/screens/test_bouncyboxes/LayerBouncyBoxes.java index 28034a6..1337f4d 100644 --- a/src/mightypork/rogue/screens/test_bouncyboxes/LayerBouncyBoxes.java +++ b/src/mightypork/rogue/screens/test_bouncyboxes/LayerBouncyBoxes.java @@ -55,7 +55,7 @@ public class LayerBouncyBoxes extends ScreenLayer { } final TextPainter tp = new TextPainter(Res.getFont("default"), AlignX.LEFT, Color.WHITE); - tp.setText("Press \"C\" for \"Cat\" screen."); + tp.setText("Press left & right to move."); final Num shadowOffset = tp.height().div(16); tp.setShadow(Color.RED, Vect.make(shadowOffset, shadowOffset)); diff --git a/src/mightypork/util/constraints/num/mutable/NumAnimated.java b/src/mightypork/util/constraints/num/mutable/NumAnimated.java index d1afcb7..2ac3a56 100644 --- a/src/mightypork/util/constraints/num/mutable/NumAnimated.java +++ b/src/mightypork/util/constraints/num/mutable/NumAnimated.java @@ -8,7 +8,9 @@ import mightypork.util.math.Easing; /** - * Double which supports delta timing + * Double which supports delta timing.
+ * When both in and out easings are set differently, then they'll be used for + * fade-in and fade-out respectively. Otherwise both use the same. * * @author MightyPork */ @@ -30,7 +32,9 @@ public class NumAnimated extends NumMutable implements Updateable, Pauseable { protected boolean paused = false; /** Easing fn */ - protected Easing easing = Easing.LINEAR; + protected Easing easingCurrent = Easing.LINEAR; + protected Easing easingOut = Easing.LINEAR; + protected Easing easingIn = Easing.LINEAR; /** Default duration (seconds) */ private double defaultDuration = 0; @@ -56,7 +60,19 @@ public class NumAnimated extends NumMutable implements Updateable, Pauseable { this(value); setEasing(easing); } + + /** + * Create animator with easing + * + * @param value initial value + * @param easingIn easing function (fade in) + * @param easingOut easing function (fade out) + */ + public NumAnimated(double value, Easing easingIn, Easing easingOut) { + this(value); + setEasing(easingIn, easingOut); + } /** * Create as copy of another @@ -69,20 +85,23 @@ public class NumAnimated extends NumMutable implements Updateable, Pauseable { /** - * @return easing function + * @param easing easing function */ - public Easing getEasing() + public void setEasing(Easing easing) { - return easing; + this.easingCurrent = this.easingIn = this.easingOut = easing; } /** - * @param easing easing function + * @param easingIn easing for fade in + * @param easingOut easing for fade out */ - public void setEasing(Easing easing) + public void setEasing(Easing easingIn, Easing easingOut) { - this.easing = easing; + this.easingIn = easingIn; + this.easingOut = easingOut; + this.easingCurrent = easingIn; } @@ -153,7 +172,7 @@ public class NumAnimated extends NumMutable implements Updateable, Pauseable { public double value() { if (duration == 0) return to; - return Calc.interpolate(from, to, (elapsedTime / duration), easing); + return Calc.interpolate(from, to, (elapsedTime / duration), easingCurrent); } @@ -220,7 +239,9 @@ public class NumAnimated extends NumMutable implements Updateable, Pauseable { this.duration = other.duration; this.elapsedTime = other.elapsedTime; this.paused = other.paused; - this.easing = other.easing; + this.easingCurrent = other.easingCurrent; + this.easingIn = other.easingIn; + this.easingOut = other.easingOut; this.defaultDuration = other.defaultDuration; } @@ -293,6 +314,7 @@ public class NumAnimated extends NumMutable implements Updateable, Pauseable { */ public void fadeIn(double time) { + easingCurrent = easingIn; animate(0, 1, time); } @@ -304,10 +326,31 @@ public class NumAnimated extends NumMutable implements Updateable, Pauseable { */ public void fadeOut(double time) { + easingCurrent = easingOut; animate(1, 0, time); } + /** + * Animate 0 to 1 with default duration + */ + public void fadeIn() + { + easingCurrent = easingIn; + animate(0, 1, defaultDuration); + } + + + /** + * Animate 1 to 0 with default duration + */ + public void fadeOut() + { + easingCurrent = easingOut; + animate(1, 0, defaultDuration); + } + + /** * Make a copy * diff --git a/src/mightypork/util/constraints/num/mutable/NumAnimatedDeg.java b/src/mightypork/util/constraints/num/mutable/NumAnimatedDeg.java index 89fbbee..8e144d3 100644 --- a/src/mightypork/util/constraints/num/mutable/NumAnimatedDeg.java +++ b/src/mightypork/util/constraints/num/mutable/NumAnimatedDeg.java @@ -32,7 +32,7 @@ public class NumAnimatedDeg extends NumAnimated { public double value() { if (duration == 0) return Deg.norm(to); - return Calc.interpolateDeg(from, to, (elapsedTime / duration), easing); + return Calc.interpolateDeg(from, to, (elapsedTime / duration), easingCurrent); } diff --git a/src/mightypork/util/constraints/num/mutable/NumAnimatedRad.java b/src/mightypork/util/constraints/num/mutable/NumAnimatedRad.java index a21cff4..02b19e5 100644 --- a/src/mightypork/util/constraints/num/mutable/NumAnimatedRad.java +++ b/src/mightypork/util/constraints/num/mutable/NumAnimatedRad.java @@ -32,7 +32,7 @@ public class NumAnimatedRad extends NumAnimated { public double value() { if (duration == 0) return Rad.norm(to); - return Calc.interpolateRad(from, to, (elapsedTime / duration), easing); + return Calc.interpolateRad(from, to, (elapsedTime / duration), easingCurrent); } diff --git a/src/mightypork/util/constraints/vect/Vect.java b/src/mightypork/util/constraints/vect/Vect.java index eeff104..96014b6 100644 --- a/src/mightypork/util/constraints/vect/Vect.java +++ b/src/mightypork/util/constraints/vect/Vect.java @@ -941,7 +941,7 @@ public abstract class Vect implements VectBound, Digestable { if (tSize == 0 || nSize == 0) return 0; - return x() / (nSize / tSize); + return t.x() / (nSize / tSize); } @@ -953,7 +953,7 @@ public abstract class Vect implements VectBound, Digestable { if (tSize == 0 || nSize == 0) return 0; - return y() / (nSize / tSize); + return t.y() / (nSize / tSize); } @@ -965,7 +965,7 @@ public abstract class Vect implements VectBound, Digestable { if (tSize == 0 || nSize == 0) return 0; - return z() / (nSize / tSize); + return t.z() / (nSize / tSize); } }; } diff --git a/src/mightypork/util/control/timing/TimedTask.java b/src/mightypork/util/control/timing/TimedTask.java new file mode 100644 index 0000000..5229699 --- /dev/null +++ b/src/mightypork/util/control/timing/TimedTask.java @@ -0,0 +1,34 @@ +package mightypork.util.control.timing; + +import mightypork.util.constraints.num.mutable.NumAnimated; + + +public abstract class TimedTask implements Runnable, Updateable { + + private NumAnimated timer = new NumAnimated(0); + private boolean running = false; + + @Override + public void update(double delta) + { + if(running) { + timer.update(delta); + if(timer.isFinished()) { + running = false; + run(); + } + } + } + + public void start(double seconds) { + timer.reset(); + timer.animate(1, seconds); + running = true; + } + + public void stop() { + running = false; + timer.reset(); + } + +}