Major track length-related updates.
- Parse and store the end time for every beatmap (i.e. end time of last hit object). - Added a 'length' sorting tab. - Added 'length' search condition. - Removed 'getTrackLength()' and 'getTrackLengthString()' methods, as they are no longer needed. - Added a loader spritesheet animation to render during MP3 conversions (in place of track length rendering upon completion). Other changes: - Added a yellow progress circle during lead-in time. - Fixed sorting tab positioning. - Slightly increased button animation speed in "Main Menu Exit" state. Signed-off-by: Jeffrey Han <itdelatrisu@gmail.com>
This commit is contained in:
parent
4ecd50f488
commit
b0c0b44ef1
BIN
res/loader.png
Normal file
BIN
res/loader.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 25 KiB |
|
@ -478,11 +478,10 @@ public class GameScore {
|
||||||
* scorebar, score, score percentage, map progress circle,
|
* scorebar, score, score percentage, map progress circle,
|
||||||
* mod icons, combo count, combo burst, and grade.
|
* mod icons, combo count, combo burst, and grade.
|
||||||
* @param g the graphics context
|
* @param g the graphics context
|
||||||
* @param mapLength the length of the beatmap (in ms)
|
|
||||||
* @param breakPeriod if true, will not draw scorebar and combo elements, and will draw grade
|
* @param breakPeriod if true, will not draw scorebar and combo elements, and will draw grade
|
||||||
* @param firstObject true if the first hit object's start time has not yet passed
|
* @param firstObject true if the first hit object's start time has not yet passed
|
||||||
*/
|
*/
|
||||||
public void drawGameElements(Graphics g, int mapLength, boolean breakPeriod, boolean firstObject) {
|
public void drawGameElements(Graphics g, boolean breakPeriod, boolean firstObject) {
|
||||||
// score
|
// score
|
||||||
drawSymbolString((scoreDisplay < 100000000) ? String.format("%08d", scoreDisplay) : Long.toString(scoreDisplay),
|
drawSymbolString((scoreDisplay < 100000000) ? String.format("%08d", scoreDisplay) : Long.toString(scoreDisplay),
|
||||||
width - 2, 0, 1.0f, true);
|
width - 2, 0, 1.0f, true);
|
||||||
|
@ -500,11 +499,19 @@ public class GameScore {
|
||||||
float circleDiameter = symbolHeight * 0.75f;
|
float circleDiameter = symbolHeight * 0.75f;
|
||||||
g.drawOval(circleX, symbolHeight, circleDiameter, circleDiameter);
|
g.drawOval(circleX, symbolHeight, circleDiameter, circleDiameter);
|
||||||
|
|
||||||
int firstObjectTime = MusicController.getOsuFile().objects[0].time;
|
OsuFile osu = MusicController.getOsuFile();
|
||||||
|
int firstObjectTime = osu.objects[0].time;
|
||||||
int trackPosition = MusicController.getPosition();
|
int trackPosition = MusicController.getPosition();
|
||||||
if (trackPosition > firstObjectTime) {
|
if (trackPosition > firstObjectTime) {
|
||||||
|
// map progress (white)
|
||||||
g.fillArc(circleX, symbolHeight, circleDiameter, circleDiameter,
|
g.fillArc(circleX, symbolHeight, circleDiameter, circleDiameter,
|
||||||
-90, -90 + (int) (360f * (trackPosition - firstObjectTime) / mapLength)
|
-90, -90 + (int) (360f * (trackPosition - firstObjectTime) / (osu.endTime - firstObjectTime))
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
// lead-in time (yellow)
|
||||||
|
g.setColor(Utils.COLOR_YELLOW_ALPHA);
|
||||||
|
g.fillArc(circleX, symbolHeight, circleDiameter, circleDiameter,
|
||||||
|
-90 + (int) (360f * trackPosition / firstObjectTime), -90
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,6 @@ import itdelatrisu.opsu.states.Options;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.nio.IntBuffer;
|
import java.nio.IntBuffer;
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
import javazoom.jl.converter.Converter;
|
import javazoom.jl.converter.Converter;
|
||||||
|
|
||||||
|
@ -249,48 +248,6 @@ public class MusicController {
|
||||||
return (trackExists() && player.setPosition(position / 1000f));
|
return (trackExists() && player.setPosition(position / 1000f));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the length of the track, in milliseconds.
|
|
||||||
* Returns 0 if no file is loaded or a track is currently being loaded.
|
|
||||||
* @author bdk (http://slick.ninjacave.com/forum/viewtopic.php?t=2699)
|
|
||||||
*/
|
|
||||||
public static int getTrackLength() {
|
|
||||||
if (!trackExists() || isTrackLoading())
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
float duration = 0f;
|
|
||||||
try {
|
|
||||||
// get Music object's (private) Audio object reference
|
|
||||||
Field sound = player.getClass().getDeclaredField("sound");
|
|
||||||
sound.setAccessible(true);
|
|
||||||
Audio audio = (Audio) (sound.get(player));
|
|
||||||
|
|
||||||
// access Audio object's (private)'length' field
|
|
||||||
Field length = audio.getClass().getDeclaredField("length");
|
|
||||||
length.setAccessible(true);
|
|
||||||
duration = (float) (length.get(audio));
|
|
||||||
} catch (Exception e) {
|
|
||||||
Log.debug("Could not get track length.");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return (int) (duration * 1000);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the length of the track as a formatted string (M:SS).
|
|
||||||
* Returns "--" if a track is currently being loaded.
|
|
||||||
*/
|
|
||||||
public static String getTrackLengthString() {
|
|
||||||
if (isTrackLoading())
|
|
||||||
return "...";
|
|
||||||
|
|
||||||
int duration = getTrackLength();
|
|
||||||
return String.format("%d:%02d",
|
|
||||||
TimeUnit.MILLISECONDS.toMinutes(duration),
|
|
||||||
TimeUnit.MILLISECONDS.toSeconds(duration) -
|
|
||||||
TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(duration)));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stops and releases all sources, clears each of the specified Audio
|
* Stops and releases all sources, clears each of the specified Audio
|
||||||
* buffers, destroys the OpenAL context, and resets SoundStore for future use.
|
* buffers, destroys the OpenAL context, and resets SoundStore for future use.
|
||||||
|
|
|
@ -96,6 +96,7 @@ public class OsuFile implements Comparable<OsuFile> {
|
||||||
public int hitObjectCircle = 0; // number of circles
|
public int hitObjectCircle = 0; // number of circles
|
||||||
public int hitObjectSlider = 0; // number of sliders
|
public int hitObjectSlider = 0; // number of sliders
|
||||||
public int hitObjectSpinner = 0; // number of spinners
|
public int hitObjectSpinner = 0; // number of spinners
|
||||||
|
public int endTime = -1; // last object end time (in ms)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor.
|
* Constructor.
|
||||||
|
|
|
@ -38,13 +38,14 @@ public class OsuGroupList {
|
||||||
SORT_ARTIST = 1,
|
SORT_ARTIST = 1,
|
||||||
SORT_CREATOR = 2,
|
SORT_CREATOR = 2,
|
||||||
SORT_BPM = 3,
|
SORT_BPM = 3,
|
||||||
SORT_MAX = 4; // not a sort
|
SORT_LENGTH = 4,
|
||||||
|
SORT_MAX = 5; // not a sort
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sorting order names (indexed by SORT_* constants).
|
* Sorting order names (indexed by SORT_* constants).
|
||||||
*/
|
*/
|
||||||
public static final String[] SORT_NAMES = {
|
public static final String[] SORT_NAMES = {
|
||||||
"Title", "Artist", "Creator", "BPM"
|
"Title", "Artist", "Creator", "BPM", "Length"
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -240,6 +241,9 @@ public class OsuGroupList {
|
||||||
case SORT_BPM:
|
case SORT_BPM:
|
||||||
Collections.sort(nodes, new OsuGroupNode.BPMOrder());
|
Collections.sort(nodes, new OsuGroupNode.BPMOrder());
|
||||||
break;
|
break;
|
||||||
|
case SORT_LENGTH:
|
||||||
|
Collections.sort(nodes, new OsuGroupNode.LengthOrder());
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
expandedIndex = -1;
|
expandedIndex = -1;
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,7 @@ package itdelatrisu.opsu;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import org.newdawn.slick.Color;
|
import org.newdawn.slick.Color;
|
||||||
import org.newdawn.slick.Image;
|
import org.newdawn.slick.Image;
|
||||||
|
@ -100,6 +101,26 @@ public class OsuGroupNode implements Comparable<OsuGroupNode> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compares two OsuGroupNode objects by length.
|
||||||
|
* Uses the longest beatmap in each set for comparison.
|
||||||
|
*/
|
||||||
|
public static class LengthOrder implements Comparator<OsuGroupNode> {
|
||||||
|
@Override
|
||||||
|
public int compare(OsuGroupNode v, OsuGroupNode w) {
|
||||||
|
int vMax = 0, wMax = 0;
|
||||||
|
for (OsuFile osu : v.osuFiles) {
|
||||||
|
if (osu.endTime > vMax)
|
||||||
|
vMax = osu.endTime;
|
||||||
|
}
|
||||||
|
for (OsuFile osu : w.osuFiles) {
|
||||||
|
if (osu.endTime > wMax)
|
||||||
|
wMax = osu.endTime;
|
||||||
|
}
|
||||||
|
return Integer.compare(vMax, wMax);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets a button background image.
|
* Sets a button background image.
|
||||||
*/
|
*/
|
||||||
|
@ -162,8 +183,10 @@ public class OsuGroupNode implements Comparable<OsuGroupNode> {
|
||||||
info[0] = osu.toString();
|
info[0] = osu.toString();
|
||||||
info[1] = String.format("Mapped by %s",
|
info[1] = String.format("Mapped by %s",
|
||||||
osu.creator);
|
osu.creator);
|
||||||
info[2] = String.format("Length: %s BPM: %s Objects: %d",
|
info[2] = String.format("Length: %d:%02d BPM: %s Objects: %d",
|
||||||
MusicController.getTrackLengthString(),
|
TimeUnit.MILLISECONDS.toMinutes(osu.endTime),
|
||||||
|
TimeUnit.MILLISECONDS.toSeconds(osu.endTime) -
|
||||||
|
TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(osu.endTime)),
|
||||||
(osu.bpmMax <= 0) ? "--" :
|
(osu.bpmMax <= 0) ? "--" :
|
||||||
((osu.bpmMin == osu.bpmMax) ? osu.bpmMin : String.format("%d-%d", osu.bpmMin, osu.bpmMax)),
|
((osu.bpmMin == osu.bpmMax) ? osu.bpmMin : String.format("%d-%d", osu.bpmMin, osu.bpmMax)),
|
||||||
(osu.hitObjectCircle + osu.hitObjectSlider + osu.hitObjectSpinner));
|
(osu.hitObjectCircle + osu.hitObjectSlider + osu.hitObjectSpinner));
|
||||||
|
@ -232,7 +255,7 @@ public class OsuGroupNode implements Comparable<OsuGroupNode> {
|
||||||
case "od": osuValue = osu.overallDifficulty; break;
|
case "od": osuValue = osu.overallDifficulty; break;
|
||||||
case "hp": osuValue = osu.HPDrainRate; break;
|
case "hp": osuValue = osu.HPDrainRate; break;
|
||||||
case "bpm": osuValue = osu.bpmMax; break;
|
case "bpm": osuValue = osu.bpmMax; break;
|
||||||
// case "length": /* not implemented */ break;
|
case "length": osuValue = osu.endTime / 1000; break;
|
||||||
default: return false;
|
default: return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -131,7 +131,7 @@ public class OsuParser {
|
||||||
osu.timingPoints = new ArrayList<OsuTimingPoint>();
|
osu.timingPoints = new ArrayList<OsuTimingPoint>();
|
||||||
|
|
||||||
String line = in.readLine();
|
String line = in.readLine();
|
||||||
String tokens[];
|
String tokens[] = null;
|
||||||
while (line != null) {
|
while (line != null) {
|
||||||
line = line.trim();
|
line = line.trim();
|
||||||
if (!isValidLine(line)) {
|
if (!isValidLine(line)) {
|
||||||
|
@ -386,6 +386,7 @@ public class OsuParser {
|
||||||
osu.combo = colors.toArray(new Color[colors.size()]);
|
osu.combo = colors.toArray(new Color[colors.size()]);
|
||||||
break;
|
break;
|
||||||
case "[HitObjects]":
|
case "[HitObjects]":
|
||||||
|
int type = -1;
|
||||||
while ((line = in.readLine()) != null) {
|
while ((line = in.readLine()) != null) {
|
||||||
line = line.trim();
|
line = line.trim();
|
||||||
if (!isValidLine(line))
|
if (!isValidLine(line))
|
||||||
|
@ -394,7 +395,7 @@ public class OsuParser {
|
||||||
break;
|
break;
|
||||||
/* Only type counts parsed at this time. */
|
/* Only type counts parsed at this time. */
|
||||||
tokens = line.split(",");
|
tokens = line.split(",");
|
||||||
int type = Integer.parseInt(tokens[3]);
|
type = Integer.parseInt(tokens[3]);
|
||||||
if ((type & OsuHitObject.TYPE_CIRCLE) > 0)
|
if ((type & OsuHitObject.TYPE_CIRCLE) > 0)
|
||||||
osu.hitObjectCircle++;
|
osu.hitObjectCircle++;
|
||||||
else if ((type & OsuHitObject.TYPE_SLIDER) > 0)
|
else if ((type & OsuHitObject.TYPE_SLIDER) > 0)
|
||||||
|
@ -402,6 +403,16 @@ public class OsuParser {
|
||||||
else //if ((type & OsuHitObject.TYPE_SPINNER) > 0)
|
else //if ((type & OsuHitObject.TYPE_SPINNER) > 0)
|
||||||
osu.hitObjectSpinner++;
|
osu.hitObjectSpinner++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// map length = last object end time (TODO: end on slider?)
|
||||||
|
if ((type & OsuHitObject.TYPE_SPINNER) > 0) {
|
||||||
|
// some 'endTime' fields contain a ':' character (?)
|
||||||
|
int index = tokens[5].indexOf(':');
|
||||||
|
if (index != -1)
|
||||||
|
tokens[5] = tokens[5].substring(0, index);
|
||||||
|
osu.endTime = Integer.parseInt(tokens[5]);
|
||||||
|
} else
|
||||||
|
osu.endTime = Integer.parseInt(tokens[2]);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
line = in.readLine();
|
line = in.readLine();
|
||||||
|
|
|
@ -59,7 +59,8 @@ public class Utils {
|
||||||
COLOR_GREEN_OBJECT = new Color(26, 207, 26),
|
COLOR_GREEN_OBJECT = new Color(26, 207, 26),
|
||||||
COLOR_BLUE_OBJECT = new Color(46, 136, 248),
|
COLOR_BLUE_OBJECT = new Color(46, 136, 248),
|
||||||
COLOR_RED_OBJECT = new Color(243, 48, 77),
|
COLOR_RED_OBJECT = new Color(243, 48, 77),
|
||||||
COLOR_ORANGE_OBJECT = new Color(255, 200, 32);
|
COLOR_ORANGE_OBJECT = new Color(255, 200, 32),
|
||||||
|
COLOR_YELLOW_ALPHA = new Color(255, 255, 0, 0.4f);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The default map colors, used when a map does not provide custom colors.
|
* The default map colors, used when a map does not provide custom colors.
|
||||||
|
|
|
@ -114,11 +114,6 @@ public class Game extends BasicGameState {
|
||||||
*/
|
*/
|
||||||
private int[] hitResultOffset;
|
private int[] hitResultOffset;
|
||||||
|
|
||||||
/**
|
|
||||||
* Time, in milliseconds, between the first and last hit object.
|
|
||||||
*/
|
|
||||||
private int mapLength;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Current break index in breaks ArrayList.
|
* Current break index in breaks ArrayList.
|
||||||
*/
|
*/
|
||||||
|
@ -274,7 +269,7 @@ public class Game extends BasicGameState {
|
||||||
g.fillRect(0, height * 0.875f, width, height * 0.125f);
|
g.fillRect(0, height * 0.875f, width, height * 0.125f);
|
||||||
}
|
}
|
||||||
|
|
||||||
score.drawGameElements(g, mapLength, true, objectIndex == 0);
|
score.drawGameElements(g, true, objectIndex == 0);
|
||||||
|
|
||||||
if (breakLength >= 8000 &&
|
if (breakLength >= 8000 &&
|
||||||
trackPosition - breakTime > 2000 &&
|
trackPosition - breakTime > 2000 &&
|
||||||
|
@ -317,7 +312,7 @@ public class Game extends BasicGameState {
|
||||||
}
|
}
|
||||||
|
|
||||||
// game elements
|
// game elements
|
||||||
score.drawGameElements(g, mapLength, false, objectIndex == 0);
|
score.drawGameElements(g, false, objectIndex == 0);
|
||||||
|
|
||||||
// skip beginning
|
// skip beginning
|
||||||
if (objectIndex == 0 &&
|
if (objectIndex == 0 &&
|
||||||
|
@ -624,7 +619,7 @@ public class Game extends BasicGameState {
|
||||||
// load checkpoint
|
// load checkpoint
|
||||||
if (input.isKeyDown(Input.KEY_RCONTROL) || input.isKeyDown(Input.KEY_LCONTROL)) {
|
if (input.isKeyDown(Input.KEY_RCONTROL) || input.isKeyDown(Input.KEY_LCONTROL)) {
|
||||||
int checkpoint = Options.getCheckpoint();
|
int checkpoint = Options.getCheckpoint();
|
||||||
if (checkpoint == 0 || checkpoint > MusicController.getTrackLength())
|
if (checkpoint == 0 || checkpoint > osu.endTime)
|
||||||
break; // invalid checkpoint
|
break; // invalid checkpoint
|
||||||
try {
|
try {
|
||||||
restart = RESTART_MANUAL;
|
restart = RESTART_MANUAL;
|
||||||
|
@ -728,15 +723,6 @@ public class Game extends BasicGameState {
|
||||||
if (restart == RESTART_NEW) {
|
if (restart == RESTART_NEW) {
|
||||||
loadImages();
|
loadImages();
|
||||||
setMapModifiers();
|
setMapModifiers();
|
||||||
|
|
||||||
// calculate map length (TODO: end on slider?)
|
|
||||||
OsuHitObject lastObject = osu.objects[osu.objects.length - 1];
|
|
||||||
int endTime;
|
|
||||||
if ((lastObject.type & OsuHitObject.TYPE_SPINNER) > 0)
|
|
||||||
endTime = lastObject.endTime;
|
|
||||||
else
|
|
||||||
endTime = lastObject.time;
|
|
||||||
mapLength = endTime - osu.objects[0].time;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// initialize object maps
|
// initialize object maps
|
||||||
|
|
|
@ -190,7 +190,7 @@ public class MainMenu extends BasicGameState {
|
||||||
g.setColor(Color.white);
|
g.setColor(Color.white);
|
||||||
if (!MusicController.isTrackLoading())
|
if (!MusicController.isTrackLoading())
|
||||||
g.fillRoundRect(width - 168, 54,
|
g.fillRoundRect(width - 168, 54,
|
||||||
148f * MusicController.getPosition() / MusicController.getTrackLength(), 5, 4);
|
148f * MusicController.getPosition() / osu.endTime, 5, 4);
|
||||||
|
|
||||||
// draw text
|
// draw text
|
||||||
g.setFont(Utils.FONT_MEDIUM);
|
g.setFont(Utils.FONT_MEDIUM);
|
||||||
|
|
|
@ -120,9 +120,9 @@ public class MainMenuExit extends BasicGameState {
|
||||||
float yesX = yesButton.getX(), noX = noButton.getX();
|
float yesX = yesButton.getX(), noX = noButton.getX();
|
||||||
float center = container.getWidth() / 2f;
|
float center = container.getWidth() / 2f;
|
||||||
if (yesX < center)
|
if (yesX < center)
|
||||||
yesButton.setX(Math.min(yesX + (delta / 6f), center));
|
yesButton.setX(Math.min(yesX + (delta / 5f), center));
|
||||||
if (noX > center)
|
if (noX > center)
|
||||||
noButton.setX(Math.max(noX - (delta / 6f), center));
|
noButton.setX(Math.max(noX - (delta / 5f), center));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -29,12 +29,14 @@ import itdelatrisu.opsu.SoundController;
|
||||||
import itdelatrisu.opsu.Utils;
|
import itdelatrisu.opsu.Utils;
|
||||||
|
|
||||||
import org.lwjgl.opengl.Display;
|
import org.lwjgl.opengl.Display;
|
||||||
|
import org.newdawn.slick.Animation;
|
||||||
import org.newdawn.slick.Color;
|
import org.newdawn.slick.Color;
|
||||||
import org.newdawn.slick.GameContainer;
|
import org.newdawn.slick.GameContainer;
|
||||||
import org.newdawn.slick.Graphics;
|
import org.newdawn.slick.Graphics;
|
||||||
import org.newdawn.slick.Image;
|
import org.newdawn.slick.Image;
|
||||||
import org.newdawn.slick.Input;
|
import org.newdawn.slick.Input;
|
||||||
import org.newdawn.slick.SlickException;
|
import org.newdawn.slick.SlickException;
|
||||||
|
import org.newdawn.slick.SpriteSheet;
|
||||||
import org.newdawn.slick.gui.TextField;
|
import org.newdawn.slick.gui.TextField;
|
||||||
import org.newdawn.slick.state.BasicGameState;
|
import org.newdawn.slick.state.BasicGameState;
|
||||||
import org.newdawn.slick.state.StateBasedGame;
|
import org.newdawn.slick.state.StateBasedGame;
|
||||||
|
@ -128,6 +130,11 @@ public class SongMenu extends BasicGameState {
|
||||||
*/
|
*/
|
||||||
private Image musicNote;
|
private Image musicNote;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loader animation.
|
||||||
|
*/
|
||||||
|
private Animation loader;
|
||||||
|
|
||||||
// game-related variables
|
// game-related variables
|
||||||
private GameContainer container;
|
private GameContainer container;
|
||||||
private StateBasedGame game;
|
private StateBasedGame game;
|
||||||
|
@ -164,7 +171,7 @@ public class SongMenu extends BasicGameState {
|
||||||
Image tab = Utils.getTabImage();
|
Image tab = Utils.getTabImage();
|
||||||
float tabX = buttonX + (tab.getWidth() / 2f);
|
float tabX = buttonX + (tab.getWidth() / 2f);
|
||||||
float tabY = (height * 0.15f) - (tab.getHeight() / 2f) - 2f;
|
float tabY = (height * 0.15f) - (tab.getHeight() / 2f) - 2f;
|
||||||
float tabOffset = (width - buttonX) / sortTabs.length;
|
float tabOffset = (width - buttonX - tab.getWidth()) / (sortTabs.length - 1);
|
||||||
for (int i = 0; i < sortTabs.length; i++)
|
for (int i = 0; i < sortTabs.length; i++)
|
||||||
sortTabs[i] = new GUIMenuButton(tab, tabX + (i * tabOffset), tabY);
|
sortTabs[i] = new GUIMenuButton(tab, tabX + (i * tabOffset), tabY);
|
||||||
|
|
||||||
|
@ -178,7 +185,7 @@ public class SongMenu extends BasicGameState {
|
||||||
|
|
||||||
search = new TextField(
|
search = new TextField(
|
||||||
container, Utils.FONT_DEFAULT,
|
container, Utils.FONT_DEFAULT,
|
||||||
(int) tabX + searchIcon.getWidth(), (int) ((height * 0.15f) - (tab.getHeight() * 5 / 2f)),
|
(int) tabX + searchIcon.getWidth(), (int) ((height * 0.15f) - (tab.getHeight() * 2.5f)),
|
||||||
(int) (buttonWidth / 2), Utils.FONT_DEFAULT.getHeight()
|
(int) (buttonWidth / 2), Utils.FONT_DEFAULT.getHeight()
|
||||||
);
|
);
|
||||||
search.setBackgroundColor(Color.transparent);
|
search.setBackgroundColor(Color.transparent);
|
||||||
|
@ -191,8 +198,16 @@ public class SongMenu extends BasicGameState {
|
||||||
Image optionsIcon = new Image("options.png").getScaledCopy(iconScale);
|
Image optionsIcon = new Image("options.png").getScaledCopy(iconScale);
|
||||||
optionsButton = new GUIMenuButton(optionsIcon, search.getX() - (optionsIcon.getWidth() * 1.5f), search.getY());
|
optionsButton = new GUIMenuButton(optionsIcon, search.getX() - (optionsIcon.getWidth() * 1.5f), search.getY());
|
||||||
|
|
||||||
|
// music note
|
||||||
int musicNoteDim = (int) (Utils.FONT_LARGE.getHeight() * 0.75f + Utils.FONT_DEFAULT.getHeight());
|
int musicNoteDim = (int) (Utils.FONT_LARGE.getHeight() * 0.75f + Utils.FONT_DEFAULT.getHeight());
|
||||||
musicNote = new Image("music-note.png").getScaledCopy(musicNoteDim, musicNoteDim);
|
musicNote = new Image("music-note.png").getScaledCopy(musicNoteDim, musicNoteDim);
|
||||||
|
|
||||||
|
// loader
|
||||||
|
SpriteSheet spr = new SpriteSheet(
|
||||||
|
new Image("loader.png").getScaledCopy(musicNoteDim / 48f),
|
||||||
|
musicNoteDim, musicNoteDim
|
||||||
|
);
|
||||||
|
loader = new Animation(spr, 50);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -218,16 +233,19 @@ public class SongMenu extends BasicGameState {
|
||||||
|
|
||||||
// header
|
// header
|
||||||
if (focusNode != null) {
|
if (focusNode != null) {
|
||||||
musicNote.draw();
|
if (MusicController.isTrackLoading())
|
||||||
int musicNoteWidth = musicNote.getWidth();
|
loader.draw();
|
||||||
int musicNoteHeight = musicNote.getHeight();
|
else
|
||||||
|
musicNote.draw();
|
||||||
|
int iconWidth = musicNote.getWidth();
|
||||||
|
int iconHeight = musicNote.getHeight();
|
||||||
|
|
||||||
String[] info = focusNode.getInfo();
|
String[] info = focusNode.getInfo();
|
||||||
g.setColor(Color.white);
|
g.setColor(Color.white);
|
||||||
Utils.FONT_LARGE.drawString(musicNoteWidth + 5, -3, info[0]);
|
Utils.FONT_LARGE.drawString(iconWidth + 5, -3, info[0]);
|
||||||
Utils.FONT_DEFAULT.drawString(
|
Utils.FONT_DEFAULT.drawString(
|
||||||
musicNoteWidth + 5, -3 + Utils.FONT_LARGE.getHeight() * 0.75f, info[1]);
|
iconWidth + 5, -3 + Utils.FONT_LARGE.getHeight() * 0.75f, info[1]);
|
||||||
int headerY = musicNoteHeight - 3;
|
int headerY = iconHeight - 3;
|
||||||
Utils.FONT_BOLD.drawString(5, headerY, info[2]);
|
Utils.FONT_BOLD.drawString(5, headerY, info[2]);
|
||||||
headerY += Utils.FONT_BOLD.getLineHeight() - 6;
|
headerY += Utils.FONT_BOLD.getLineHeight() - 6;
|
||||||
Utils.FONT_DEFAULT.drawString(5, headerY, info[3]);
|
Utils.FONT_DEFAULT.drawString(5, headerY, info[3]);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user