Follow-up to #52.
- Animate skip button during lead in. - Update flashlight radius during lead in. - Check if keys are set before calling gameKeyPressed(). - Deleted mouse moved/dragged events (no longer used). - Renamed updateGameKeyPress(). - Added "auto"/"relax" mod checks to gameKeyPressed(). Also fixed a bug where the MenuButton class wasn't properly resetting image alpha/rotation in certain cases. Signed-off-by: Jeffrey Han <itdelatrisu@gmail.com>
This commit is contained in:
parent
ba20953634
commit
b46c589b97
|
@ -1236,12 +1236,12 @@ public class GameData {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a Replay object encapsulating all game data.
|
* Returns a Replay object encapsulating all game data.
|
||||||
* If a replay already exists and frames is null, the existing object will
|
* If a replay already exists and frames is null, the existing object will be returned.
|
||||||
* be returned.
|
|
||||||
* @param frames the replay frames
|
* @param frames the replay frames
|
||||||
|
* @param osu the associated OsuFile
|
||||||
* @return the Replay object, or null if none exists and frames is null
|
* @return the Replay object, or null if none exists and frames is null
|
||||||
*/
|
*/
|
||||||
public Replay getReplay(ReplayFrame[] frames, OsuFile file) {
|
public Replay getReplay(ReplayFrame[] frames, OsuFile osu) {
|
||||||
if (replay != null && frames == null)
|
if (replay != null && frames == null)
|
||||||
return replay;
|
return replay;
|
||||||
|
|
||||||
|
@ -1251,7 +1251,7 @@ public class GameData {
|
||||||
replay = new Replay();
|
replay = new Replay();
|
||||||
replay.mode = OsuFile.MODE_OSU;
|
replay.mode = OsuFile.MODE_OSU;
|
||||||
replay.version = Updater.get().getBuildDate();
|
replay.version = Updater.get().getBuildDate();
|
||||||
replay.beatmapHash = Utils.getMD5(file.getFile());
|
replay.beatmapHash = (osu == null) ? "" : Utils.getMD5(osu.getFile());
|
||||||
replay.playerName = ""; // TODO
|
replay.playerName = ""; // TODO
|
||||||
replay.replayHash = Long.toString(System.currentTimeMillis()); // TODO
|
replay.replayHash = Long.toString(System.currentTimeMillis()); // TODO
|
||||||
replay.hit300 = (short) hitResultCount[HIT_300];
|
replay.hit300 = (short) hitResultCount[HIT_300];
|
||||||
|
|
|
@ -200,7 +200,7 @@ public class MenuButton {
|
||||||
if ((hoverEffect & EFFECT_ROTATE) > 0)
|
if ((hoverEffect & EFFECT_ROTATE) > 0)
|
||||||
image.setRotation(angle);
|
image.setRotation(angle);
|
||||||
image.draw(x - xRadius, y - yRadius, filter);
|
image.draw(x - xRadius, y - yRadius, filter);
|
||||||
if (image != this.img) {
|
if (image == this.img) {
|
||||||
image.setAlpha(oldAlpha);
|
image.setAlpha(oldAlpha);
|
||||||
image.setRotation(oldAngle);
|
image.setRotation(oldAngle);
|
||||||
}
|
}
|
||||||
|
|
|
@ -542,19 +542,18 @@ public class Utils {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the md5 hash of a file in hex form.
|
* Returns the md5 hash of a file in hex form.
|
||||||
* @param file
|
* @param file the file to hash
|
||||||
* @return the md5 hash
|
* @return the md5 hash
|
||||||
*/
|
*/
|
||||||
public static String getMD5(File file){
|
public static String getMD5(File file) {
|
||||||
try {
|
try {
|
||||||
InputStream in = new BufferedInputStream(new FileInputStream(file));
|
InputStream in = new BufferedInputStream(new FileInputStream(file));
|
||||||
MessageDigest md = MessageDigest.getInstance("MD5");
|
MessageDigest md = MessageDigest.getInstance("MD5");
|
||||||
byte[] buf = new byte[4096];
|
byte[] buf = new byte[4096];
|
||||||
|
|
||||||
while(true) {
|
while (true) {
|
||||||
int len = in.read(buf);
|
int len = in.read(buf);
|
||||||
if (len < 0)
|
if (len < 0)
|
||||||
break;
|
break;
|
||||||
|
@ -564,13 +563,11 @@ public class Utils {
|
||||||
|
|
||||||
byte[] md5byte = md.digest();
|
byte[] md5byte = md.digest();
|
||||||
StringBuilder result = new StringBuilder();
|
StringBuilder result = new StringBuilder();
|
||||||
for (byte b : md5byte) {
|
for (byte b : md5byte)
|
||||||
result.append(String.format("%02x", b));
|
result.append(String.format("%02x", b));
|
||||||
}
|
|
||||||
return result.toString();
|
return result.toString();
|
||||||
} catch (NoSuchAlgorithmException | IOException e) {
|
} catch (NoSuchAlgorithmException | IOException e) {
|
||||||
e.printStackTrace();
|
ErrorHandler.error("Failed to calculate MD5 hash.", e, true);
|
||||||
Log.error(e);
|
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,6 @@ import itdelatrisu.opsu.GameImage;
|
||||||
import itdelatrisu.opsu.GameMod;
|
import itdelatrisu.opsu.GameMod;
|
||||||
import itdelatrisu.opsu.OsuHitObject;
|
import itdelatrisu.opsu.OsuHitObject;
|
||||||
import itdelatrisu.opsu.Utils;
|
import itdelatrisu.opsu.Utils;
|
||||||
import itdelatrisu.opsu.audio.MusicController;
|
|
||||||
import itdelatrisu.opsu.states.Game;
|
import itdelatrisu.opsu.states.Game;
|
||||||
|
|
||||||
import org.newdawn.slick.Color;
|
import org.newdawn.slick.Color;
|
||||||
|
|
|
@ -38,7 +38,7 @@ public interface HitObject {
|
||||||
* @param mouseX the x coordinate of the mouse
|
* @param mouseX the x coordinate of the mouse
|
||||||
* @param mouseY the y coordinate of the mouse
|
* @param mouseY the y coordinate of the mouse
|
||||||
* @param keyPressed whether or not a game key is currently pressed
|
* @param keyPressed whether or not a game key is currently pressed
|
||||||
* @param trackPosition the track Position
|
* @param trackPosition the track position
|
||||||
* @return true if object ended
|
* @return true if object ended
|
||||||
*/
|
*/
|
||||||
public boolean update(boolean overlap, int delta, int mouseX, int mouseY, boolean keyPressed, int trackPosition);
|
public boolean update(boolean overlap, int delta, int mouseX, int mouseY, boolean keyPressed, int trackPosition);
|
||||||
|
@ -47,7 +47,7 @@ public interface HitObject {
|
||||||
* Processes a mouse click.
|
* Processes a mouse click.
|
||||||
* @param x the x coordinate of the mouse
|
* @param x the x coordinate of the mouse
|
||||||
* @param y the y coordinate of the mouse
|
* @param y the y coordinate of the mouse
|
||||||
* @param trackPosition the track Position
|
* @param trackPosition the track position
|
||||||
* @return true if a hit result was processed
|
* @return true if a hit result was processed
|
||||||
*/
|
*/
|
||||||
public boolean mousePressed(int x, int y, int trackPosition);
|
public boolean mousePressed(int x, int y, int trackPosition);
|
||||||
|
|
|
@ -38,7 +38,7 @@ import org.newdawn.slick.Image;
|
||||||
* Data type representing a slider object.
|
* Data type representing a slider object.
|
||||||
*/
|
*/
|
||||||
public class Slider implements HitObject {
|
public class Slider implements HitObject {
|
||||||
/** Slider ball animation. */
|
/** Slider ball frames. */
|
||||||
private static Image[] sliderBallImages;
|
private static Image[] sliderBallImages;
|
||||||
|
|
||||||
/** Slider movement speed multiplier. */
|
/** Slider movement speed multiplier. */
|
||||||
|
@ -148,7 +148,6 @@ public class Slider implements HitObject {
|
||||||
this.curve = new LinearBezier(hitObject, color);
|
this.curve = new LinearBezier(hitObject, color);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
|
||||||
@Override
|
@Override
|
||||||
public void draw(Graphics g, int trackPosition) {
|
public void draw(Graphics g, int trackPosition) {
|
||||||
int timeDiff = hitObject.getTime() - trackPosition;
|
int timeDiff = hitObject.getTime() - trackPosition;
|
||||||
|
@ -216,23 +215,22 @@ public class Slider implements HitObject {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (timeDiff >= 0) {
|
if (timeDiff >= 0) {
|
||||||
// approach circle
|
// approach circle
|
||||||
color.a = 1 - scale;
|
color.a = 1 - scale;
|
||||||
GameImage.APPROACHCIRCLE.getImage().getScaledCopy(approachScale).drawCentered(x, y, color);
|
GameImage.APPROACHCIRCLE.getImage().getScaledCopy(approachScale).drawCentered(x, y, color);
|
||||||
} else {
|
} else {
|
||||||
//since update might not have run before drawing during replay,
|
// Since update() might not have run before drawing during a replay, the
|
||||||
//the slider time may not have been calculated.
|
// slider time may not have been calculated, which causes NAN numbers and flicker.
|
||||||
//Which will cause NAN numbers and cause flicker.
|
|
||||||
if (sliderTime == 0)
|
if (sliderTime == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
float[] c = curve.pointAt(getT(trackPosition, false));
|
float[] c = curve.pointAt(getT(trackPosition, false));
|
||||||
float[] c2 = curve.pointAt(getT(trackPosition, false) + 0.01f);
|
float[] c2 = curve.pointAt(getT(trackPosition, false) + 0.01f);
|
||||||
|
|
||||||
float t = getT(trackPosition, false);
|
float t = getT(trackPosition, false);
|
||||||
//float dis = hitObject.getPixelLength()*OsuHitObject.getXMultiplier() * (t -(int)t);
|
// float dis = hitObject.getPixelLength() * OsuHitObject.getXMultiplier() * (t - (int) t);
|
||||||
//Image sliderBallFrame = sliderBallImages[ (int)(dis/ (diameter*Math.PI) *30)%sliderBallImages.length];
|
// Image sliderBallFrame = sliderBallImages[(int) (dis / (diameter * Math.PI) * 30) % sliderBallImages.length];
|
||||||
Image sliderBallFrame = sliderBallImages[(int) (t * sliderTime * 60 / 1000) % 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[1] - c[1], c2[0] - c[0]) * 180 / Math.PI);
|
||||||
sliderBallFrame.setRotation(angle);
|
sliderBallFrame.setRotation(angle);
|
||||||
|
|
|
@ -23,7 +23,6 @@ import itdelatrisu.opsu.GameImage;
|
||||||
import itdelatrisu.opsu.GameMod;
|
import itdelatrisu.opsu.GameMod;
|
||||||
import itdelatrisu.opsu.OsuHitObject;
|
import itdelatrisu.opsu.OsuHitObject;
|
||||||
import itdelatrisu.opsu.Utils;
|
import itdelatrisu.opsu.Utils;
|
||||||
import itdelatrisu.opsu.audio.MusicController;
|
|
||||||
import itdelatrisu.opsu.audio.SoundController;
|
import itdelatrisu.opsu.audio.SoundController;
|
||||||
import itdelatrisu.opsu.audio.SoundEffect;
|
import itdelatrisu.opsu.audio.SoundEffect;
|
||||||
import itdelatrisu.opsu.states.Game;
|
import itdelatrisu.opsu.states.Game;
|
||||||
|
|
|
@ -174,7 +174,7 @@ public class Game extends BasicGameState {
|
||||||
/** The last replay frame time. */
|
/** The last replay frame time. */
|
||||||
private int lastReplayTime = 0;
|
private int lastReplayTime = 0;
|
||||||
|
|
||||||
/** The keys from the previous replayFrame */
|
/** The keys from the previous replay frame. */
|
||||||
private int lastReplayKeys = 0;
|
private int lastReplayKeys = 0;
|
||||||
|
|
||||||
/** The last game keys pressed. */
|
/** The last game keys pressed. */
|
||||||
|
@ -526,29 +526,30 @@ public class Game extends BasicGameState {
|
||||||
public void update(GameContainer container, StateBasedGame game, int delta)
|
public void update(GameContainer container, StateBasedGame game, int delta)
|
||||||
throws SlickException {
|
throws SlickException {
|
||||||
UI.update(delta);
|
UI.update(delta);
|
||||||
int mouseX, mouseY;
|
int mouseX = input.getMouseX(), mouseY = input.getMouseY();
|
||||||
mouseX = input.getMouseX();
|
skipButton.hoverUpdate(delta, mouseX, mouseY);
|
||||||
mouseY = input.getMouseY();
|
int trackPosition = MusicController.getPosition();
|
||||||
if (isLeadIn()) { // stop updating during song lead-in
|
|
||||||
|
// stop updating during song lead-in
|
||||||
|
if (isLeadIn()) {
|
||||||
leadInTime -= delta;
|
leadInTime -= delta;
|
||||||
if (!isLeadIn())
|
if (!isLeadIn())
|
||||||
MusicController.resume();
|
MusicController.resume();
|
||||||
|
updateFlashlightRadius(delta, trackPosition);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//hover updates only the real mouse position
|
// normal game update
|
||||||
//but doesn't hover the replays
|
if (!isReplay)
|
||||||
skipButton.hoverUpdate(delta, mouseX, mouseY);
|
|
||||||
|
|
||||||
|
|
||||||
int trackPosition = MusicController.getPosition();
|
|
||||||
if (!isReplay) {
|
|
||||||
addReplayFrameAndRun(mouseX, mouseY, lastKeysPressed, trackPosition);
|
addReplayFrameAndRun(mouseX, mouseY, lastKeysPressed, trackPosition);
|
||||||
} else {
|
|
||||||
//out of frames, use previous data
|
// watching replay
|
||||||
if (replayIndex >= replay.frames.length){
|
else {
|
||||||
|
// out of frames, use previous data
|
||||||
|
if (replayIndex >= replay.frames.length)
|
||||||
updateGame(replayX, replayY, delta, MusicController.getPosition(), lastKeysPressed);
|
updateGame(replayX, replayY, delta, MusicController.getPosition(), lastKeysPressed);
|
||||||
}
|
|
||||||
|
// update and run replay frames
|
||||||
while (replayIndex < replay.frames.length && trackPosition >= replay.frames[replayIndex].getTime()) {
|
while (replayIndex < replay.frames.length && trackPosition >= replay.frames[replayIndex].getTime()) {
|
||||||
ReplayFrame frame = replay.frames[replayIndex];
|
ReplayFrame frame = replay.frames[replayIndex];
|
||||||
replayX = frame.getScaledX();
|
replayX = frame.getScaledX();
|
||||||
|
@ -556,7 +557,6 @@ public class Game extends BasicGameState {
|
||||||
replayKeyPressed = frame.isKeyPressed();
|
replayKeyPressed = frame.isKeyPressed();
|
||||||
lastKeysPressed = frame.getKeys();
|
lastKeysPressed = frame.getKeys();
|
||||||
runReplayFrame(frame);
|
runReplayFrame(frame);
|
||||||
|
|
||||||
replayIndex++;
|
replayIndex++;
|
||||||
}
|
}
|
||||||
mouseX = replayX;
|
mouseX = replayX;
|
||||||
|
@ -564,60 +564,7 @@ public class Game extends BasicGameState {
|
||||||
}
|
}
|
||||||
|
|
||||||
// "flashlight" mod: calculate visible area radius
|
// "flashlight" mod: calculate visible area radius
|
||||||
if (GameMod.FLASHLIGHT.isActive()) {
|
updateFlashlightRadius(delta, trackPosition);
|
||||||
int width = container.getWidth(), height = container.getHeight();
|
|
||||||
boolean firstObject = (objectIndex == 0 && trackPosition < osu.objects[0].getTime());
|
|
||||||
if (isLeadIn()) {
|
|
||||||
// lead-in: expand area
|
|
||||||
float progress = Math.max((float) (leadInTime - osu.audioLeadIn) / approachTime, 0f);
|
|
||||||
flashlightRadius = width - (int) ((width - (height * 2 / 3)) * progress);
|
|
||||||
} else if (firstObject) {
|
|
||||||
// before first object: shrink area
|
|
||||||
int timeDiff = osu.objects[0].getTime() - trackPosition;
|
|
||||||
flashlightRadius = width;
|
|
||||||
if (timeDiff < approachTime) {
|
|
||||||
float progress = (float) timeDiff / approachTime;
|
|
||||||
flashlightRadius -= (width - (height * 2 / 3)) * (1 - progress);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// gameplay: size based on combo
|
|
||||||
int targetRadius;
|
|
||||||
int combo = data.getComboStreak();
|
|
||||||
if (combo < 100)
|
|
||||||
targetRadius = height * 2 / 3;
|
|
||||||
else if (combo < 200)
|
|
||||||
targetRadius = height / 2;
|
|
||||||
else
|
|
||||||
targetRadius = height / 3;
|
|
||||||
if (osu.breaks != null && breakIndex < osu.breaks.size() && breakTime > 0) {
|
|
||||||
// breaks: expand at beginning, shrink at end
|
|
||||||
flashlightRadius = targetRadius;
|
|
||||||
int endTime = osu.breaks.get(breakIndex);
|
|
||||||
int breakLength = endTime - breakTime;
|
|
||||||
if (breakLength > approachTime * 3) {
|
|
||||||
float progress = 1f;
|
|
||||||
if (trackPosition - breakTime < approachTime)
|
|
||||||
progress = (float) (trackPosition - breakTime) / approachTime;
|
|
||||||
else if (endTime - trackPosition < approachTime)
|
|
||||||
progress = (float) (endTime - trackPosition) / approachTime;
|
|
||||||
flashlightRadius += (width - flashlightRadius) * progress;
|
|
||||||
}
|
|
||||||
} else if (flashlightRadius != targetRadius) {
|
|
||||||
// radius size change
|
|
||||||
float radiusDiff = height * delta / 2000f;
|
|
||||||
if (flashlightRadius > targetRadius) {
|
|
||||||
flashlightRadius -= radiusDiff;
|
|
||||||
if (flashlightRadius < targetRadius)
|
|
||||||
flashlightRadius = targetRadius;
|
|
||||||
} else {
|
|
||||||
flashlightRadius += radiusDiff;
|
|
||||||
if (flashlightRadius > targetRadius)
|
|
||||||
flashlightRadius = targetRadius;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// returning from pause screen: must click previous mouse position
|
// returning from pause screen: must click previous mouse position
|
||||||
if (pauseTime > -1) {
|
if (pauseTime > -1) {
|
||||||
|
@ -646,15 +593,11 @@ public class Game extends BasicGameState {
|
||||||
|
|
||||||
data.updateDisplays(delta);
|
data.updateDisplays(delta);
|
||||||
|
|
||||||
// replays
|
// replays: skip intro
|
||||||
if (isReplay) {
|
if (isReplay && replaySkipTime > 0 && trackPosition > replaySkipTime) {
|
||||||
// skip intro
|
|
||||||
if (replaySkipTime > 0 && trackPosition > replaySkipTime) {
|
|
||||||
skipIntro();
|
skipIntro();
|
||||||
replaySkipTime = -1;
|
replaySkipTime = -1;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// pause game if focus lost
|
// pause game if focus lost
|
||||||
if (!container.hasFocus() && !GameMod.AUTO.isActive() && !isReplay) {
|
if (!container.hasFocus() && !GameMod.AUTO.isActive() && !isReplay) {
|
||||||
|
@ -667,19 +610,17 @@ public class Game extends BasicGameState {
|
||||||
pauseTime = trackPosition;
|
pauseTime = trackPosition;
|
||||||
game.enterState(Opsu.STATE_GAMEPAUSEMENU);
|
game.enterState(Opsu.STATE_GAMEPAUSEMENU);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates the game
|
* Updates the game.
|
||||||
* @param mouseX the mouse x position
|
* @param mouseX the mouse x coordinate
|
||||||
* @param mouseY
|
* @param mouseY the mouse y coordinate
|
||||||
* @param delta
|
* @param delta the delta interval
|
||||||
* @param trackPosition the track position
|
* @param trackPosition the track position
|
||||||
* @param keysPressed the keys that are pressed
|
* @param keys the keys that are pressed
|
||||||
*/
|
*/
|
||||||
private void updateGame(int mouseX, int mouseY, int delta, int trackPosition, int keysPressed) {
|
private void updateGame(int mouseX, int mouseY, int delta, int trackPosition, int keys) {
|
||||||
// "Easy" mod: multiple "lives"
|
// "Easy" mod: multiple "lives"
|
||||||
if (GameMod.EASY.isActive() && deathTime > -1) {
|
if (GameMod.EASY.isActive() && deathTime > -1) {
|
||||||
if (data.getHealth() < 99f)
|
if (data.getHealth() < 99f)
|
||||||
|
@ -690,7 +631,6 @@ public class Game extends BasicGameState {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// map complete!
|
// map complete!
|
||||||
if (objectIndex >= hitObjects.length || (MusicController.trackEnded() && objectIndex > 0)) {
|
if (objectIndex >= hitObjects.length || (MusicController.trackEnded() && objectIndex > 0)) {
|
||||||
// track ended before last object was processed: force a hit result
|
// track ended before last object was processed: force a hit result
|
||||||
|
@ -787,7 +727,7 @@ public class Game extends BasicGameState {
|
||||||
}
|
}
|
||||||
|
|
||||||
// update objects (loop in unlikely event of any skipped indexes)
|
// update objects (loop in unlikely event of any skipped indexes)
|
||||||
boolean keyPressed = keysPressed != ReplayFrame.KEY_NONE;
|
boolean keyPressed = keys != ReplayFrame.KEY_NONE;
|
||||||
while (objectIndex < hitObjects.length && trackPosition > osu.objects[objectIndex].getTime()) {
|
while (objectIndex < hitObjects.length && trackPosition > osu.objects[objectIndex].getTime()) {
|
||||||
// check if we've already passed the next object's start time
|
// check if we've already passed the next object's start time
|
||||||
boolean overlap = (objectIndex + 1 < hitObjects.length &&
|
boolean overlap = (objectIndex + 1 < hitObjects.length &&
|
||||||
|
@ -807,16 +747,17 @@ public class Game extends BasicGameState {
|
||||||
@Override
|
@Override
|
||||||
public void keyPressed(int key, char c) {
|
public void keyPressed(int key, char c) {
|
||||||
int trackPosition = MusicController.getPosition();
|
int trackPosition = MusicController.getPosition();
|
||||||
|
|
||||||
// game keys
|
|
||||||
int mouseX = input.getMouseX();
|
int mouseX = input.getMouseX();
|
||||||
int mouseY = input.getMouseY();
|
int mouseY = input.getMouseY();
|
||||||
|
|
||||||
|
// game keys
|
||||||
if (!Keyboard.isRepeatEvent()) {
|
if (!Keyboard.isRepeatEvent()) {
|
||||||
int keys = 0;
|
int keys = ReplayFrame.KEY_NONE;
|
||||||
if (key == Options.getGameKeyLeft())
|
if (key == Options.getGameKeyLeft())
|
||||||
keys = ReplayFrame.KEY_K1;
|
keys = ReplayFrame.KEY_K1;
|
||||||
else if (key == Options.getGameKeyRight())
|
else if (key == Options.getGameKeyRight())
|
||||||
keys = ReplayFrame.KEY_K2;
|
keys = ReplayFrame.KEY_K2;
|
||||||
|
if (keys != ReplayFrame.KEY_NONE)
|
||||||
gameKeyPressed(keys, mouseX, mouseY, trackPosition);
|
gameKeyPressed(keys, mouseX, mouseY, trackPosition);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -943,15 +884,14 @@ public class Game extends BasicGameState {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// game keys
|
||||||
int keys = 0;
|
int keys = ReplayFrame.KEY_NONE;
|
||||||
if (button == Input.MOUSE_LEFT_BUTTON)
|
if (button == Input.MOUSE_LEFT_BUTTON)
|
||||||
keys = ReplayFrame.KEY_M1;
|
keys = ReplayFrame.KEY_M1;
|
||||||
else if (button == Input.MOUSE_RIGHT_BUTTON)
|
else if (button == Input.MOUSE_RIGHT_BUTTON)
|
||||||
keys = ReplayFrame.KEY_M2;
|
keys = ReplayFrame.KEY_M2;
|
||||||
|
if (keys != ReplayFrame.KEY_NONE)
|
||||||
gameKeyPressed(keys, x, y, MusicController.getPosition());
|
gameKeyPressed(keys, x, y, MusicController.getPosition());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -959,7 +899,7 @@ public class Game extends BasicGameState {
|
||||||
* @param keys the game keys pressed
|
* @param keys the game keys pressed
|
||||||
* @param x the mouse x coordinate
|
* @param x the mouse x coordinate
|
||||||
* @param y the mouse y coordinate
|
* @param y the mouse y coordinate
|
||||||
* @param trackPosition the track Position
|
* @param trackPosition the track position
|
||||||
*/
|
*/
|
||||||
private void gameKeyPressed(int keys, int x, int y, int trackPosition) {
|
private void gameKeyPressed(int keys, int x, int y, int trackPosition) {
|
||||||
// returning from pause screen
|
// returning from pause screen
|
||||||
|
@ -983,13 +923,17 @@ public class Game extends BasicGameState {
|
||||||
return; // successfully skipped
|
return; // successfully skipped
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!isReplay && keys > 0) {
|
// "auto" and "relax" mods: ignore user actions
|
||||||
lastKeysPressed |= keys; //sets keys bits
|
if (GameMod.AUTO.isActive() || GameMod.RELAX.isActive())
|
||||||
|
return;
|
||||||
|
|
||||||
|
// send a game key press
|
||||||
|
if (!isReplay && keys != ReplayFrame.KEY_NONE) {
|
||||||
|
lastKeysPressed |= keys; // set keys bits
|
||||||
addReplayFrameAndRun(x, y, lastKeysPressed, trackPosition);
|
addReplayFrameAndRun(x, y, lastKeysPressed, trackPosition);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void mouseReleased(int button, int x, int y) {
|
public void mouseReleased(int button, int x, int y) {
|
||||||
if (Options.isMouseDisabled())
|
if (Options.isMouseDisabled())
|
||||||
|
@ -998,46 +942,40 @@ public class Game extends BasicGameState {
|
||||||
if (button == Input.MOUSE_MIDDLE_BUTTON)
|
if (button == Input.MOUSE_MIDDLE_BUTTON)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
int keys = 0;
|
int keys = ReplayFrame.KEY_NONE;
|
||||||
if (button == Input.MOUSE_LEFT_BUTTON)
|
if (button == Input.MOUSE_LEFT_BUTTON)
|
||||||
keys = ReplayFrame.KEY_M1;
|
keys = ReplayFrame.KEY_M1;
|
||||||
else if (button == Input.MOUSE_RIGHT_BUTTON)
|
else if (button == Input.MOUSE_RIGHT_BUTTON)
|
||||||
keys = ReplayFrame.KEY_M2;
|
keys = ReplayFrame.KEY_M2;
|
||||||
|
if (keys != ReplayFrame.KEY_NONE)
|
||||||
gameKeyReleased(keys, x, y, MusicController.getPosition());
|
gameKeyReleased(keys, x, y, MusicController.getPosition());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void keyReleased(int key, char c) {
|
public void keyReleased(int key, char c) {
|
||||||
int keys = 0;
|
int keys = ReplayFrame.KEY_NONE;
|
||||||
if (key == Options.getGameKeyLeft())
|
if (key == Options.getGameKeyLeft())
|
||||||
keys = ReplayFrame.KEY_K1;
|
keys = ReplayFrame.KEY_K1;
|
||||||
else if (key == Options.getGameKeyRight())
|
else if (key == Options.getGameKeyRight())
|
||||||
keys = ReplayFrame.KEY_K2;
|
keys = ReplayFrame.KEY_K2;
|
||||||
|
if (keys != ReplayFrame.KEY_NONE)
|
||||||
gameKeyReleased(keys, input.getMouseX(), input.getMouseY(), MusicController.getPosition());
|
gameKeyReleased(keys, input.getMouseX(), input.getMouseY(), MusicController.getPosition());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles a game key Released event.
|
* Handles a game key released event.
|
||||||
* @param keys the game keys released
|
* @param keys the game keys released
|
||||||
* @param x the mouse x coordinate
|
* @param x the mouse x coordinate
|
||||||
* @param y the mouse y coordinate
|
* @param y the mouse y coordinate
|
||||||
* @param trackPosition the track Position
|
* @param trackPosition the track position
|
||||||
*/
|
*/
|
||||||
private void gameKeyReleased(int keys, int x, int y, int trackPosition) {
|
private void gameKeyReleased(int keys, int x, int y, int trackPosition) {
|
||||||
if (!isReplay && keys > 0) {
|
if (!isReplay && keys != ReplayFrame.KEY_NONE) {
|
||||||
lastKeysPressed &= ~keys; //clears keys bits
|
lastKeysPressed &= ~keys; // clear keys bits
|
||||||
addReplayFrameAndRun(x, y, lastKeysPressed, trackPosition);
|
addReplayFrameAndRun(x, y, lastKeysPressed, trackPosition);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void mouseMoved(int oldx, int oldy, int newx, int newy) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void mouseDragged(int oldx, int oldy, int newx, int newy) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void mouseWheelMoved(int newValue) {
|
public void mouseWheelMoved(int newValue) {
|
||||||
if (Options.isMouseWheelDisabled() || Options.isMouseDisabled())
|
if (Options.isMouseWheelDisabled() || Options.isMouseDisabled())
|
||||||
|
@ -1111,7 +1049,6 @@ public class Game extends BasicGameState {
|
||||||
if (GameMod.AUTO.isActive() || isReplay)
|
if (GameMod.AUTO.isActive() || isReplay)
|
||||||
UI.showCursor();
|
UI.showCursor();
|
||||||
|
|
||||||
lastReplayTime = 0;
|
|
||||||
// load replay frames
|
// load replay frames
|
||||||
if (isReplay) {
|
if (isReplay) {
|
||||||
// load mods
|
// load mods
|
||||||
|
@ -1287,6 +1224,7 @@ public class Game extends BasicGameState {
|
||||||
deaths = 0;
|
deaths = 0;
|
||||||
deathTime = -1;
|
deathTime = -1;
|
||||||
replayFrames = null;
|
replayFrames = null;
|
||||||
|
lastReplayTime = 0;
|
||||||
autoMouseX = 0;
|
autoMouseX = 0;
|
||||||
autoMouseY = 0;
|
autoMouseY = 0;
|
||||||
autoMousePressed = false;
|
autoMousePressed = false;
|
||||||
|
@ -1440,7 +1378,6 @@ public class Game extends BasicGameState {
|
||||||
*/
|
*/
|
||||||
public float getTimingPointMultiplier() { return beatLength / beatLengthBase; }
|
public float getTimingPointMultiplier() { return beatLength / beatLengthBase; }
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets a replay to view, or resets the replay if null.
|
* Sets a replay to view, or resets the replay if null.
|
||||||
* @param replay the replay
|
* @param replay the replay
|
||||||
|
@ -1460,50 +1397,51 @@ public class Game extends BasicGameState {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds a replay frame to the list if able and runs it.
|
* Adds a replay frame to the list, if possible, and runs it.
|
||||||
* @param x the cursor x coordinate
|
* @param x the cursor x coordinate
|
||||||
* @param y the cursor y coordinate
|
* @param y the cursor y coordinate
|
||||||
* @param keys the keys pressed
|
* @param keys the keys pressed
|
||||||
* @param time the time of the replay Frame
|
* @param time the time of the replay Frame
|
||||||
*/
|
*/
|
||||||
public synchronized void addReplayFrameAndRun(int x, int y, int keys, int time){
|
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()) {
|
if (GameMod.AUTO.isActive() || GameMod.AUTOPILOT.isActive()) {
|
||||||
x = autoMouseX;
|
x = autoMouseX;
|
||||||
y = autoMouseY;
|
y = autoMouseY;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReplayFrame frame = addReplayFrame(x, y, keys, time);
|
ReplayFrame frame = addReplayFrame(x, y, keys, time);
|
||||||
if(frame != null)
|
if (frame != null)
|
||||||
runReplayFrame(frame);
|
runReplayFrame(frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Runs a replay Frame
|
* Runs a replay frame.
|
||||||
* @param frame the frame to run
|
* @param frame the frame to run
|
||||||
*/
|
*/
|
||||||
private void runReplayFrame(ReplayFrame frame){
|
private void runReplayFrame(ReplayFrame frame){
|
||||||
int keys = frame.getKeys();
|
int keys = frame.getKeys();
|
||||||
int replayX = frame.getScaledX();
|
int replayX = frame.getScaledX();
|
||||||
int replayY = frame.getScaledY();
|
int replayY = frame.getScaledY();
|
||||||
int deltaKeys = (keys & ~lastReplayKeys ); //keys that turned on
|
int deltaKeys = (keys & ~lastReplayKeys); // keys that turned on
|
||||||
if (deltaKeys > 0) { // send a key press
|
if (deltaKeys != ReplayFrame.KEY_NONE) // send a key press
|
||||||
updateGameKeyPress(deltaKeys, replayX, replayY, frame.getTime());
|
sendGameKeyPress(deltaKeys, replayX, replayY, frame.getTime());
|
||||||
} else if(keys != lastReplayKeys){
|
else if (keys != lastReplayKeys)
|
||||||
} else {
|
; // do nothing
|
||||||
|
else
|
||||||
updateGame(replayX, replayY, frame.getTimeDiff(), frame.getTime(), keys);
|
updateGame(replayX, replayY, frame.getTimeDiff(), frame.getTime(), keys);
|
||||||
}
|
|
||||||
lastReplayKeys = keys;
|
lastReplayKeys = keys;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates the games mouse pressed
|
* Sends a game key press and updates the hit objects.
|
||||||
* @param mouseX the mouse x position
|
|
||||||
* @param mouseY
|
|
||||||
* @param trackPosition the track position
|
* @param trackPosition the track position
|
||||||
* @param keysPressed the keys that are pressed
|
* @param x the cursor x coordinate
|
||||||
|
* @param y the cursor y coordinate
|
||||||
|
* @param keys the keys that are pressed
|
||||||
*/
|
*/
|
||||||
private void updateGameKeyPress(int keys, int x, int y, int trackPosition) {
|
private void sendGameKeyPress(int keys, int x, int y, int trackPosition) {
|
||||||
if (objectIndex >= hitObjects.length) // nothing left to do here
|
if (objectIndex >= hitObjects.length) // nothing to do here
|
||||||
return;
|
return;
|
||||||
|
|
||||||
OsuHitObject hitObject = osu.objects[objectIndex];
|
OsuHitObject hitObject = osu.objects[objectIndex];
|
||||||
|
@ -1515,26 +1453,25 @@ public class Game extends BasicGameState {
|
||||||
// sliders
|
// sliders
|
||||||
else if (hitObject.isSlider())
|
else if (hitObject.isSlider())
|
||||||
hitObjects[objectIndex].mousePressed(x, y, trackPosition);
|
hitObjects[objectIndex].mousePressed(x, y, trackPosition);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds a replay frame to the list if able.
|
* Adds a replay frame to the list, if possible.
|
||||||
* @param x the cursor x coordinate
|
* @param x the cursor x coordinate
|
||||||
* @param y the cursor y coordinate
|
* @param y the cursor y coordinate
|
||||||
* @param keys the keys pressed
|
* @param keys the keys pressed
|
||||||
* @param time the time of the replay Frame
|
* @param time the time of the replay frame
|
||||||
* @return a Replay Frame representing the data
|
* @return a ReplayFrame representing the data
|
||||||
*/
|
*/
|
||||||
private ReplayFrame addReplayFrame(int x, int y, int keys, int time) {
|
private ReplayFrame addReplayFrame(int x, int y, int keys, int time) {
|
||||||
int timeDiff = time - lastReplayTime;
|
int timeDiff = time - lastReplayTime;
|
||||||
lastReplayTime = time;
|
lastReplayTime = time;
|
||||||
int cx = (int) ((x - OsuHitObject.getXOffset()) / OsuHitObject.getXMultiplier());
|
int cx = (int) ((x - OsuHitObject.getXOffset()) / OsuHitObject.getXMultiplier());
|
||||||
int cy = (int) ((y - OsuHitObject.getYOffset()) / OsuHitObject.getYMultiplier());
|
int cy = (int) ((y - OsuHitObject.getYOffset()) / OsuHitObject.getYMultiplier());
|
||||||
ReplayFrame tFrame = new ReplayFrame(timeDiff, time, cx, cy, keys);
|
ReplayFrame frame = new ReplayFrame(timeDiff, time, cx, cy, keys);
|
||||||
if(replayFrames != null)
|
if (replayFrames != null)
|
||||||
replayFrames.add(tFrame);
|
replayFrames.add(frame);
|
||||||
return tFrame;
|
return frame;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1556,4 +1493,66 @@ public class Game extends BasicGameState {
|
||||||
xy[1] = startY + (endY - startY) * t;
|
xy[1] = startY + (endY - startY) * t;
|
||||||
return xy;
|
return xy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the current visible area radius (if the "flashlight" mod is enabled).
|
||||||
|
* @param delta the delta interval
|
||||||
|
* @param trackPosition the track position
|
||||||
|
*/
|
||||||
|
private void updateFlashlightRadius(int delta, int trackPosition) {
|
||||||
|
if (!GameMod.FLASHLIGHT.isActive())
|
||||||
|
return;
|
||||||
|
|
||||||
|
int width = container.getWidth(), height = container.getHeight();
|
||||||
|
boolean firstObject = (objectIndex == 0 && trackPosition < osu.objects[0].getTime());
|
||||||
|
if (isLeadIn()) {
|
||||||
|
// lead-in: expand area
|
||||||
|
float progress = Math.max((float) (leadInTime - osu.audioLeadIn) / approachTime, 0f);
|
||||||
|
flashlightRadius = width - (int) ((width - (height * 2 / 3)) * progress);
|
||||||
|
} else if (firstObject) {
|
||||||
|
// before first object: shrink area
|
||||||
|
int timeDiff = osu.objects[0].getTime() - trackPosition;
|
||||||
|
flashlightRadius = width;
|
||||||
|
if (timeDiff < approachTime) {
|
||||||
|
float progress = (float) timeDiff / approachTime;
|
||||||
|
flashlightRadius -= (width - (height * 2 / 3)) * (1 - progress);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// gameplay: size based on combo
|
||||||
|
int targetRadius;
|
||||||
|
int combo = data.getComboStreak();
|
||||||
|
if (combo < 100)
|
||||||
|
targetRadius = height * 2 / 3;
|
||||||
|
else if (combo < 200)
|
||||||
|
targetRadius = height / 2;
|
||||||
|
else
|
||||||
|
targetRadius = height / 3;
|
||||||
|
if (osu.breaks != null && breakIndex < osu.breaks.size() && breakTime > 0) {
|
||||||
|
// breaks: expand at beginning, shrink at end
|
||||||
|
flashlightRadius = targetRadius;
|
||||||
|
int endTime = osu.breaks.get(breakIndex);
|
||||||
|
int breakLength = endTime - breakTime;
|
||||||
|
if (breakLength > approachTime * 3) {
|
||||||
|
float progress = 1f;
|
||||||
|
if (trackPosition - breakTime < approachTime)
|
||||||
|
progress = (float) (trackPosition - breakTime) / approachTime;
|
||||||
|
else if (endTime - trackPosition < approachTime)
|
||||||
|
progress = (float) (endTime - trackPosition) / approachTime;
|
||||||
|
flashlightRadius += (width - flashlightRadius) * progress;
|
||||||
|
}
|
||||||
|
} else if (flashlightRadius != targetRadius) {
|
||||||
|
// radius size change
|
||||||
|
float radiusDiff = height * delta / 2000f;
|
||||||
|
if (flashlightRadius > targetRadius) {
|
||||||
|
flashlightRadius -= radiusDiff;
|
||||||
|
if (flashlightRadius < targetRadius)
|
||||||
|
flashlightRadius = targetRadius;
|
||||||
|
} else {
|
||||||
|
flashlightRadius += radiusDiff;
|
||||||
|
if (flashlightRadius > targetRadius)
|
||||||
|
flashlightRadius = targetRadius;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user