Merge branch 'master' into Curving

This commit is contained in:
Awlex 2016-11-19 22:17:19 +01:00
commit 3bd16a8593
10 changed files with 327 additions and 327 deletions

View File

@ -27,30 +27,13 @@ public class FakeGameObject extends GameObject {
} }
public FakeGameObject(GameObject start, GameObject end) { public FakeGameObject(GameObject start, GameObject end) {
halfTime = Math.abs(start.getEndTime() + (end.getTime() - start.getEndTime()) / 2); halfTime = start.getEndTime() + (end.getTime() - start.getEndTime()) / 2;
this.start = new Vec2f(); this.start = new Vec2f();
this.end = new Vec2f(); this.end = new Vec2f();
this.start.x = this.end.x = (start.end.x + end.start.x) / 2; this.start.x = this.end.x = (start.end.x + end.start.x) / 2;
this.start.y = this.end.y = (start.end.y + end.start.y) / 2; this.start.y = this.end.y = (start.end.y + end.start.y) / 2;
} }
@Override
public int getEndTime() {
return halfTime;
}
@Override
public int getTime() {
return halfTime;
}
public void setTime(int time) {
this.halfTime = time;
}
/*
* Everything down here is unimportant
*/
@Override @Override
public void draw(Graphics g, int trackPosition, boolean mirrored) { public void draw(Graphics g, int trackPosition, boolean mirrored) {
@ -71,6 +54,16 @@ public class FakeGameObject extends GameObject {
return null; return null;
} }
@Override
public int getEndTime() {
return halfTime;
}
@Override
public int getTime() {
return halfTime;
}
@Override @Override
public void updatePosition() { public void updatePosition() {
@ -105,4 +98,8 @@ public class FakeGameObject extends GameObject {
return null; return null;
} }
public void setTime(int time) {
this.halfTime = time;
}
} }

View File

