Ingame scoreboard initial implementation

This commit is contained in:
MatteoS 2015-11-29 09:56:10 +01:00
parent 78511737ce
commit 6f685cf5c7
3 changed files with 97 additions and 3 deletions

View File

@ -1396,10 +1396,9 @@ public class GameData {
* @return the ScoreData object
*/
public ScoreData getScoreData(Beatmap beatmap) {
if (scoreData != null)
return scoreData;
if (scoreData == null)
scoreData = new ScoreData();
scoreData = new ScoreData();
scoreData.timestamp = System.currentTimeMillis() / 1000L;
scoreData.MID = beatmap.beatmapID;
scoreData.MSID = beatmap.beatmapSetID;
@ -1419,6 +1418,7 @@ public class GameData {
scoreData.mods = GameMod.getModState();
scoreData.replayString = (replay == null) ? null : replay.getReplayFilename();
scoreData.playerName = null; // TODO
return scoreData;
}

View File

@ -328,6 +328,40 @@ public class ScoreData implements Comparable<ScoreData> {
c.a = oldAlpha;
}
/**
* Draws the score ingame (smaller and with less information).
* @param g the current graphics context
* @param vPos the base y position of the scoreboard
* @param rank the current rank of this score
* @param position the animated position offset
* @param data an instance of GameData to draw rank number
* @param alpha the transparancy of the score
* @param isActive if this score is the one currently played
*/
public void drawSmall(Graphics g, int vPos, int rank, float position, GameData data, float alpha, boolean isActive) {
int rectHeight = data.getScoreSymbolImage('0').getHeight();
int vertDistance = rectHeight + 10;
int yPos = (int)(vPos + position * vertDistance - rectHeight/2);
String scoreString = String.format("%d (%dx)", score, combo);
String rankString = String.format("%d", rank);
int rectWidth = (int) (170 * GameImage.getUIscale());
Color rectColor = isActive ? Colors.YELLOW_ALPHA : Colors.BLACK_ALPHA;
rectColor.a = 0.5f * alpha;
g.setColor(rectColor);
g.fillRect(0, yPos, rectWidth, rectHeight);
data.drawSymbolString(rankString, rectWidth, yPos, 1.0f, 0.5f*alpha, true);
if (playerName != null) {
Colors.WHITE_ALPHA.a = 0.5f * alpha;
Fonts.MEDIUM.drawString(0, yPos, playerName, Colors.WHITE_ALPHA);
}
Colors.WHITE_ALPHA.a = alpha;
Fonts.MEDIUMBOLD.drawString(0, yPos + rectHeight - Fonts.MEDIUM.getLineHeight(), scoreString, Colors.WHITE_ALPHA);
}
/**
* Returns the tooltip string for this score.
*/

View File

@ -101,6 +101,12 @@ public class Game extends BasicGameState {
/** Maximum rotation, in degrees, over fade out upon death. */
private static final float MAX_ROTATION = 90f;
/** The duration of the score changing animation */
private static final float SCOREBOARD_ANIMATION_TIME = 500f;
/** The time the scoreboard takes to fade in */
private static final float SCOREBOARD_FADE_IN_TIME = 500f;
/** Minimum time before start of song, in milliseconds, to process skip-related actions. */
private static final int SKIP_OFFSET = 2000;
@ -256,6 +262,18 @@ public class Game extends BasicGameState {
/** Music position bar coordinates and dimensions (for replay seeking). */
private float musicBarX, musicBarY, musicBarWidth, musicBarHeight;
/** The previous scores. */
private ScoreData[] previousScores;
/** The current rank in the scores. */
private int currentRank;
/** The time the rank was last updated. */
private int lastRankUpdateTime;
/** Is the scoreboard visible? */
private boolean scoreboardVisible;
/** Music position bar background colors. */
private static final Color
MUSICBAR_NORMAL = new Color(12, 9, 10, 0.25f),
@ -482,6 +500,7 @@ public class Game extends BasicGameState {
arrow.draw(width * 0.75f, height * 0.75f);
}
}
}
// non-break
@ -563,6 +582,38 @@ public class Game extends BasicGameState {
drawHitObjects(g, trackPosition);
}
if (previousScores != null && trackPosition >= firstObjectTime && !GameMod.RELAX.isActive() && !GameMod.AUTOPILOT.isActive() && scoreboardVisible) {
ScoreData currentScore = data.getScoreData(beatmap);
while (currentRank > 0 && previousScores[currentRank-1].score < currentScore.score) {
currentRank--;
lastRankUpdateTime = trackPosition;
}
float animation = AnimationEquation.IN_OUT_QUAD.calc(Utils.clamp((trackPosition - lastRankUpdateTime) / SCOREBOARD_ANIMATION_TIME, 0f, 1f));
float fadeIn = Utils.clamp((trackPosition - firstObjectTime) / SCOREBOARD_FADE_IN_TIME, 0f, 1f);
int scoreboardPosition = 2 * container.getHeight() / 3;
if (currentRank < 4) {
//draw the (new) top 5 ranks
for (int i = 0; i < 4; i++) {
int ii = i + (i>=currentRank ? 1 : 0);
if (i < previousScores.length)
previousScores[i].drawSmall(g, scoreboardPosition, ii + 1, ii + (i==currentRank ? animation-3f : -2f), data, fadeIn, false);
}
currentScore.drawSmall(g, scoreboardPosition, currentRank + 1, currentRank - 1f - animation, data, fadeIn, true);
} else {
//draw the top 2 and next 2 ranks
previousScores[0].drawSmall(g, scoreboardPosition, 1, -2f, data, fadeIn, false);
previousScores[1].drawSmall(g, scoreboardPosition, 2, -1f, data, fadeIn, false);
previousScores[currentRank-2].drawSmall(g, scoreboardPosition, currentRank - 1, animation - 1f, data, fadeIn*animation, false);
previousScores[currentRank-1].drawSmall(g, scoreboardPosition, currentRank, animation, data, fadeIn, false);
currentScore.drawSmall(g, scoreboardPosition, currentRank + 1, 2f, data, fadeIn, true);
if (animation < 1.0f && currentRank < previousScores.length) {
previousScores[currentRank].drawSmall(g, scoreboardPosition, currentRank + 2, 1f + 5 * animation, data, fadeIn*(1f - animation), false);
}
}
}
if (GameMod.AUTO.isActive())
GameImage.UNRANKED.getImage().drawCentered(width / 2, height * 0.077f);
@ -986,6 +1037,9 @@ public class Game extends BasicGameState {
case Input.KEY_F12:
Utils.takeScreenShot();
break;
case Input.KEY_TAB:
scoreboardVisible = ! scoreboardVisible;
break;
}
}
@ -1138,6 +1192,12 @@ public class Game extends BasicGameState {
if (beatmap == null || beatmap.objects == null)
throw new RuntimeException("Running game with no beatmap loaded.");
// fetch previous results
previousScores = ScoreDB.getMapScores(beatmap);
lastRankUpdateTime = -1000;
if (previousScores != null)
currentRank = previousScores.length;
scoreboardVisible = true;
// free all previously cached hitobject to framebuffer mappings if some still exist
FrameBufferCache.getInstance().freeMap();