diff --git a/src/awlex/ospu/polymover/Arc.java b/src/awlex/ospu/polymover/ArcMover.java similarity index 71% rename from src/awlex/ospu/polymover/Arc.java rename to src/awlex/ospu/polymover/ArcMover.java index a479a0bc..481af09f 100644 --- a/src/awlex/ospu/polymover/Arc.java +++ b/src/awlex/ospu/polymover/ArcMover.java @@ -8,19 +8,19 @@ import static java.lang.Math.*; /** * Created by Awlex on 13.11.2016. */ -public class Arc extends PolyMover { +public class ArcMover extends PolyMover { private GameObject p1, middle, p2; private double xm, ym, r, alpha, beta, gamma; - public Arc(GameObject p1, GameObject middle, GameObject p2) { + public ArcMover(GameObject p1, GameObject middle, GameObject p2) { this.p1 = p1; this.middle = middle; this.p2 = p2; init(); } - public Arc(PolyMover mover, GameObject p) { + public ArcMover(PolyMover mover, GameObject p) { GameObject[] items = mover.getItems(); p1 = items[items.length - 2]; middle = items[items.length - 1]; @@ -40,17 +40,12 @@ public class Arc extends PolyMover { @Override public double[] getPointAt(int time) { - double percent; double angle; if (time < middle.getTime()) { - time -= p1.getEndTime(); - percent = ((double) time) / ((middle.getTime() - p1.getEndTime())); - angle = alpha + beta * percent; + angle = alpha + beta * ((double) time - p1.getEndTime()) / ((middle.getTime() - p1.getEndTime())); } else { - time -= middle.getTime(); - percent = ((double) time) / (p2.getTime() - middle.getTime()); - angle = beta + gamma * percent; + angle = beta + gamma * ((double) time - middle.getTime()) / (p2.getTime() - middle.getTime()); } return new double[]{ xm + r * cos(angle), @@ -67,7 +62,7 @@ public class Arc extends PolyMover { }; } - private Matrix prepareMatrix(GameObject p1, GameObject middle, GameObject p2) { + private static Matrix prepareMatrix(GameObject p1, GameObject middle, GameObject p2) { Matrix a = new Matrix(new double[][]{ {1, -p1.end.x, -p1.end.y}, {1, -middle.end.x, -middle.end.y}, @@ -83,6 +78,11 @@ public class Arc extends PolyMover { } public static boolean canCricleExistBetweenItems(GameObject p1, GameObject p2, GameObject p3) { - return !((p1.end.x == p2.start.x && p1.end.x == p3.start.x) || (p1.end.y == p2.start.y && p1.end.y == p3.start.y)); + try { + prepareMatrix(p1, p2, p3); + } catch (RuntimeException e) { + return false; + } + return true; } } diff --git a/src/awlex/ospu/polymover/LineMover.java b/src/awlex/ospu/polymover/LineMover.java new file mode 100644 index 00000000..20a0da36 --- /dev/null +++ b/src/awlex/ospu/polymover/LineMover.java @@ -0,0 +1,32 @@ +package awlex.ospu.polymover; + +import itdelatrisu.opsu.objects.DummyObject; +import itdelatrisu.opsu.objects.GameObject; +import yugecin.opsudance.movers.LinearMover; + +/** + * Created by Awlex on 19.11.2016. + */ +public class LineMover extends PolyMover { + + GameObject[] objects; + + public LineMover(GameObject[] objects, int startIndex, int count) { + this.objects = new GameObject[count]; + System.arraycopy(objects, startIndex, this.objects, 0, count); + } + + @Override + public double[] getPointAt(int time) { + int i = 0; + while (time > objects[i].getTime() && i < objects.length - 1) + i++; + + return new LinearMover(i == 0 ? new DummyObject() : objects[i - 1], objects[i], 1).getPointAt(time); + } + + @Override + public GameObject[] getItems() { + return new GameObject[0]; + } +} diff --git a/src/awlex/ospu/polymover/factory/ArcFactory.java b/src/awlex/ospu/polymover/factory/ArcFactory.java index ea2e3923..973d5022 100644 --- a/src/awlex/ospu/polymover/factory/ArcFactory.java +++ b/src/awlex/ospu/polymover/factory/ArcFactory.java @@ -1,6 +1,7 @@ package awlex.ospu.polymover.factory; -import awlex.ospu.polymover.Arc; +import awlex.ospu.polymover.ArcMover; +import awlex.ospu.polymover.LineMover; import awlex.ospu.polymover.PolyMover; import itdelatrisu.opsu.objects.GameObject; @@ -10,15 +11,16 @@ import itdelatrisu.opsu.objects.GameObject; public class ArcFactory implements PolyMoverFactory { private static final int PREFFERED_BUFFER_SIZE = 3; - private PolyMover arc1, arc2; + private PolyMover current, previous; + private int lastIndex; public double[] getPointAt(int time) { - if (arc2 == null) { - return arc1.getPointAt(time); + if (previous == null) { + return current.getPointAt(time); } - double[] point1 = arc1.getPointAt(time); - double[] point2 = arc2.getPointAt(time); + double[] point1 = current.getPointAt(time); + double[] point2 = previous.getPointAt(time); return new double[]{ (point1[0] + point2[0]) * 0.5, @@ -30,18 +32,26 @@ public class ArcFactory implements PolyMoverFactory { public void init(GameObject[] objects, int startIndex) { if (objects == null) throw new NullPointerException("Objects musn't be null"); - arc1 = new Arc(objects[startIndex], objects[startIndex + 1], objects[startIndex + 2]); - arc2 = null; + + GameObject middle = objects[startIndex + 1]; + if (middle.isSlider() || middle.isSpinner() || !ArcMover.canCricleExistBetweenItems(objects[startIndex], middle, objects[startIndex + 2])) + current = new LineMover(objects, startIndex, 3); + else + current = new ArcMover(objects[startIndex], middle, objects[startIndex + 2]); + lastIndex = startIndex + 2; + previous = null; } public void update(GameObject p) { - GameObject[] items = (arc2 == null ? arc1 : arc2).getItems(); + GameObject[] items = (previous == null ? current : previous).getItems(); GameObject last = items[items.length - 1]; if (last != p) { - if (arc2 == null) - arc2 = arc1; - arc1 = new Arc(arc2, p); + if (ArcMover.canCricleExistBetweenItems(items[items.length - 2], items[items.length - 1], p)) { + previous = current; + current = new ArcMover(previous, p); + } } + lastIndex++; } @Override @@ -56,6 +66,12 @@ public class ArcFactory implements PolyMoverFactory { @Override public boolean isInitialized() { - return arc1 != null; + return current != null; } + + @Override + public int getLatestIndex() { + return lastIndex; + } + } diff --git a/src/awlex/ospu/polymover/factory/PolyMoverFactory.java b/src/awlex/ospu/polymover/factory/PolyMoverFactory.java index dd6d739c..bffd79f9 100644 --- a/src/awlex/ospu/polymover/factory/PolyMoverFactory.java +++ b/src/awlex/ospu/polymover/factory/PolyMoverFactory.java @@ -25,4 +25,6 @@ public interface PolyMoverFactory { int getPrefferedBufferSize(); boolean isInitialized(); + + int getLatestIndex(); } diff --git a/src/yugecin/opsudance/Dancer.java b/src/yugecin/opsudance/Dancer.java index 13c5328c..02f08357 100644 --- a/src/yugecin/opsudance/Dancer.java +++ b/src/yugecin/opsudance/Dancer.java @@ -266,13 +266,12 @@ public class Dancer { double[] spinnerStartPoint = spinner.getPoint(); c.start = new Vec2f((float) spinnerStartPoint[0], (float) spinnerStartPoint[1]); } - GameObject g = gameObjects[objectIndex + 2]; - if (!g.isSpinner() && !g.isSlider()) - if (polyMoverFactory.isInitialized()) { - polyMoverFactory.update(g); - } else { - polyMoverFactory.init(gameObjects, objectIndex); - } + + if (polyMoverFactory.isInitialized() && polyMoverFactory.getLatestIndex() < objectIndex + polyMoverFactory.getPrefferedBufferSize() - 1) { + polyMoverFactory.update(gameObjects[polyMoverFactory.getPrefferedBufferSize() - 1]); + } else { + polyMoverFactory.init(gameObjects, objectIndex); + } } if (time < c.getTime()) {