Very minor formatting changes to #76.
Signed-off-by: Jeffrey Han <itdelatrisu@gmail.com>
This commit is contained in:
parent
a69f960e26
commit
5fcff76690
|
@ -619,7 +619,7 @@ public class Utils {
|
||||||
public static float easeOut(float t, float a, float b, float d) {
|
public static float easeOut(float t, float a, float b, float d) {
|
||||||
return b * ((t = t / d - 1f) * t * t + 1f) + a;
|
return b * ((t = t / d - 1f) * t * t + 1f) + a;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fake bounce ease function.
|
* Fake bounce ease function.
|
||||||
* @param t the current time
|
* @param t the current time
|
||||||
|
|
|
@ -164,7 +164,7 @@ public class SoundController {
|
||||||
}
|
}
|
||||||
if (bestIndex >= 0)
|
if (bestIndex >= 0)
|
||||||
return new MultiClip(ref, AudioSystem.getAudioInputStream(formats[bestIndex], audioIn));
|
return new MultiClip(ref, AudioSystem.getAudioInputStream(formats[bestIndex], audioIn));
|
||||||
|
|
||||||
// still couldn't find anything, try the default clip format
|
// still couldn't find anything, try the default clip format
|
||||||
return new MultiClip(ref, AudioSystem.getAudioInputStream(clip.getFormat(), audioIn));
|
return new MultiClip(ref, AudioSystem.getAudioInputStream(clip.getFormat(), audioIn));
|
||||||
}
|
}
|
||||||
|
|
|
@ -460,7 +460,7 @@ public class Slider implements HitObject {
|
||||||
|
|
||||||
if (hitObject.getSliderType() == OsuHitObject.SLIDER_PASSTHROUGH && hitObject.getSliderX().length == 2)
|
if (hitObject.getSliderType() == OsuHitObject.SLIDER_PASSTHROUGH && hitObject.getSliderX().length == 2)
|
||||||
this.curve = new CircumscribedCircle(hitObject, color);
|
this.curve = new CircumscribedCircle(hitObject, color);
|
||||||
else if ( hitObject.getSliderType() == OsuHitObject.SLIDER_CATMULL)
|
else if (hitObject.getSliderType() == OsuHitObject.SLIDER_CATMULL)
|
||||||
this.curve = new CatmullCurve(hitObject, color);
|
this.curve = new CatmullCurve(hitObject, color);
|
||||||
else
|
else
|
||||||
this.curve = new LinearBezier(hitObject, color, hitObject.getSliderType() == OsuHitObject.SLIDER_LINEAR);
|
this.curve = new LinearBezier(hitObject, color, hitObject.getSliderType() == OsuHitObject.SLIDER_LINEAR);
|
||||||
|
|
|
@ -23,7 +23,7 @@ package itdelatrisu.opsu.objects.curves;
|
||||||
*
|
*
|
||||||
* @author fluddokt (https://github.com/fluddokt)
|
* @author fluddokt (https://github.com/fluddokt)
|
||||||
*/
|
*/
|
||||||
public class Bezier2 extends CurveType{
|
public class Bezier2 extends CurveType {
|
||||||
/** The control points of the Bezier curve. */
|
/** The control points of the Bezier curve. */
|
||||||
private Vec2f[] points;
|
private Vec2f[] points;
|
||||||
|
|
||||||
|
@ -55,12 +55,11 @@ public class Bezier2 extends CurveType{
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculates the binomial coefficient.
|
* Calculates the binomial coefficient.
|
||||||
* http://en.wikipedia.org/wiki/Binomial_coefficient#Binomial_coefficient_in_programming_languages
|
* http://en.wikipedia.org/wiki/Binomial_coefficient#Binomial_coefficient_in_programming_languages
|
||||||
*/
|
*/
|
||||||
public static long binomialCoefficient(int n, int k) {
|
private static long binomialCoefficient(int n, int k) {
|
||||||
if (k < 0 || k > n)
|
if (k < 0 || k > n)
|
||||||
return 0;
|
return 0;
|
||||||
if (k == 0 || k == n)
|
if (k == 0 || k == n)
|
||||||
|
|
|
@ -18,19 +18,20 @@
|
||||||
|
|
||||||
package itdelatrisu.opsu.objects.curves;
|
package itdelatrisu.opsu.objects.curves;
|
||||||
|
|
||||||
import java.util.LinkedList;
|
import itdelatrisu.opsu.ErrorHandler;
|
||||||
|
|
||||||
import itdelatrisu.opsu.OsuHitObject;
|
import itdelatrisu.opsu.OsuHitObject;
|
||||||
|
|
||||||
|
import java.util.LinkedList;
|
||||||
|
|
||||||
import org.newdawn.slick.Color;
|
import org.newdawn.slick.Color;
|
||||||
|
import org.newdawn.slick.SlickException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Representation of Catmull Curve with equidistant points.
|
* Representation of Catmull Curve with equidistant points.
|
||||||
*
|
*
|
||||||
* @author fluddokt (https://github.com/fluddokt)
|
* @author fluddokt (https://github.com/fluddokt)
|
||||||
*/
|
*/
|
||||||
public class CatmullCurve extends EqualDistanceMultiCurve{
|
public class CatmullCurve extends EqualDistanceMultiCurve {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor.
|
* Constructor.
|
||||||
* @param hitObject the associated OsuHitObject
|
* @param hitObject the associated OsuHitObject
|
||||||
|
@ -40,9 +41,8 @@ public class CatmullCurve extends EqualDistanceMultiCurve{
|
||||||
super(hitObject, color);
|
super(hitObject, color);
|
||||||
LinkedList<CurveType> catmulls = new LinkedList<CurveType>();
|
LinkedList<CurveType> catmulls = new LinkedList<CurveType>();
|
||||||
int ncontrolPoints = hitObject.getSliderX().length + 1;
|
int ncontrolPoints = hitObject.getSliderX().length + 1;
|
||||||
// temporary list of points to separate different curves
|
LinkedList<Vec2f> points = new LinkedList<Vec2f>(); // temporary list of points to separate different curves
|
||||||
LinkedList<Vec2f> points = new LinkedList<Vec2f>();
|
|
||||||
|
|
||||||
// repeat the first and last points as controls points
|
// repeat the first and last points as controls points
|
||||||
// aabb
|
// aabb
|
||||||
// aabc abcc
|
// aabc abcc
|
||||||
|
@ -51,14 +51,23 @@ public class CatmullCurve extends EqualDistanceMultiCurve{
|
||||||
for (int i = 0; i < ncontrolPoints; i++) {
|
for (int i = 0; i < ncontrolPoints; i++) {
|
||||||
points.addLast(new Vec2f(getX(i), getY(i)));
|
points.addLast(new Vec2f(getX(i), getY(i)));
|
||||||
if (points.size() >= 4) {
|
if (points.size() >= 4) {
|
||||||
catmulls.add(new CentripetalCatmullRom(points.toArray(new Vec2f[0])));
|
try {
|
||||||
|
catmulls.add(new CentripetalCatmullRom(points.toArray(new Vec2f[0])));
|
||||||
|
} catch (SlickException e) {
|
||||||
|
ErrorHandler.error(null, e, true);
|
||||||
|
}
|
||||||
points.removeFirst();
|
points.removeFirst();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
points.addLast(new Vec2f(getX(ncontrolPoints - 1),getY(ncontrolPoints - 1)));
|
points.addLast(new Vec2f(getX(ncontrolPoints - 1), getY(ncontrolPoints - 1)));
|
||||||
if (points.size() >= 4) {
|
if (points.size() >= 4) {
|
||||||
catmulls.add(new CentripetalCatmullRom(points.toArray(new Vec2f[0])));
|
try {
|
||||||
|
catmulls.add(new CentripetalCatmullRom(points.toArray(new Vec2f[0])));
|
||||||
|
} catch (SlickException e) {
|
||||||
|
ErrorHandler.error(null, e, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
init(catmulls);
|
init(catmulls);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,30 +18,30 @@
|
||||||
|
|
||||||
package itdelatrisu.opsu.objects.curves;
|
package itdelatrisu.opsu.objects.curves;
|
||||||
|
|
||||||
|
import org.newdawn.slick.SlickException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Representation of a Centripetal Catmull–Rom spline.
|
* Representation of a Centripetal Catmull–Rom spline.
|
||||||
|
* (Currently not technically Centripetal Catmull–Rom.)
|
||||||
* http://en.wikipedia.org/wiki/Centripetal_Catmull%E2%80%93Rom_spline
|
* http://en.wikipedia.org/wiki/Centripetal_Catmull%E2%80%93Rom_spline
|
||||||
*
|
*
|
||||||
* Currently not technically Centripetal Catmull–Rom
|
|
||||||
*
|
|
||||||
* @author fluddokt (https://github.com/fluddokt)
|
* @author fluddokt (https://github.com/fluddokt)
|
||||||
*/
|
*/
|
||||||
public class CentripetalCatmullRom extends CurveType{
|
public class CentripetalCatmullRom extends CurveType {
|
||||||
|
|
||||||
/** The time values of the Catmull curve. */
|
/** The time values of the Catmull curve. */
|
||||||
float [] time;
|
private float [] time;
|
||||||
|
|
||||||
/** The control points of the Catmull curve. */
|
/** The control points of the Catmull curve. */
|
||||||
Vec2f[] points;
|
private Vec2f[] points;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor.
|
* Constructor.
|
||||||
* @param hitObject the associated OsuHitObject
|
* @param points the control points of the curve
|
||||||
* @param color the color of this curve
|
* @throws SlickException
|
||||||
*/
|
*/
|
||||||
protected CentripetalCatmullRom(Vec2f[] points) {
|
protected CentripetalCatmullRom(Vec2f[] points) throws SlickException {
|
||||||
if (points.length != 4)
|
if (points.length != 4)
|
||||||
throw new Error("need exactly 4 points");
|
throw new SlickException(String.format("Need exactly 4 points to initialize CentripetalCatmullRom, %d provided.", points.length));
|
||||||
|
|
||||||
this.points = points;
|
this.points = points;
|
||||||
time = new float[4];
|
time = new float[4];
|
||||||
|
@ -57,12 +57,12 @@ public class CentripetalCatmullRom extends CurveType{
|
||||||
// time[i] = (float) Math.sqrt(len) + time[i-1];// ^(0.5)
|
// time[i] = (float) Math.sqrt(len) + time[i-1];// ^(0.5)
|
||||||
time[i] = i;
|
time[i] = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
init(approxLength / 2);
|
init(approxLength / 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Vec2f pointAt(float t){
|
public Vec2f pointAt(float t) {
|
||||||
t = t * (time[2] - time[1]) + time[1];
|
t = t * (time[2] - time[1]) + time[1];
|
||||||
|
|
||||||
Vec2f A1 = points[0].cpy().scale((time[1] - t) / (time[1] - time[0]))
|
Vec2f A1 = points[0].cpy().scale((time[1] - t) / (time[1] - time[0]))
|
||||||
|
@ -79,8 +79,7 @@ public class CentripetalCatmullRom extends CurveType{
|
||||||
|
|
||||||
Vec2f C = B1.cpy().scale((time[2] - t) / (time[2] - time[1]))
|
Vec2f C = B1.cpy().scale((time[2] - t) / (time[2] - time[1]))
|
||||||
.add(B2.cpy().scale((t - time[1]) / (time[2] - time[1])));
|
.add(B2.cpy().scale((t - time[1]) / (time[2] - time[1])));
|
||||||
|
|
||||||
return C;
|
return C;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -168,7 +168,6 @@ public class CircumscribedCircle extends Curve {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public float getEndAngle() { return drawEndAngle; }
|
public float getEndAngle() { return drawEndAngle; }
|
||||||
|
|
||||||
|
|
|
@ -31,10 +31,9 @@ import org.newdawn.slick.Image;
|
||||||
* @author fluddokt (https://github.com/fluddokt)
|
* @author fluddokt (https://github.com/fluddokt)
|
||||||
*/
|
*/
|
||||||
public abstract class Curve {
|
public abstract class Curve {
|
||||||
|
/** Points generated along the curve should be spaced this far apart. */
|
||||||
/** Points generated along the curve should be spaced this much apart*/
|
|
||||||
protected static float CURVE_POINTS_SEPERATION = 5;
|
protected static float CURVE_POINTS_SEPERATION = 5;
|
||||||
|
|
||||||
/** The associated OsuHitObject. */
|
/** The associated OsuHitObject. */
|
||||||
protected OsuHitObject hitObject;
|
protected OsuHitObject hitObject;
|
||||||
|
|
||||||
|
@ -44,7 +43,7 @@ public abstract class Curve {
|
||||||
/** The scaled slider x, y coordinate lists. */
|
/** The scaled slider x, y coordinate lists. */
|
||||||
protected float[] sliderX, sliderY;
|
protected float[] sliderX, sliderY;
|
||||||
|
|
||||||
/** Points along the curve. To be set be inherited classes*/
|
/** Points along the curve (set by inherited classes). */
|
||||||
protected Vec2f[] curve;
|
protected Vec2f[] curve;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -72,9 +71,9 @@ public abstract class Curve {
|
||||||
* @param color the color filter
|
* @param color the color filter
|
||||||
*/
|
*/
|
||||||
public void draw(Color color) {
|
public void draw(Color color) {
|
||||||
if (curve == null){
|
if (curve == null)
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
Image hitCircle = GameImage.HITCIRCLE.getImage();
|
Image hitCircle = GameImage.HITCIRCLE.getImage();
|
||||||
Image hitCircleOverlay = GameImage.HITCIRCLE_OVERLAY.getImage();
|
Image hitCircleOverlay = GameImage.HITCIRCLE_OVERLAY.getImage();
|
||||||
for (int i = 0; i < curve.length; i++)
|
for (int i = 0; i < curve.length; i++)
|
||||||
|
|
|
@ -24,7 +24,6 @@ package itdelatrisu.opsu.objects.curves;
|
||||||
* @author fluddokt (https://github.com/fluddokt)
|
* @author fluddokt (https://github.com/fluddokt)
|
||||||
*/
|
*/
|
||||||
public abstract class CurveType {
|
public abstract class CurveType {
|
||||||
|
|
||||||
/** Points along the curve of the Bezier curve. */
|
/** Points along the curve of the Bezier curve. */
|
||||||
private Vec2f[] curve;
|
private Vec2f[] curve;
|
||||||
|
|
||||||
|
@ -43,11 +42,10 @@ public abstract class CurveType {
|
||||||
* @return the point [x, y]
|
* @return the point [x, y]
|
||||||
*/
|
*/
|
||||||
public abstract Vec2f pointAt(float t);
|
public abstract Vec2f pointAt(float t);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize the curve points and distance
|
* Initialize the curve points and distance.
|
||||||
* Must be called by inherited classes
|
* Must be called by inherited classes.
|
||||||
*
|
|
||||||
* @param approxlength an approximate length of the curve
|
* @param approxlength an approximate length of the curve
|
||||||
*/
|
*/
|
||||||
public void init(float approxlength) {
|
public void init(float approxlength) {
|
||||||
|
@ -65,6 +63,7 @@ public abstract class CurveType {
|
||||||
totalDistance += curveDis[i];
|
totalDistance += curveDis[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the points along the curve of the Bezier curve.
|
* Returns the points along the curve of the Bezier curve.
|
||||||
*/
|
*/
|
||||||
|
@ -84,5 +83,4 @@ public abstract class CurveType {
|
||||||
* Returns the total distances of this Bezier curve.
|
* Returns the total distances of this Bezier curve.
|
||||||
*/
|
*/
|
||||||
public float totalDistance() { return totalDistance; }
|
public float totalDistance() { return totalDistance; }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,13 +45,11 @@ public abstract class EqualDistanceMultiCurve extends Curve {
|
||||||
*/
|
*/
|
||||||
public EqualDistanceMultiCurve(OsuHitObject hitObject, Color color) {
|
public EqualDistanceMultiCurve(OsuHitObject hitObject, Color color) {
|
||||||
super(hitObject, color);
|
super(hitObject, color);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize the curve points with equal distance
|
* Initialize the curve points with equal distance.
|
||||||
* Must be called by inherited classes
|
* Must be called by inherited classes.
|
||||||
*
|
|
||||||
* @param curvesList a list of curves to join
|
* @param curvesList a list of curves to join
|
||||||
*/
|
*/
|
||||||
public void init(LinkedList<CurveType> curvesList){
|
public void init(LinkedList<CurveType> curvesList){
|
||||||
|
@ -116,7 +114,7 @@ public abstract class EqualDistanceMultiCurve extends Curve {
|
||||||
this.endAngle = (float) (Math.atan2(c2.y - c1.y, c2.x - c1.x) * 180 / Math.PI);
|
this.endAngle = (float) (Math.atan2(c2.y - c1.y, c2.x - c1.x) * 180 / Math.PI);
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public float[] pointAt(float t) {
|
public float[] pointAt(float t) {
|
||||||
float indexF = t * ncurve;
|
float indexF = t * ncurve;
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
package itdelatrisu.opsu.objects.curves;
|
package itdelatrisu.opsu.objects.curves;
|
||||||
|
|
||||||
import itdelatrisu.opsu.OsuHitObject;
|
import itdelatrisu.opsu.OsuHitObject;
|
||||||
|
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
|
|
||||||
import org.newdawn.slick.Color;
|
import org.newdawn.slick.Color;
|
||||||
|
@ -30,29 +31,28 @@ import org.newdawn.slick.Color;
|
||||||
* @author fluddokt (https://github.com/fluddokt)
|
* @author fluddokt (https://github.com/fluddokt)
|
||||||
*/
|
*/
|
||||||
public class LinearBezier extends EqualDistanceMultiCurve {
|
public class LinearBezier extends EqualDistanceMultiCurve {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor.
|
* Constructor.
|
||||||
* @param hitObject the associated OsuHitObject
|
* @param hitObject the associated OsuHitObject
|
||||||
* @param color the color of this curve
|
* @param color the color of this curve
|
||||||
|
* @param line whether a new curve should be generated for each sequential pair
|
||||||
*/
|
*/
|
||||||
public LinearBezier(OsuHitObject hitObject, Color color, boolean line) {
|
public LinearBezier(OsuHitObject hitObject, Color color, boolean line) {
|
||||||
super(hitObject, color);
|
super(hitObject, color);
|
||||||
|
|
||||||
LinkedList<CurveType> beziers = new LinkedList<CurveType>();
|
LinkedList<CurveType> beziers = new LinkedList<CurveType>();
|
||||||
|
|
||||||
// Beziers: splits points into different Beziers if has the same points (red points)
|
// Beziers: splits points into different Beziers if has the same points (red points)
|
||||||
// a b c - c d - d e f g
|
// a b c - c d - d e f g
|
||||||
// Lines: generate a new curve for each sequential pair
|
// Lines: generate a new curve for each sequential pair
|
||||||
// ab bc cd de ef fg
|
// ab bc cd de ef fg
|
||||||
|
|
||||||
int controlPoints = hitObject.getSliderX().length + 1;
|
int controlPoints = hitObject.getSliderX().length + 1;
|
||||||
LinkedList<Vec2f> points = new LinkedList<Vec2f>(); // temporary list of points to separate different Bezier curves
|
LinkedList<Vec2f> points = new LinkedList<Vec2f>(); // temporary list of points to separate different Bezier curves
|
||||||
Vec2f lastPoi = null;
|
Vec2f lastPoi = null;
|
||||||
for (int i = 0; i < controlPoints; i++) {
|
for (int i = 0; i < controlPoints; i++) {
|
||||||
Vec2f tpoi = new Vec2f(getX(i), getY(i));
|
Vec2f tpoi = new Vec2f(getX(i), getY(i));
|
||||||
if (line) {
|
if (line) {
|
||||||
if(lastPoi != null) {
|
if (lastPoi != null) {
|
||||||
points.add(tpoi);
|
points.add(tpoi);
|
||||||
beziers.add(new Bezier2(points.toArray(new Vec2f[0])));
|
beziers.add(new Bezier2(points.toArray(new Vec2f[0])));
|
||||||
points.clear();
|
points.clear();
|
||||||
|
@ -72,7 +72,7 @@ public class LinearBezier extends EqualDistanceMultiCurve {
|
||||||
beziers.add(new Bezier2(points.toArray(new Vec2f[0])));
|
beziers.add(new Bezier2(points.toArray(new Vec2f[0])));
|
||||||
points.clear();
|
points.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
init(beziers);
|
init(beziers);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,7 +70,7 @@ public class Vec2f {
|
||||||
y += o.y;
|
y += o.y;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Subtracts a vector from this vector.
|
* Subtracts a vector from this vector.
|
||||||
* @param o the other vector
|
* @param o the other vector
|
||||||
|
@ -120,7 +120,6 @@ public class Vec2f {
|
||||||
*/
|
*/
|
||||||
public boolean equals(Vec2f o) { return (x == o.x && y == o.y); }
|
public boolean equals(Vec2f o) { return (x == o.x && y == o.y); }
|
||||||
|
|
||||||
public String toString(){
|
@Override
|
||||||
return "Vec2f:"+x+" "+y;
|
public String toString() { return String.format("(%.3f, %.3f)", x, y); }
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1044,8 +1044,6 @@ public class Game extends BasicGameState {
|
||||||
resetGameData();
|
resetGameData();
|
||||||
|
|
||||||
// load the first timingPoint for stacking
|
// load the first timingPoint for stacking
|
||||||
timingPointIndex = 0;
|
|
||||||
beatLengthBase = beatLength = 1;
|
|
||||||
if (!osu.timingPoints.isEmpty()) {
|
if (!osu.timingPoints.isEmpty()) {
|
||||||
OsuTimingPoint timingPoint = osu.timingPoints.get(0);
|
OsuTimingPoint timingPoint = osu.timingPoints.get(0);
|
||||||
if (!timingPoint.isInherited()) {
|
if (!timingPoint.isInherited()) {
|
||||||
|
@ -1053,6 +1051,7 @@ public class Game extends BasicGameState {
|
||||||
timingPointIndex++;
|
timingPointIndex++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// initialize object maps
|
// initialize object maps
|
||||||
for (int i = 0; i < osu.objects.length; i++) {
|
for (int i = 0; i < osu.objects.length; i++) {
|
||||||
OsuHitObject hitObject = osu.objects[i];
|
OsuHitObject hitObject = osu.objects[i];
|
||||||
|
|
Loading…
Reference in New Issue
Block a user