diff --git a/src/itdelatrisu/opsu/GameData.java b/src/itdelatrisu/opsu/GameData.java index b2a065ca..0afcfe7f 100644 --- a/src/itdelatrisu/opsu/GameData.java +++ b/src/itdelatrisu/opsu/GameData.java @@ -26,6 +26,7 @@ import itdelatrisu.opsu.beatmap.Beatmap; import itdelatrisu.opsu.beatmap.HitObject; import itdelatrisu.opsu.downloads.Updater; import itdelatrisu.opsu.objects.curves.Curve; +import itdelatrisu.opsu.objects.curves.Vec2f; import itdelatrisu.opsu.replay.Replay; import itdelatrisu.opsu.replay.ReplayFrame; import itdelatrisu.opsu.ui.Colors; @@ -1379,9 +1380,9 @@ public class GameData { // sliders: add the other curve endpoint for the hit animation if (curve != null) { boolean isFirst = (hitResultType == HitObjectType.SLIDER_FIRST); - float[] p = curve.pointAt((isFirst) ? 1f : 0f); + Vec2f p = curve.pointAt((isFirst) ? 1f : 0f); HitObjectType type = (isFirst) ? HitObjectType.SLIDER_LAST : HitObjectType.SLIDER_FIRST; - hitResultList.add(new HitObjectResult(time, hitResult, p[0], p[1], color, type, null, expand, hideResult)); + hitResultList.add(new HitObjectResult(time, hitResult, p.x, p.y, color, type, null, expand, hideResult)); } } diff --git a/src/itdelatrisu/opsu/beatmap/BeatmapDifficultyCalculator.java b/src/itdelatrisu/opsu/beatmap/BeatmapDifficultyCalculator.java index 2d2dc920..6cf29528 100644 --- a/src/itdelatrisu/opsu/beatmap/BeatmapDifficultyCalculator.java +++ b/src/itdelatrisu/opsu/beatmap/BeatmapDifficultyCalculator.java @@ -539,7 +539,6 @@ class tpSlider { float t = (time - startTime) / sliderTime; float floor = (float) Math.floor(t); t = (floor % 2 == 0) ? t - floor : floor + 1 - t; - float[] xy = curve.pointAt(t); - return new Vec2f(xy[0], xy[1]); + return curve.pointAt(t); } } diff --git a/src/itdelatrisu/opsu/objects/Circle.java b/src/itdelatrisu/opsu/objects/Circle.java index fca7073e..15e94524 100644 --- a/src/itdelatrisu/opsu/objects/Circle.java +++ b/src/itdelatrisu/opsu/objects/Circle.java @@ -25,6 +25,7 @@ import itdelatrisu.opsu.GameMod; import itdelatrisu.opsu.Options; import itdelatrisu.opsu.Utils; import itdelatrisu.opsu.beatmap.HitObject; +import itdelatrisu.opsu.objects.curves.Vec2f; import itdelatrisu.opsu.states.Game; import itdelatrisu.opsu.ui.Colors; @@ -194,7 +195,7 @@ public class Circle implements GameObject { } @Override - public float[] getPointAt(int trackPosition) { return new float[] { x, y }; } + public Vec2f getPointAt(int trackPosition) { return new Vec2f(x, y); } @Override public int getEndTime() { return hitObject.getTime(); } diff --git a/src/itdelatrisu/opsu/objects/DummyObject.java b/src/itdelatrisu/opsu/objects/DummyObject.java index 45c9c1ed..a5426ba6 100644 --- a/src/itdelatrisu/opsu/objects/DummyObject.java +++ b/src/itdelatrisu/opsu/objects/DummyObject.java @@ -19,6 +19,7 @@ package itdelatrisu.opsu.objects; import itdelatrisu.opsu.beatmap.HitObject; +import itdelatrisu.opsu.objects.curves.Vec2f; import org.newdawn.slick.Graphics; @@ -53,7 +54,7 @@ public class DummyObject implements GameObject { public boolean mousePressed(int x, int y, int trackPosition) { return false; } @Override - public float[] getPointAt(int trackPosition) { return new float[] { x, y }; } + public Vec2f getPointAt(int trackPosition) { return new Vec2f(x, y); } @Override public int getEndTime() { return hitObject.getTime(); } diff --git a/src/itdelatrisu/opsu/objects/GameObject.java b/src/itdelatrisu/opsu/objects/GameObject.java index 2a40ca47..f1f788d2 100644 --- a/src/itdelatrisu/opsu/objects/GameObject.java +++ b/src/itdelatrisu/opsu/objects/GameObject.java @@ -18,6 +18,8 @@ package itdelatrisu.opsu.objects; +import itdelatrisu.opsu.objects.curves.Vec2f; + import org.newdawn.slick.Graphics; /** @@ -55,9 +57,9 @@ public interface GameObject { /** * Returns the coordinates of the hit object at a given track position. * @param trackPosition the track position - * @return the [x,y] coordinates + * @return the position vector */ - public float[] getPointAt(int trackPosition); + public Vec2f getPointAt(int trackPosition); /** * Returns the end time of the hit object. diff --git a/src/itdelatrisu/opsu/objects/Slider.java b/src/itdelatrisu/opsu/objects/Slider.java index 65cfc257..2d2476b4 100644 --- a/src/itdelatrisu/opsu/objects/Slider.java +++ b/src/itdelatrisu/opsu/objects/Slider.java @@ -27,6 +27,7 @@ import itdelatrisu.opsu.Utils; import itdelatrisu.opsu.beatmap.Beatmap; import itdelatrisu.opsu.beatmap.HitObject; import itdelatrisu.opsu.objects.curves.Curve; +import itdelatrisu.opsu.objects.curves.Vec2f; import itdelatrisu.opsu.states.Game; import itdelatrisu.opsu.ui.Colors; @@ -184,14 +185,14 @@ public class Slider implements GameObject { Colors.WHITE_FADE.a = color.a = alpha; Image hitCircleOverlay = GameImage.HITCIRCLE_OVERLAY.getImage(); Image hitCircle = GameImage.HITCIRCLE.getImage(); - float[] endPos = curve.pointAt(1); + Vec2f endPos = curve.pointAt(1); curve.draw(color); color.a = alpha; // end circle - hitCircle.drawCentered(endPos[0], endPos[1], color); - hitCircleOverlay.drawCentered(endPos[0], endPos[1], Colors.WHITE_FADE); + hitCircle.drawCentered(endPos.x, endPos.y, color); + hitCircleOverlay.drawCentered(endPos.x, endPos.y, Colors.WHITE_FADE); // start circle hitCircle.drawCentered(x, y, color); @@ -202,8 +203,8 @@ public class Slider implements GameObject { if (ticksT != null) { Image tick = GameImage.SLIDER_TICK.getImage(); for (int i = 0; i < ticksT.length; i++) { - float[] c = curve.pointAt(ticksT[i]); - tick.drawCentered(c[0], c[1], Colors.WHITE_FADE); + Vec2f c = curve.pointAt(ticksT[i]); + tick.drawCentered(c.x, c.y, Colors.WHITE_FADE); } } if (GameMod.HIDDEN.isActive()) { @@ -236,7 +237,7 @@ public class Slider implements GameObject { if (tcurRepeat % 2 == 0) { // last circle arrow.setRotation(curve.getEndAngle()); - arrow.drawCentered(endPos[0], endPos[1]); + arrow.drawCentered(endPos.x, endPos.y); } else { // first circle arrow.setRotation(curve.getStartAngle()); @@ -255,20 +256,20 @@ public class Slider implements GameObject { if (sliderTime == 0) return; - float[] c = curve.pointAt(getT(trackPosition, false)); - float[] c2 = curve.pointAt(getT(trackPosition, false) + 0.01f); + Vec2f c = curve.pointAt(getT(trackPosition, false)); + Vec2f c2 = curve.pointAt(getT(trackPosition, false) + 0.01f); float t = getT(trackPosition, false); // float dis = hitObject.getPixelLength() * HitObject.getXMultiplier() * (t - (int) t); // Image sliderBallFrame = sliderBallImages[(int) (dis / (diameter * Math.PI) * 30) % sliderBallImages.length]; Image sliderBallFrame = sliderBallImages[(int) (t * sliderTime * 60 / 1000) % sliderBallImages.length]; - float angle = (float) (Math.atan2(c2[1] - c[1], c2[0] - c[0]) * 180 / Math.PI); + float angle = (float) (Math.atan2(c2.y - c.y, c2.x - c.x) * 180 / Math.PI); sliderBallFrame.setRotation(angle); - sliderBallFrame.drawCentered(c[0], c[1]); + sliderBallFrame.drawCentered(c.x, c.y); // follow circle if (followCircleActive) { - GameImage.SLIDER_FOLLOWCIRCLE.getImage().drawCentered(c[0], c[1]); + GameImage.SLIDER_FOLLOWCIRCLE.getImage().drawCentered(c.x, c.y); // "flashlight" mod: dim the screen if (GameMod.FLASHLIGHT.isActive()) { @@ -351,9 +352,9 @@ public class Slider implements GameObject { float cx, cy; HitObjectType type; if (currentRepeats % 2 == 0) { // last circle - float[] lastPos = curve.pointAt(1); - cx = lastPos[0]; - cy = lastPos[1]; + Vec2f lastPos = curve.pointAt(1); + cx = lastPos.x; + cy = lastPos.y; type = HitObjectType.SLIDER_LAST; } else { // first circle cx = x; @@ -434,8 +435,8 @@ public class Slider implements GameObject { // check if cursor pressed and within end circle if (keyPressed || GameMod.RELAX.isActive()) { - float[] c = curve.pointAt(getT(trackPosition, false)); - double distance = Math.hypot(c[0] - mouseX, c[1] - mouseY); + Vec2f c = curve.pointAt(getT(trackPosition, false)); + double distance = Math.hypot(c.x - mouseX, c.y - mouseY); if (distance < followRadius) sliderHeldToEnd = true; } @@ -478,8 +479,8 @@ public class Slider implements GameObject { } // holding slider... - float[] c = curve.pointAt(getT(trackPosition, false)); - double distance = Math.hypot(c[0] - mouseX, c[1] - mouseY); + Vec2f c = curve.pointAt(getT(trackPosition, false)); + double distance = Math.hypot(c.x - mouseX, c.y - mouseY); if (((keyPressed || GameMod.RELAX.isActive()) && distance < followRadius) || isAutoMod) { // mouse pressed and within follow circle followCircleActive = true; @@ -493,14 +494,14 @@ public class Slider implements GameObject { curve.getX(lastIndex), curve.getY(lastIndex), hitObject, currentRepeats); } else // first circle data.sliderTickResult(trackPosition, GameData.HIT_SLIDER30, - c[0], c[1], hitObject, currentRepeats); + c.x, c.y, hitObject, currentRepeats); } // held during new tick if (isNewTick) { ticksHit++; data.sliderTickResult(trackPosition, GameData.HIT_SLIDER10, - c[0], c[1], hitObject, currentRepeats); + c.x, c.y, hitObject, currentRepeats); } // held near end of slider @@ -526,12 +527,12 @@ public class Slider implements GameObject { } @Override - public float[] getPointAt(int trackPosition) { + public Vec2f getPointAt(int trackPosition) { if (trackPosition <= hitObject.getTime()) - return new float[] { x, y }; + return new Vec2f(x, y); else if (trackPosition >= hitObject.getTime() + sliderTimeTotal) { if (hitObject.getRepeatCount() % 2 == 0) - return new float[] { x, y }; + return new Vec2f(x, y); else return curve.pointAt(1); } else diff --git a/src/itdelatrisu/opsu/objects/Spinner.java b/src/itdelatrisu/opsu/objects/Spinner.java index 1ac9d7cd..e82fa6a3 100644 --- a/src/itdelatrisu/opsu/objects/Spinner.java +++ b/src/itdelatrisu/opsu/objects/Spinner.java @@ -27,6 +27,7 @@ import itdelatrisu.opsu.Utils; import itdelatrisu.opsu.audio.SoundController; import itdelatrisu.opsu.audio.SoundEffect; import itdelatrisu.opsu.beatmap.HitObject; +import itdelatrisu.opsu.objects.curves.Vec2f; import itdelatrisu.opsu.states.Game; import itdelatrisu.opsu.ui.Colors; @@ -347,7 +348,7 @@ public class Spinner implements GameObject { public void updatePosition() {} @Override - public float[] getPointAt(int trackPosition) { + public Vec2f getPointAt(int trackPosition) { // get spinner time int timeDiff; float x = hitObject.getScaledX(), y = hitObject.getScaledY(); @@ -362,10 +363,7 @@ public class Spinner implements GameObject { float multiplier = (GameMod.AUTO.isActive()) ? AUTO_MULTIPLIER : SPUN_OUT_MULTIPLIER; float angle = (timeDiff * multiplier) - HALF_PI; final float r = height / 10f; - return new float[] { - (float) (x + r * Math.cos(angle)), - (float) (y + r * Math.sin(angle)) - }; + return new Vec2f((float) (x + r * Math.cos(angle)), (float) (y + r * Math.sin(angle))); } @Override diff --git a/src/itdelatrisu/opsu/objects/curves/CircumscribedCircle.java b/src/itdelatrisu/opsu/objects/curves/CircumscribedCircle.java index 9563384e..866ade2e 100644 --- a/src/itdelatrisu/opsu/objects/curves/CircumscribedCircle.java +++ b/src/itdelatrisu/opsu/objects/curves/CircumscribedCircle.java @@ -115,10 +115,8 @@ public class CircumscribedCircle extends Curve { // calculate points float step = hitObject.getPixelLength() / CURVE_POINTS_SEPERATION; curve = new Vec2f[(int) step + 1]; - for (int i = 0; i < curve.length; i++) { - float[] xy = pointAt(i / step); - curve[i] = new Vec2f(xy[0], xy[1]); - } + for (int i = 0; i < curve.length; i++) + curve[i] = pointAt(i / step); } /** @@ -157,12 +155,12 @@ public class CircumscribedCircle extends Curve { } @Override - public float[] pointAt(float t) { + public Vec2f pointAt(float t) { float ang = Utils.lerp(startAng, endAng, t); - return new float[] { + return new Vec2f( (float) (Math.cos(ang) * radius + circleCenter.x), (float) (Math.sin(ang) * radius + circleCenter.y) - }; + ); } @Override diff --git a/src/itdelatrisu/opsu/objects/curves/Curve.java b/src/itdelatrisu/opsu/objects/curves/Curve.java index 90eac4da..313013db 100644 --- a/src/itdelatrisu/opsu/objects/curves/Curve.java +++ b/src/itdelatrisu/opsu/objects/curves/Curve.java @@ -106,9 +106,9 @@ public abstract class Curve { /** * Returns the point on the curve at a value t. * @param t the t value [0, 1] - * @return the point [x, y] + * @return the position vector */ - public abstract float[] pointAt(float t); + public abstract Vec2f pointAt(float t); /** * Draws the full curve to the graphics context. diff --git a/src/itdelatrisu/opsu/objects/curves/EqualDistanceMultiCurve.java b/src/itdelatrisu/opsu/objects/curves/EqualDistanceMultiCurve.java index 5b1353cd..4393d1aa 100644 --- a/src/itdelatrisu/opsu/objects/curves/EqualDistanceMultiCurve.java +++ b/src/itdelatrisu/opsu/objects/curves/EqualDistanceMultiCurve.java @@ -124,20 +124,19 @@ public abstract class EqualDistanceMultiCurve extends Curve { } @Override - public float[] pointAt(float t) { + public Vec2f pointAt(float t) { float indexF = t * ncurve; int index = (int) indexF; - if (index >= ncurve) { - Vec2f poi = curve[ncurve]; - return new float[] { poi.x, poi.y }; - } else { + if (index >= ncurve) + return curve[ncurve].cpy(); + else { Vec2f poi = curve[index]; Vec2f poi2 = curve[index + 1]; float t2 = indexF - index; - return new float[] { + return new Vec2f( Utils.lerp(poi.x, poi2.x, t2), Utils.lerp(poi.y, poi2.y, t2) - }; + ); } } diff --git a/src/itdelatrisu/opsu/objects/curves/Vec2f.java b/src/itdelatrisu/opsu/objects/curves/Vec2f.java index 08d7c8bf..3858823d 100644 --- a/src/itdelatrisu/opsu/objects/curves/Vec2f.java +++ b/src/itdelatrisu/opsu/objects/curves/Vec2f.java @@ -40,6 +40,16 @@ public class Vec2f { */ public Vec2f() {} + /** + * Sets the x and y components of this vector. + * @return itself (for chaining) + */ + public Vec2f set(float nx, float ny) { + x = nx; + y = ny; + return this; + } + /** * Finds the midpoint between this vector and another vector. * @param o the other vector diff --git a/src/itdelatrisu/opsu/states/Game.java b/src/itdelatrisu/opsu/states/Game.java index f4cff494..0bfa1d54 100644 --- a/src/itdelatrisu/opsu/states/Game.java +++ b/src/itdelatrisu/opsu/states/Game.java @@ -42,6 +42,7 @@ import itdelatrisu.opsu.objects.GameObject; import itdelatrisu.opsu.objects.Slider; import itdelatrisu.opsu.objects.Spinner; import itdelatrisu.opsu.objects.curves.Curve; +import itdelatrisu.opsu.objects.curves.Vec2f; import itdelatrisu.opsu.render.FrameBufferCache; import itdelatrisu.opsu.replay.PlaybackSpeed; import itdelatrisu.opsu.replay.Replay; @@ -158,7 +159,7 @@ public class Game extends BasicGameState { countdown2Sound, countdownGoSound; /** Mouse coordinates before game paused. */ - private int pausedMouseX = -1, pausedMouseY = -1; + private Vec2f pausedMousePosition; /** Track position when game paused. */ private int pauseTime = -1; @@ -221,7 +222,7 @@ public class Game extends BasicGameState { private int flashlightRadius; /** The cursor coordinates using the "auto" or "relax" mods. */ - private int autoMouseX = 0, autoMouseY = 0; + private Vec2f autoMousePosition; /** Whether or not the cursor should be pressed using the "auto" mod. */ private boolean autoMousePressed; @@ -317,32 +318,31 @@ public class Game extends BasicGameState { // "auto" and "autopilot" mods: move cursor automatically // TODO: this should really be in update(), not render() - autoMouseX = width / 2; - autoMouseY = height / 2; + autoMousePosition.set(width / 2, height / 2); autoMousePressed = false; if (GameMod.AUTO.isActive() || GameMod.AUTOPILOT.isActive()) { - float[] autoXY = null; + Vec2f autoPoint = null; if (isLeadIn()) { // lead-in float progress = Math.max((float) (leadInTime - beatmap.audioLeadIn) / approachTime, 0f); - autoMouseY = (int) (height / (2f - progress)); + autoMousePosition.y = height / (2f - progress); } else if (objectIndex == 0 && trackPosition < firstObjectTime) { // before first object timeDiff = firstObjectTime - trackPosition; if (timeDiff < approachTime) { - float[] xy = gameObjects[0].getPointAt(trackPosition); - autoXY = getPointAt(autoMouseX, autoMouseY, xy[0], xy[1], 1f - ((float) timeDiff / approachTime)); + Vec2f point = gameObjects[0].getPointAt(trackPosition); + autoPoint = getPointAt(autoMousePosition.x, autoMousePosition.y, point.x, point.y, 1f - ((float) timeDiff / approachTime)); } } else if (objectIndex < beatmap.objects.length) { // normal object int objectTime = beatmap.objects[objectIndex].getTime(); if (trackPosition < objectTime) { - float[] xyStart = gameObjects[objectIndex - 1].getPointAt(trackPosition); + Vec2f startPoint = gameObjects[objectIndex - 1].getPointAt(trackPosition); int startTime = gameObjects[objectIndex - 1].getEndTime(); if (beatmap.breaks != null && breakIndex < beatmap.breaks.size()) { // starting a break: keep cursor at previous hit object position if (breakTime > 0 || objectTime > beatmap.breaks.get(breakIndex)) - autoXY = xyStart; + autoPoint = startPoint; // after a break ends: move startTime to break end time else if (breakIndex > 1) { @@ -351,10 +351,10 @@ public class Game extends BasicGameState { startTime = lastBreakEndTime; } } - if (autoXY == null) { - float[] xyEnd = gameObjects[objectIndex].getPointAt(trackPosition); + if (autoPoint == null) { + Vec2f endPoint = gameObjects[objectIndex].getPointAt(trackPosition); int totalTime = objectTime - startTime; - autoXY = getPointAt(xyStart[0], xyStart[1], xyEnd[0], xyEnd[1], (float) (trackPosition - startTime) / totalTime); + autoPoint = getPointAt(startPoint.x, startPoint.y, endPoint.x, endPoint.y, (float) (trackPosition - startTime) / totalTime); // hit circles: show a mouse press int offset300 = hitResultOffset[GameData.HIT_300]; @@ -363,19 +363,17 @@ public class Game extends BasicGameState { autoMousePressed = true; } } else { - autoXY = gameObjects[objectIndex].getPointAt(trackPosition); + autoPoint = gameObjects[objectIndex].getPointAt(trackPosition); autoMousePressed = true; } } else { // last object - autoXY = gameObjects[objectIndex - 1].getPointAt(trackPosition); + autoPoint = gameObjects[objectIndex - 1].getPointAt(trackPosition); } // set mouse coordinates - if (autoXY != null) { - autoMouseX = (int) autoXY[0]; - autoMouseY = (int) autoXY[1]; - } + if (autoPoint != null) + autoMousePosition.set(autoPoint.x, autoPoint.y); } // "flashlight" mod: restricted view of hit objects around cursor @@ -393,12 +391,12 @@ public class Game extends BasicGameState { g.setDrawMode(Graphics.MODE_ALPHA_MAP); g.clearAlphaMap(); int mouseX, mouseY; - if (pauseTime > -1 && pausedMouseX > -1 && pausedMouseY > -1) { - mouseX = pausedMouseX; - mouseY = pausedMouseY; + if (pauseTime > -1 && pausedMousePosition != null) { + mouseX = (int) pausedMousePosition.x; + mouseY = (int) pausedMousePosition.y; } else if (GameMod.AUTO.isActive() || GameMod.AUTOPILOT.isActive()) { - mouseX = autoMouseX; - mouseY = autoMouseY; + mouseX = (int) autoMousePosition.x; + mouseY = (int) autoMousePosition.y; } else if (isReplay) { mouseX = replayX; mouseY = replayY; @@ -565,27 +563,27 @@ public class Game extends BasicGameState { } // returning from pause screen - if (pauseTime > -1 && pausedMouseX > -1 && pausedMouseY > -1) { + if (pauseTime > -1 && pausedMousePosition != null) { // darken the screen g.setColor(Colors.BLACK_ALPHA); g.fillRect(0, 0, width, height); // draw glowing hit select circle and pulse effect - int circleRadius = GameImage.HITCIRCLE.getImage().getWidth(); - Image cursorCircle = GameImage.HITCIRCLE_SELECT.getImage().getScaledCopy(circleRadius, circleRadius); + int circleDiameter = GameImage.HITCIRCLE.getImage().getWidth(); + Image cursorCircle = GameImage.HITCIRCLE_SELECT.getImage().getScaledCopy(circleDiameter, circleDiameter); cursorCircle.setAlpha(1.0f); - cursorCircle.drawCentered(pausedMouseX, pausedMouseY); + cursorCircle.drawCentered(pausedMousePosition.x, pausedMousePosition.y); Image cursorCirclePulse = cursorCircle.getScaledCopy(1f + pausePulse); cursorCirclePulse.setAlpha(1f - pausePulse); - cursorCirclePulse.drawCentered(pausedMouseX, pausedMouseY); + cursorCirclePulse.drawCentered(pausedMousePosition.x, pausedMousePosition.y); } if (isReplay) UI.draw(g, replayX, replayY, replayKeyPressed); else if (GameMod.AUTO.isActive()) - UI.draw(g, autoMouseX, autoMouseY, autoMousePressed); + UI.draw(g, (int) autoMousePosition.x, (int) autoMousePosition.y, autoMousePressed); else if (GameMod.AUTOPILOT.isActive()) - UI.draw(g, autoMouseX, autoMouseY, Utils.isGameKeyPressed()); + UI.draw(g, (int) autoMousePosition.x, (int) autoMousePosition.y, Utils.isGameKeyPressed()); else UI.draw(g); } @@ -603,8 +601,7 @@ public class Game extends BasicGameState { // returning from pause screen: must click previous mouse position if (pauseTime > -1) { // paused during lead-in or break, or "relax" or "autopilot": continue immediately - if ((pausedMouseX < 0 && pausedMouseY < 0) || - (GameMod.RELAX.isActive() || GameMod.AUTOPILOT.isActive())) { + if (pausedMousePosition == null || (GameMod.RELAX.isActive() || GameMod.AUTOPILOT.isActive())) { pauseTime = -1; if (!isLeadIn()) MusicController.resume(); @@ -791,8 +788,7 @@ public class Game extends BasicGameState { // pause game if focus lost if (!container.hasFocus() && !GameMod.AUTO.isActive() && !isReplay) { if (pauseTime < 0) { - pausedMouseX = mouseX; - pausedMouseY = mouseY; + pausedMousePosition = new Vec2f(mouseX, mouseY); pausePulse = 0f; } if (MusicController.isPlaying() || isLeadIn()) @@ -865,8 +861,7 @@ public class Game extends BasicGameState { // pause game if (pauseTime < 0 && breakTime <= 0 && trackPosition >= beatmap.objects[0].getTime()) { - pausedMouseX = mouseX; - pausedMouseY = mouseY; + pausedMousePosition = new Vec2f(mouseX, mouseY); pausePulse = 0f; } if (MusicController.isPlaying() || isLeadIn()) @@ -993,8 +988,7 @@ public class Game extends BasicGameState { if (button == Input.MOUSE_MIDDLE_BUTTON && !Options.isMouseWheelDisabled()) { int trackPosition = MusicController.getPosition(); if (pauseTime < 0 && breakTime <= 0 && trackPosition >= beatmap.objects[0].getTime()) { - pausedMouseX = x; - pausedMouseY = y; + pausedMousePosition = new Vec2f(x, y); pausePulse = 0f; } if (MusicController.isPlaying() || isLeadIn()) @@ -1023,13 +1017,12 @@ public class Game extends BasicGameState { private void gameKeyPressed(int keys, int x, int y, int trackPosition) { // returning from pause screen if (pauseTime > -1) { - double distance = Math.hypot(pausedMouseX - x, pausedMouseY - y); + double distance = Math.hypot(pausedMousePosition.x - x, pausedMousePosition.y - y); int circleRadius = GameImage.HITCIRCLE.getImage().getWidth() / 2; if (distance < circleRadius) { // unpause the game pauseTime = -1; - pausedMouseX = -1; - pausedMouseY = -1; + pausedMousePosition = null; if (!isLeadIn()) MusicController.resume(); } @@ -1303,10 +1296,10 @@ public class Game extends BasicGameState { final int followPointInterval = container.getHeight() / 14; int lastObjectEndTime = gameObjects[lastObjectIndex].getEndTime() + 1; int objectStartTime = beatmap.objects[index].getTime(); - float[] startXY = gameObjects[lastObjectIndex].getPointAt(lastObjectEndTime); - float[] endXY = gameObjects[index].getPointAt(objectStartTime); - float xDiff = endXY[0] - startXY[0]; - float yDiff = endXY[1] - startXY[1]; + Vec2f startPoint = gameObjects[lastObjectIndex].getPointAt(lastObjectEndTime); + Vec2f endPoint = gameObjects[index].getPointAt(objectStartTime); + float xDiff = endPoint.x - startPoint.x; + float yDiff = endPoint.y - startPoint.y; float dist = (float) Math.hypot(xDiff, yDiff); int numPoints = (int) ((dist - GameImage.HITCIRCLE.getImage().getWidth()) / followPointInterval); if (numPoints > 0) { @@ -1327,8 +1320,8 @@ public class Game extends BasicGameState { float step = 1f / (numPoints + 1); float t = step; for (int i = 0; i < numPoints; i++) { - float x = startXY[0] + xDiff * t; - float y = startXY[1] + yDiff * t; + float x = startPoint.x + xDiff * t; + float y = startPoint.y + yDiff * t; float nextT = t + step; if (lastObjectIndex < objectIndex) { // fade the previous trail if (progress < nextT) { @@ -1382,8 +1375,7 @@ public class Game extends BasicGameState { timingPointIndex = 0; beatLengthBase = beatLength = 1; pauseTime = -1; - pausedMouseX = -1; - pausedMouseY = -1; + pausedMousePosition = null; countdownReadySound = false; countdown3Sound = false; countdown1Sound = false; @@ -1394,8 +1386,7 @@ public class Game extends BasicGameState { deathTime = -1; replayFrames = null; lastReplayTime = 0; - autoMouseX = 0; - autoMouseY = 0; + autoMousePosition = new Vec2f(); autoMousePressed = false; flashlightRadius = container.getHeight() * 2 / 3; @@ -1624,8 +1615,8 @@ public class Game extends BasicGameState { public synchronized void addReplayFrameAndRun(int x, int y, int keys, int time){ // "auto" and "autopilot" mods: use automatic cursor coordinates if (GameMod.AUTO.isActive() || GameMod.AUTOPILOT.isActive()) { - x = autoMouseX; - y = autoMouseY; + x = (int) autoMousePosition.x; + y = (int) autoMousePosition.y; } ReplayFrame frame = addReplayFrame(x, y, keys, time); @@ -1699,17 +1690,13 @@ public class Game extends BasicGameState { * @param endX the ending x coordinate * @param endY the ending y coordinate * @param t the t value [0, 1] - * @return the [x,y] coordinates + * @return the position vector */ - private float[] getPointAt(float startX, float startY, float endX, float endY, float t) { + private Vec2f getPointAt(float startX, float startY, float endX, float endY, float t) { // "autopilot" mod: move quicker between objects if (GameMod.AUTOPILOT.isActive()) t = Utils.clamp(t * 2f, 0f, 1f); - - float[] xy = new float[2]; - xy[0] = startX + (endX - startX) * t; - xy[1] = startY + (endY - startY) * t; - return xy; + return new Vec2f(startX + (endX - startX) * t, startY + (endY - startY) * t); } /** @@ -1803,9 +1790,9 @@ public class Game extends BasicGameState { // possible special case: if slider end in the stack, // all next hit objects in stack move right down if (hitObjectN.isSlider()) { - float[] p1 = gameObjects[i].getPointAt(hitObjectI.getTime()); - float[] p2 = gameObjects[n].getPointAt(gameObjects[n].getEndTime()); - float distance = Utils.distance(p1[0], p1[1], p2[0], p2[1]); + Vec2f p1 = gameObjects[i].getPointAt(hitObjectI.getTime()); + Vec2f p2 = gameObjects[n].getPointAt(gameObjects[n].getEndTime()); + float distance = Utils.distance(p1.x, p1.y, p2.x, p2.y); // check if hit object part of this stack if (distance < STACK_LENIENCE * HitObject.getXMultiplier()) { @@ -1813,7 +1800,7 @@ public class Game extends BasicGameState { for (int j = n + 1; j <= i; j++) { HitObject hitObjectJ = beatmap.objects[j]; p1 = gameObjects[j].getPointAt(hitObjectJ.getTime()); - distance = Utils.distance(p1[0], p1[1], p2[0], p2[1]); + distance = Utils.distance(p1.x, p1.y, p2.x, p2.y); // hit object below slider end if (distance < STACK_LENIENCE * HitObject.getXMultiplier())