@ -1,36 +1,46 @@
package awlex.ospu.movers; package awlex.ospu.movers;
import itdelatrisu.opsu.Utils;
import itdelatrisu.opsu.objects.GameObject; import itdelatrisu.opsu.objects.GameObject;
import yugecin.opsudance.movers.Mover; import yugecin.opsudance.movers.Mover;
/** /**
* Created by Alex Wieser on 09.10.2016. * Created by Alex Wieser on 09.10.2016.
* WHO DO YOU THINK I AM? * WHO DO YOU THINK I AM?
* <p> *
* This {@link Mover} starts the spiral from the start object * This {@link Mover} starts the spiral from the start object
*/ */
public class CentralSpiralMover extends SpiralMover { public class CentralSpiralMover extends Mover {
public CentralSpiralMover(GameObject start, GameObject end, int dir) { /**
super(start, end, dir); * How many times the cursor goes around the center
} * For satisfying results this musn't be a multiple of 2
*/
private final int CIRCLENAVIGATIONS = 1;
@Override double startAng;
public double[] getPointAt(int time) { double startRad;
double rad = radius * getT(time);
double ang = angle + 2d * Math.PI * getT(time) * dir;
return new double[]{
startX + rad * Math.cos(ang),
startY + rad * Math.sin(ang)
};
}
@Override public CentralSpiralMover(GameObject start, GameObject end, int dir) {
public boolean checkBounds() { super(start, end, dir);
boolean ret = true; startAng = Math.atan2(endY - startY, endX - startX);
int totalTime = endTime - startTime; startRad = Utils.distance(startX, startY, endX, endY);
for (int i = 0; ret && i <= 20; i++) if (startRad < 20)
ret = checkIfPointInBounds(getPointAt((int) (startTime + totalTime * (i / 20d)))); startRad = 20 + startRad / 20d;
return ret; }
}
@Override
public double[] getPointAt(int time) {
double rad = startRad * getT(time);
double ang = CIRCLENAVIGATIONS * (startAng + 2d * Math.PI * getT(time) * dir);
return new double[]{
startX + rad * Math.cos(ang),
startY + rad * Math.sin(ang)
};
}
@Override
public String getName() {
return "Spiral2";
}
} }

View File

@ -4,8 +4,6 @@ import awlex.ospu.FakeGameObject;
import itdelatrisu.opsu.Options; import itdelatrisu.opsu.Options;
import itdelatrisu.opsu.Utils; import itdelatrisu.opsu.Utils;
import itdelatrisu.opsu.objects.GameObject; import itdelatrisu.opsu.objects.GameObject;
import yugecin.opsudance.movers.CircleMover;
import yugecin.opsudance.movers.LinearMover;
import yugecin.opsudance.movers.Mover; import yugecin.opsudance.movers.Mover;
import yugecin.opsudance.movers.factories.AutoMoverFactory; import yugecin.opsudance.movers.factories.AutoMoverFactory;
@ -18,100 +16,120 @@ import yugecin.opsudance.movers.factories.AutoMoverFactory;
* 2 inner {@link Mover}s around it. This class works recursively and might lead to * 2 inner {@link Mover}s around it. This class works recursively and might lead to
* high ram usage on very jumpy maps or even a StackOverFlow. * high ram usage on very jumpy maps or even a StackOverFlow.
*/ */
public class CombinedSpiralMover extends SpiralMover { public class CombinedSpiralMover extends Mover {
private Mover[] movers; private Mover[] movers;
private GameObject fakeObject; private GameObject fakeObject;
private int halfTime; private int halfTime;
private int startTime; private int startTime;
private int endTime; private int endTime;
public CombinedSpiralMover(GameObject middle, GameObject start, GameObject end, int dir) { public CombinedSpiralMover(GameObject middle, GameObject start, GameObject end, int dir) {
this(true, middle, start, end, dir); super(start, end, dir);
} fakeObject = middle != null ? middle : new FakeGameObject(start, end);
public CombinedSpiralMover(boolean prefered, GameObject middle, GameObject start, GameObject end, int dir) { halfTime = fakeObject.getEndTime();
super(start, end, dir); startTime = start.getEndTime();
fakeObject = middle != null ? middle : new FakeGameObject(start, end); endTime = end.getTime();
halfTime = fakeObject.getEndTime(); movers = new Mover[2];
startTime = start.getEndTime(); movers[0] = bestPick(0, start, fakeObject, dir);
endTime = end.getTime(); movers[1] = bestPick(1, fakeObject, end, dir);
}
movers = new Mover[2]; public CombinedSpiralMover(GameObject start, GameObject end, int dir) {
movers[0] = bestPick(prefered ? 0 : 1, start, fakeObject, dir); this(null, start, end, dir);
movers[1] = bestPick(prefered ? 1 : 0, fakeObject, end, dir); }
}
public CombinedSpiralMover(GameObject start, GameObject end, int dir) { /**
this(null, start, end, dir); * Method to pick the 2 inner {@link Mover}s.
} * Tries to pick a {@link SpiralToMover} first position and a
* {@link CombinedSpiralMover} for second position for the sake of good looks
*
* @param pos index of
* @param start start object
* @param end end object
* @param dir direction
* @return best fitting Mover
*/
private Mover bestPick(int pos, GameObject start, GameObject end, int dir) {
@Override if (endTime - startTime < 10 || Utils.distance(start.end.x, start.end.y, end.start.x, end.start.y) < 40)
public boolean checkBounds() { return new AutoMoverFactory().create(start, end, dir);
/*Not needed in this case*/
return true; SpiralToMover spiralTo = new SpiralToMover(start, end, dir);
} CentralSpiralMover center = new CentralSpiralMover(start, end, dir);
if (pos == 0) {
if (inBounds1(spiralTo) || inBounds1(spiralTo = new SpiralToMover(start, end, -dir)))
return spiralTo;
else if (inBounds1(center) || inBounds1(center = new CentralSpiralMover(start, end, -dir)))
return center;
} else if (pos == 1) {
if (inBounds2(center) || inBounds2(center = new CentralSpiralMover(start, end, -dir)))
return center;
else if (inBounds2(spiralTo = new SpiralToMover(start, end, -dir)) || inBounds2(spiralTo = new SpiralToMover(start, end, dir)))
return spiralTo;
} else throw new IllegalStateException("Only 2 inner Movers allowed");
return new CombinedSpiralMover(start, end, dir);
}
public CombinedSpiralMover(Mover mover1, Mover mover2, int startTime, int halfTime, int endTime) { @Override
super(new FakeGameObject(), new FakeGameObject(), 0); //With this constructor you only care about the movers public double[] getPointAt(int time) {
this.startTime = startTime; if (time < halfTime)
this.endTime = endTime; return movers[0].getPointAt(time);
this.halfTime = halfTime; else if (time > halfTime)
movers = new Mover[]{ return movers[1].getPointAt(time);
mover1, else return new double[]{
mover2 fakeObject.start.x,
}; fakeObject.start.y
} };
}
/** @Override
* Method to pick the 2 inner {@link Mover}s. public String getName() {
* Tries to pick a {@link SpiralToMover} first position and a return "CombinedSpiralMover";
* {@link CombinedSpiralMover} for second position for the sake of good looks }
*
* @param pos index of
* @param start start object
* @param end end object
* @param dir direction
* @return best fitting Mover
*/
private Mover bestPick(int pos, GameObject start, GameObject end, int dir) {
if (endTime - startTime < 40 || Utils.distance(start.end.x, start.end.y, end.start.x, end.start.y) < 40) /**
return new LinearMover(start, end, dir); * /**
* Check if the first object would be inbounds
*
* @param mover - the mover to check
* @return is mover always inbounds
*/
public boolean inBounds1(Mover mover) {
boolean ret = true;
int middle = halfTime - startTime;
for (int i = 1; ret && i < 15; i++) {
ret = checkBounds(mover.getPointAt(startTime + (middle * i) / 16));
//System.out.println("i: " + i + " = " + ret);
}
SpiralToMover spiralTo = new SpiralToMover(start, end, dir); return ret;
CentralSpiralMover center = new CentralSpiralMover(start, end, dir); }
if (pos == 0) { /**
if (spiralTo.checkBounds() || (spiralTo = new SpiralToMover(start, end, -dir)).checkBounds()) * /**
return spiralTo; * Check if the second object would be inbounds
else if (center.checkBounds() || (center = new CentralSpiralMover(start, end, -dir)).checkBounds()) *
return center; * @param mover - the mover to check
} * @return is mover always inbounds
else if (pos == 1) { */
if (center.checkBounds() || (center = new CentralSpiralMover(start, end, -dir)).checkBounds()) private boolean inBounds2(Mover mover) {
return center; boolean ret = true;
else if ((spiralTo = new SpiralToMover(start, end, -dir)).checkBounds() || (spiralTo = new SpiralToMover(start, end, dir)).checkBounds()) int middle = endTime - halfTime;
return spiralTo; for (int i = 1; ret && i < 15; i++) {
} ret = checkBounds(mover.getPointAt(startTime + (middle * i) / 16));
else throw new IllegalStateException("Only 2 inner Movers allowed"); //System.out.println("i: " + i + " = " + ret);
}
return new CombinedSpiralMover(start, end, dir); return ret;
} }
@Override
public double[] getPointAt(int time) {
if (time < halfTime)
return movers[0].getPointAt(time);
else if (time > halfTime)
return movers[1].getPointAt(time);
else return new double[]{
fakeObject.start.x,
fakeObject.start.y
};
}
private boolean checkBounds(double[] pos) {
return 0 < pos[0] && pos[0] < Options.width && 0 < pos[1] && pos[1] < Options.height;
}
} }

View File

@ -0,0 +1,38 @@
package awlex.ospu.movers;
import itdelatrisu.opsu.Utils;
import itdelatrisu.opsu.objects.GameObject;
import yugecin.opsudance.movers.Mover;
/**
* Created by Awlex on 27.10.2016.
*/
public class SinusMover extends Mover {
private double angle;
private double radius;
private double amplitude;
public SinusMover(GameObject start, GameObject end, int dir) {
super(start, end, dir);
angle = Math.atan2(endY - startY, endX - startX);
radius = Utils.distance(startX, startY, endX, endY);
amplitude = radius / 4;
this.dir = angle < 180 ? dir : -dir;
}
@Override
public double[] getPointAt(int time) {
double x = radius * getT(time);
double y = amplitude * Math.sin(2d * Math.PI * getT(time)) * dir;
return new double[]{
startX + x * Math.cos(angle) - y * Math.sin(angle),
startY + x * Math.sin(angle) + y * Math.cos(angle)
};
}
@Override
public String getName() {
return "Sinustic";
}
}

View File

@ -1,55 +0,0 @@
package awlex.ospu.movers;
import itdelatrisu.opsu.Options;
import itdelatrisu.opsu.Utils;
import itdelatrisu.opsu.objects.GameObject;
import org.newdawn.slick.util.pathfinding.Mover;
/**
* Created by Alex Wieser on 22.10.2016.
*/
abstract class SpiralMover extends yugecin.opsudance.movers.Mover {
protected double angle;
protected double radius;
int startTime;
int endTime;
SpiralMover(GameObject start, GameObject end, int dir) {
super(start, end, dir);
angle = Math.atan2(endY - startY, endX - startX);
radius = Utils.distance(startX, startY, endX, endY);
startTime = start.getEndTime();
endTime = end.getTime();
}
public double getAngle() {
return angle;
}
public double getRadius() {
return radius;
}
public int getDir() {
return dir;
}
public abstract boolean checkBounds();
@Override
public String getName() {
return getClass().getSimpleName();
}
/**
* checks if a point is in bounds
*
* @param pos x and y coordinations
* @return whether this point is within the screen
*/
boolean checkIfPointInBounds(double[] pos) {
return 0 < pos[0] && pos[0] < Options.width && 0 < pos[1] && pos[1] < Options.height;
}
}

View File

@ -1,36 +1,46 @@
package awlex.ospu.movers; package awlex.ospu.movers;
import itdelatrisu.opsu.Utils;
import itdelatrisu.opsu.objects.GameObject; import itdelatrisu.opsu.objects.GameObject;
import yugecin.opsudance.movers.Mover; import yugecin.opsudance.movers.Mover;
/** /**
* Created by Alex Wieser on 09.10.2016. * Created by Alex Wieser on 09.10.2016.
* WHO DO YOU THINK I AM? * WHO DO YOU THINK I AM?
* <p> *
* This {@link Mover} ends the spiral from the start object * This {@link Mover} ends the spiral from the start object
*/ */
public class SpiralToMover extends SpiralMover { public class SpiralToMover extends Mover {
public SpiralToMover(GameObject start, GameObject end, int dir) { /**
super(start, end, dir); * How many times the cursor goes around the center
} * For satisfying results this musn't be a multiple of 2
*/
private final int CIRCLENAVIGATIONS = 1;
@Override double startAng;
public double[] getPointAt(int time) { double startRad;
double rad = radius * (1 - getT(time));
double ang = angle + Math.PI + 2d * Math.PI * (1 - getT(time)) * dir;
return new double[]{
endX + rad * Math.cos(ang),
endY + rad * Math.sin(ang)
};
}
@Override public SpiralToMover(GameObject start, GameObject end, int dir) {
public boolean checkBounds() { super(start, end, dir);
boolean ret = true; startAng = Math.atan2(endY - startY, endX - startX) + Math.PI;
int totalTime = endTime - startTime; startRad = Utils.distance(startX, startY, endX, endY);
for (int i = 0; ret && i <= 20; i++) if (startRad < 20)
ret = checkIfPointInBounds(getPointAt((int) (startTime + totalTime * (1 - i / 20d)))); startRad = 20 + startRad / 20d;
return ret; }
}
@Override
public double[] getPointAt(int time) {
double rad = startRad * (1 - getT(time));
double ang = CIRCLENAVIGATIONS * (startAng + 2d * Math.PI * (1 - getT(time)) * dir);
return new double[]{
endX + rad * Math.cos(ang),
endY + rad * Math.sin(ang)
};
}
@Override
public String getName() {
return "Spiral2";
}
} }

View File

@ -8,20 +8,20 @@ import yugecin.opsudance.movers.factories.MoverFactory;
/** /**
* Created by Alex Wieser on 10.10.2016. * Created by Alex Wieser on 10.10.2016.
* Best With Only one direction (Left or Right)
*/ */
public class CenterSpiralMoverFactory implements MoverFactory { public class CenterSpiralMoverFactory implements MoverFactory {
private static FakeGameObject middle = new FakeGameObject(); private static FakeGameObject middle;
@Override
public Mover create(GameObject start, GameObject end, int dir) {
if (middle == null)
middle = new FakeGameObject();
middle.setTime(start.getEndTime() + (end.getTime() - start.getEndTime()) / 2);
return new CombinedSpiralMover(middle, start, end, dir);
}
@Override @Override
public Mover create(GameObject start, GameObject end, int dir) { public String toString() {
middle.setTime(start.getEndTime() + (end.getTime() - start.getEndTime()) / 2); return "CentralSpiralSpin";
return new CombinedSpiralMover(middle, start, end, dir); }
}
@Override
public String toString() {
return "CentralSpiralSpin";
}
} }

View File

@ -1,22 +0,0 @@
package awlex.ospu.movers.factories;
import awlex.ospu.movers.CombinedSpiralMover;
import itdelatrisu.opsu.objects.GameObject;
import yugecin.opsudance.movers.Mover;
import yugecin.opsudance.movers.factories.MoverFactory;
/**
* Created by Alex Wieser on 26.10.2016.
*/
public class CombinedSpiralMoverFactory implements MoverFactory {
@Override
public Mover create(GameObject start, GameObject end, int dir) {
return new CombinedSpiralMover(start, end, dir);
}
@Override
public String toString() {
return "Spiral even more";
}
}

View File

@ -10,84 +10,86 @@ import yugecin.opsudance.spinners.Spinner;
*/ */
public class SpiralSpinner extends Spinner { public class SpiralSpinner extends Spinner {
/** /**
* How many points the Spinner uses. * How many points the Spinner uses.
* if there are not enough points the spinner looks angular. * if there are not enough points the spinner looks angular.
* if there are too many points the spinner doesn't operate smooth * if there are too many points the spinner doesn't operate smooth
*/ */
private final int SIZE = 100; private final int SIZE = 100;
/** /**
* The density of the spinner * The density of the spinner
* Determines how many times the spinner will around the center. * Determines how many times the spinner will around the center.
* if the value is to high the spinner will become angular. * if the value is to high the spinner will become angular.
* if this value goes under 2 the spinner won't be complete * if this value goes under 2 the spinner won't be complete
*/ */
private final int DENSITY = 10; private final int DENSITY = 10;
/** /**
* How much the spinner will be rotated. * How much the spinner will be rotated.
* Negative = clockwise * Negative = clockwise
* Positive = counter clockwise * Positive = counter clockwise
*/ */
private final double DELTA = -Math.PI / 20; private final double DELTA = -Math.PI / 20;
private int MAX_RAD; private int MAX_RAD;
private int index; private int index;
private double[][] points; double[][] points;
private boolean down; boolean down;
@Override @Override
public void init() { public void init() {
points = new double[SIZE][]; points = new double[SIZE][];
double ang; double ang;
double rad; double rad;
for (int i = 0; i < SIZE / 2; i++) { for (int i = 0; i < SIZE / 2; i++) {
MAX_RAD = (int) (Options.height * .35); MAX_RAD = (int) (Options.height * .35);
ang = (DENSITY * (Math.PI / SIZE) * i); ang = (DENSITY * (Math.PI / SIZE) * i);
rad = (MAX_RAD / (SIZE / 2)) * i; rad = (MAX_RAD / (SIZE / 2)) * i;
int offsetX = Options.width / 2; int offsetX = Options.width / 2;
int offsetY = Options.height / 2; int offsetY = Options.height / 2;
points[SIZE / 2 - 1 - i] = new double[]{ points[SIZE / 2 - 1 - i] = new double[]{
offsetX + rad * Math.cos(ang), offsetX + rad * Math.cos(ang),
offsetY + rad * Math.sin(ang) offsetY + rad * Math.sin(ang)
}; };
points[SIZE / 2 + i] = new double[]{ points[SIZE / 2 + i] = new double[]{
offsetX + rad * (Math.cos(ang) * Math.cos(Math.PI) - Math.sin(ang) * Math.sin(Math.PI)), offsetX + rad * (Math.cos(ang) * Math.cos(Math.PI) - Math.sin(ang) * Math.sin(Math.PI)),
offsetY + rad * -Math.sin(ang) offsetY + rad * -Math.sin(ang)
}; };
} }
} }
@Override @Override
public String toString() { public String toString() {
return "Spiralspinner"; return "Spiralspinner";
} }
@Override @Override
public double[] getPoint() { public double[] getPoint() {
if (down) { //if (waitForDelay()) {
if (--index == 0) if (down) {
down = !down; if (--index == 0)
} else if (++index == SIZE - 1) down = !down;
down = !down; } else if (++index == SIZE - 1)
down = !down;
if (!down && index == 1) { if (!down && index == 1) {
rotatePointAroundCenter(points[0], DELTA); rotatePointAroundCenter(points[0], DELTA);
} else if (down && index == SIZE - 2) { } else if (down && index == SIZE - 2) {
rotatePointAroundCenter(points[SIZE - 1], DELTA); rotatePointAroundCenter(points[SIZE - 1], DELTA);
} }
rotatePointAroundCenter(points[index], DELTA); //}
return points[index]; rotatePointAroundCenter(points[index], DELTA);
} return points[index];
}
private void rotatePointAroundCenter(double[] point, double beta) { private void rotatePointAroundCenter(double[] point, double beta) {
double angle = Math.atan2(point[1] - Options.height / 2, point[0] - Options.width / 2); double angle = Math.atan2(point[1] - Options.height / 2, point[0] - Options.width / 2);
double rad = Utils.distance(point[0], point[1], Options.width / 2, Options.height / 2); double rad = Utils.distance(point[0], point[1], Options.width / 2, Options.height / 2);
//rotationMatrix //rotationMatrix
point[0] = Options.width / 2 + rad * (Math.cos(angle) * Math.cos(beta) - Math.sin(angle) * Math.sin(beta)); point[0] = Options.width / 2 + rad * (Math.cos(angle) * Math.cos(beta) - Math.sin(angle) * Math.sin(beta));
point[1] = Options.height / 2 + rad * (Math.cos(angle) * Math.sin(beta) + Math.sin(angle) * Math.cos(beta)); point[1] = Options.height / 2 + rad * (Math.cos(angle) * Math.sin(beta) + Math.sin(angle) * Math.cos(beta));
} }
} }

View File

@ -184,6 +184,8 @@ public class SBOverlay {
public void setGameObjects(GameObject[] gameObjects) { public void setGameObjects(GameObject[] gameObjects) {
if (this.gameObjects.length != gameObjects.length) { if (this.gameObjects.length != gameObjects.length) {
optionsMap = new HashMap[gameObjects.length]; optionsMap = new HashMap[gameObjects.length];
}
if (optionsMap.length > 0) {
// copy all current settings in first obj map // copy all current settings in first obj map
optionsMap[0] = new HashMap<>(); optionsMap[0] = new HashMap<>();
for (Options.GameOption o : options.getSavedOptionList()) { for (Options.GameOption o : options.getSavedOptionList()) {