diff --git a/src/yugecin/opsudance/OpsuDance.java b/src/yugecin/opsudance/OpsuDance.java index 5b3651fa..1022158f 100644 --- a/src/yugecin/opsudance/OpsuDance.java +++ b/src/yugecin/opsudance/OpsuDance.java @@ -21,6 +21,7 @@ import com.google.inject.Inject; import org.lwjgl.LWJGLException; import yugecin.opsudance.core.DisplayContainer; import yugecin.opsudance.errorhandling.ErrorHandler; +import yugecin.opsudance.states.EmptyState; import static yugecin.opsudance.kernel.Entrypoint.sout; @@ -35,7 +36,7 @@ public class OpsuDance { public void start() { sout("initialized"); - container.init(); + container.switchStateNow(EmptyState.class); while (rungame()); } diff --git a/src/yugecin/opsudance/core/Demux.java b/src/yugecin/opsudance/core/Demux.java index 14cf80fd..a4361ca2 100644 --- a/src/yugecin/opsudance/core/Demux.java +++ b/src/yugecin/opsudance/core/Demux.java @@ -22,12 +22,10 @@ import org.newdawn.slick.Graphics; import org.newdawn.slick.Input; import org.newdawn.slick.KeyListener; import org.newdawn.slick.MouseListener; +import yugecin.opsudance.core.state.BaseOpsuState; +import yugecin.opsudance.core.state.transitions.*; import yugecin.opsudance.kernel.InstanceContainer; -import yugecin.opsudance.states.EmptyState; import yugecin.opsudance.core.state.OpsuState; -import yugecin.opsudance.core.state.transitions.FadeInTransitionState; -import yugecin.opsudance.core.state.transitions.FadeOutTransitionState; -import yugecin.opsudance.core.state.transitions.TransitionState; /** * state demultiplexer, sends events to current state @@ -36,47 +34,75 @@ public class Demux implements KeyListener, MouseListener { private final InstanceContainer instanceContainer; - private TransitionState fadeOutTransitionState; - private TransitionState fadeInTransitionState; + private TransitionState outTransitionState; + private TransitionState inTransitionState; + + private final TransitionFinishedListener outTransitionListener; + private final TransitionFinishedListener inTransitionListener; private OpsuState state; @Inject - public Demux(InstanceContainer instanceContainer) { + public Demux(final InstanceContainer instanceContainer) { this.instanceContainer = instanceContainer; + + state = new BaseOpsuState() { + + @Override + public void update(int delta) { } + + @Override + public void preRenderUpdate(int delta) { } + + @Override + public void render(Graphics g) { } + + @Override + public void enter() { } + + @Override + public void leave() { } + + }; + + outTransitionListener = new TransitionFinishedListener() { + @Override + public void onFinish() { + state.leave(); + outTransitionState.getApplicableState().leave(); + state = inTransitionState; + state.enter(); + inTransitionState.getApplicableState().enter(); + } + }; + + inTransitionListener = new TransitionFinishedListener() { + @Override + public void onFinish() { + state.leave(); + state = inTransitionState.getApplicableState(); + } + }; } - // cannot do this in constructor, would cause circular dependency - public void init() { - state = instanceContainer.provide(EmptyState.class); - fadeOutTransitionState = instanceContainer.provide(FadeOutTransitionState.class); - fadeInTransitionState = instanceContainer.provide(FadeInTransitionState.class); - } public boolean isTransitioning() { - return state == fadeInTransitionState || state == fadeOutTransitionState; + return state instanceof TransitionState; } public void switchState(Class newState) { - switchState(instanceContainer.provide(newState)); + switchState(newState, FadeOutTransitionState.class, 200, FadeInTransitionState.class, 300); } - public void switchState(OpsuState newState) { + public void switchState(Class newState, Class outTransition, int outTime, Class inTransition, int inTime) { if (isTransitioning()) { return; } - fadeOutTransitionState.setApplicableState(state); - fadeInTransitionState.setApplicableState(newState); - state = fadeOutTransitionState; + outTransitionState = instanceContainer.provide(outTransition).set(state, outTime, outTransitionListener); + inTransitionState = instanceContainer.provide(inTransition).set(instanceContainer.provide(newState), inTime, inTransitionListener); + state = outTransitionState; state.enter(); } - public void switchStateNow(OpsuState newState) { - if (!isTransitioning()) { - return; - } - state = newState; - } - /* * demux stuff below */ diff --git a/src/yugecin/opsudance/core/DisplayContainer.java b/src/yugecin/opsudance/core/DisplayContainer.java index b9fd70b1..77368bd3 100644 --- a/src/yugecin/opsudance/core/DisplayContainer.java +++ b/src/yugecin/opsudance/core/DisplayContainer.java @@ -31,6 +31,8 @@ import org.newdawn.slick.opengl.renderer.Renderer; import org.newdawn.slick.opengl.renderer.SGL; import org.newdawn.slick.util.Log; import yugecin.opsudance.core.state.OpsuState; +import yugecin.opsudance.core.state.transitions.EmptyTransitionState; +import yugecin.opsudance.core.state.transitions.TransitionState; import yugecin.opsudance.errorhandling.ErrorDumpable; import yugecin.opsudance.utils.GLHelper; @@ -84,16 +86,16 @@ public class DisplayContainer implements ErrorDumpable { resolutionChangeListeners.add(listener); } - public void switchState(OpsuState newState) { - demux.switchState(newState); - } - public void switchState(Class newState) { demux.switchState(newState); } - public void init() { - demux.init(); + public void switchStateNow(Class newState) { + demux.switchState(newState, EmptyTransitionState.class, 0, EmptyTransitionState.class, 0); + } + + public void switchState(Class newState, Class outTransition, int outTime, Class inTransition, int inTime) { + demux.switchState(newState, outTransition, outTime, inTransition, inTime); } public void run() throws LWJGLException { diff --git a/src/yugecin/opsudance/core/state/transitions/EmptyTransitionState.java b/src/yugecin/opsudance/core/state/transitions/EmptyTransitionState.java new file mode 100644 index 00000000..fec4c716 --- /dev/null +++ b/src/yugecin/opsudance/core/state/transitions/EmptyTransitionState.java @@ -0,0 +1,27 @@ +/* + * opsu!dance - fork of opsu! with cursordance auto + * Copyright (C) 2017 yugecin + * + * opsu!dance is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * opsu!dance is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with opsu!dance. If not, see . + */ +package yugecin.opsudance.core.state.transitions; + +public class EmptyTransitionState extends TransitionState { + + @Override + public void enter() { + finish(); + } + +} diff --git a/src/yugecin/opsudance/core/state/transitions/FadeInTransitionState.java b/src/yugecin/opsudance/core/state/transitions/FadeInTransitionState.java index d5b1f15a..aa78f646 100644 --- a/src/yugecin/opsudance/core/state/transitions/FadeInTransitionState.java +++ b/src/yugecin/opsudance/core/state/transitions/FadeInTransitionState.java @@ -18,17 +18,13 @@ package yugecin.opsudance.core.state.transitions; import com.google.inject.Inject; -import yugecin.opsudance.core.Demux; import yugecin.opsudance.core.DisplayContainer; public class FadeInTransitionState extends FadeTransitionState { - private final Demux demux; - @Inject - public FadeInTransitionState(DisplayContainer container, Demux demux) { - super(container, 300); - this.demux = demux; + public FadeInTransitionState(DisplayContainer container) { + super(container); } @Override @@ -36,15 +32,4 @@ public class FadeInTransitionState extends FadeTransitionState { return 1f - fadeProgress; } - @Override - public void enter() { - super.enter(); - applicableState.enter(); - } - - @Override - protected void onTransitionFinished() { - demux.switchStateNow(applicableState); - } - } diff --git a/src/yugecin/opsudance/core/state/transitions/FadeOutTransitionState.java b/src/yugecin/opsudance/core/state/transitions/FadeOutTransitionState.java index d45e4d79..95cde1d7 100644 --- a/src/yugecin/opsudance/core/state/transitions/FadeOutTransitionState.java +++ b/src/yugecin/opsudance/core/state/transitions/FadeOutTransitionState.java @@ -18,19 +18,13 @@ package yugecin.opsudance.core.state.transitions; import com.google.inject.Inject; -import yugecin.opsudance.core.Demux; import yugecin.opsudance.core.DisplayContainer; public class FadeOutTransitionState extends FadeTransitionState { - private final Demux demux; - private final FadeInTransitionState fadeInTransitionState; - @Inject - public FadeOutTransitionState(DisplayContainer container, Demux demux, FadeInTransitionState fadeInTransitionState) { - super(container, 200); - this.demux = demux; - this.fadeInTransitionState = fadeInTransitionState; + public FadeOutTransitionState(DisplayContainer container) { + super(container); } @Override @@ -38,11 +32,4 @@ public class FadeOutTransitionState extends FadeTransitionState { return fadeProgress; } - @Override - protected void onTransitionFinished() { - applicableState.leave(); - demux.switchStateNow(fadeInTransitionState); - fadeInTransitionState.enter(); - } - } diff --git a/src/yugecin/opsudance/core/state/transitions/FadeTransitionState.java b/src/yugecin/opsudance/core/state/transitions/FadeTransitionState.java index dac1f279..8c516c83 100644 --- a/src/yugecin/opsudance/core/state/transitions/FadeTransitionState.java +++ b/src/yugecin/opsudance/core/state/transitions/FadeTransitionState.java @@ -20,55 +20,26 @@ package yugecin.opsudance.core.state.transitions; import org.newdawn.slick.Color; import org.newdawn.slick.Graphics; import yugecin.opsudance.core.DisplayContainer; -import yugecin.opsudance.core.state.OpsuState; public abstract class FadeTransitionState extends TransitionState { - protected OpsuState applicableState; - private final DisplayContainer container; - protected final int fadeTargetTime; - protected int fadeTime; - private final Color black; - public FadeTransitionState(DisplayContainer container, int fadeTargetTime) { - super(fadeTargetTime); + public FadeTransitionState(DisplayContainer container) { this.container = container; - this.fadeTargetTime = fadeTargetTime; black = new Color(Color.black); } - public void setApplicableState(OpsuState applicableState) { - this.applicableState = applicableState; - } - - @Override - public void update(int delta) { - applicableState.update(delta); - fadeTime += delta; - if (fadeTime >= fadeTargetTime) { - onTransitionFinished(); - } - } - @Override public void render(Graphics g) { applicableState.render(g); - black.a = getMaskAlphaLevel((float) fadeTime / fadeTargetTime); + black.a = getMaskAlphaLevel((float) transitionTime / transitionTargetTime); g.setColor(black); g.fillRect(0, 0, container.width, container.height); } - @Override - public void enter() { - fadeTime = 0; - } - - @Override - public void leave() { } - protected abstract float getMaskAlphaLevel(float fadeProgress); } diff --git a/src/yugecin/opsudance/core/state/transitions/TransitionFinishedListener.java b/src/yugecin/opsudance/core/state/transitions/TransitionFinishedListener.java new file mode 100644 index 00000000..3838884b --- /dev/null +++ b/src/yugecin/opsudance/core/state/transitions/TransitionFinishedListener.java @@ -0,0 +1,24 @@ +/* + * opsu!dance - fork of opsu! with cursordance auto + * Copyright (C) 2017 yugecin + * + * opsu!dance is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * opsu!dance is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with opsu!dance. If not, see . + */ +package yugecin.opsudance.core.state.transitions; + +public interface TransitionFinishedListener { + + void onFinish(); + +} diff --git a/src/yugecin/opsudance/core/state/transitions/TransitionState.java b/src/yugecin/opsudance/core/state/transitions/TransitionState.java index e90310f7..8b839b0d 100644 --- a/src/yugecin/opsudance/core/state/transitions/TransitionState.java +++ b/src/yugecin/opsudance/core/state/transitions/TransitionState.java @@ -25,15 +25,20 @@ public abstract class TransitionState extends BaseOpsuState { protected OpsuState applicableState; - protected final int transitionTargetTime; + protected int transitionTargetTime; protected int transitionTime; - public TransitionState(int transitionTargetTime) { - this.transitionTargetTime = transitionTargetTime; + private TransitionFinishedListener listener; + + public final TransitionState set(OpsuState applicableState, int targetTime, TransitionFinishedListener listener) { + this.applicableState = applicableState; + this.transitionTargetTime = targetTime; + this.listener = listener; + return this; } - public void setApplicableState(OpsuState applicableState) { - this.applicableState = applicableState; + public final OpsuState getApplicableState() { + return applicableState; } @Override @@ -41,7 +46,7 @@ public abstract class TransitionState extends BaseOpsuState { applicableState.update(delta); transitionTime += delta; if (transitionTime >= transitionTargetTime) { - onTransitionFinished(); + finish(); } } @@ -62,6 +67,8 @@ public abstract class TransitionState extends BaseOpsuState { @Override public void leave() { } - protected abstract void onTransitionFinished(); + protected final void finish() { + listener.onFinish(); + } } diff --git a/src/yugecin/opsudance/kernel/OpsuDanceModule.java b/src/yugecin/opsudance/kernel/OpsuDanceModule.java index 59a15e1d..0708d3f1 100644 --- a/src/yugecin/opsudance/kernel/OpsuDanceModule.java +++ b/src/yugecin/opsudance/kernel/OpsuDanceModule.java @@ -21,6 +21,7 @@ import com.google.inject.AbstractModule; import yugecin.opsudance.PreStartupInitializer; import yugecin.opsudance.core.DisplayContainer; import yugecin.opsudance.core.Demux; +import yugecin.opsudance.core.state.transitions.EmptyTransitionState; import yugecin.opsudance.states.EmptyRedState; import yugecin.opsudance.states.EmptyState; import yugecin.opsudance.core.state.transitions.FadeInTransitionState; @@ -31,12 +32,15 @@ public class OpsuDanceModule extends AbstractModule { protected void configure() { bind(InstanceContainer.class).to(InstanceResolver.class); bind(PreStartupInitializer.class).asEagerSingleton(); + bind(Demux.class).asEagerSingleton(); bind(DisplayContainer.class).asEagerSingleton(); + + bind(EmptyTransitionState.class).asEagerSingleton(); bind(FadeInTransitionState.class).asEagerSingleton(); bind(FadeOutTransitionState.class).asEagerSingleton(); + bind(EmptyRedState.class).asEagerSingleton(); bind(EmptyState.class).asEagerSingleton(); - bind(Demux.class).asEagerSingleton(); } }