feat: highscore dialog and list

This commit is contained in:
Martin Prokoph
2025-08-01 20:24:14 +02:00
parent 93c0ee5f95
commit d10313ea76
9 changed files with 72 additions and 8 deletions

View File

@@ -9,8 +9,8 @@ public class HighScores {
private static final NightJson json = new NightJson(HighScores.class, "tetris_scores.json5");
public static Map<String, Integer> scores = new HashMap<>();
public static void addScore(int score) {
scores.put(String.valueOf(System.currentTimeMillis()), score);
public static void addScore(String playerName, int score) {
scores.put(playerName, score);
write();
}

View File

@@ -52,11 +52,11 @@ public class Tetris {
public static void stopGame() {
SoundUtil.stopMusic("/music/theme.wav");
HighScores.addScore(space.getScore());
if (gravityTask != null) gravityTask.cancel();
timer.purge();
if (ui.getMenuPanel() instanceof ScoreMenu) ((ScoreMenu) ui.getMenuPanel()).gameOver();
ui.transferFocus();
if (HighScores.scores.values().stream().noneMatch(hs -> hs > space.getScore())) ui.showHighscoreDialog(space.getScore());
}
public static void updateScore(int score) {

View File

@@ -0,0 +1,45 @@
package eu.midnightdust.yaytris.ui;
import eu.midnightdust.yaytris.HighScores;
import javax.swing.*;
import java.awt.*;
import java.util.ArrayList;
import java.util.List;
import static eu.midnightdust.yaytris.ui.TetrisUI.scale;
public class HighScoreMenu extends JPanel {
final TetrisUI ui;
HighScoreMenu(int x, int y, int width, int height, TetrisUI ui) {
this.ui = ui;
this.setBounds(x, y, width, height);
this.setLayout(null);
this.add(new JLabel("Highscores:"));
List<String> highscores = new ArrayList<>();
for (String key : HighScores.scores.keySet()) {
highscores.add(String.format("%s %s", HighScores.scores.get(key), key));
}
highscores.sort((s1, s2) -> Integer.compare(Integer.parseInt(s2.split("")[0].replace(" ", "")), Integer.parseInt(s1.split("")[0].replace(" ", ""))));
JList<String> highscoreList = new JList<>(highscores.toArray(String[]::new));
JScrollPane highscoreScrollPane = new JScrollPane(highscoreList);
this.add(highscoreScrollPane);
highscoreScrollPane.setBounds(scale(60), scale(43), scale(100), scale(80));
JButton backButton = new JButton("Zurück");
backButton.addActionListener(ui::openMainMenu);
backButton.setBounds(scale(60), scale(140), scale(100), scale(20));
this.add(backButton);
}
@Override
public Component add(Component comp) {
if (comp instanceof JLabel) {
comp.setBounds(scale(60), scale(30), scale(100), scale(7));
}
return super.add(comp);
}
}

View File

@@ -18,6 +18,10 @@ public class MainMenu extends AbstractMenu {
settingsButton.addActionListener(ui::openSettings);
this.add(settingsButton);
JButton highscoreButton = new JButton("Highscores");
highscoreButton.addActionListener(ui::openHighscores);
this.add(highscoreButton);
JButton leaveButton = new JButton("Spiel verlassen");
leaveButton.addActionListener(e -> System.exit(0));
this.add(leaveButton);

View File

@@ -70,7 +70,7 @@ public class SettingsMenu extends JPanel {
public Component add(Component comp) {
comp.setBounds(scale(60), scale(20+23*this.getComponentCount()-labelAmount*10), scale(100), scale(20));
if (comp instanceof JLabel) {
comp.setBounds(scale(60), scale(50+23*(this.getComponentCount()-1)-labelAmount*10), scale(100), scale(5));
comp.setBounds(scale(60), scale(50+23*(this.getComponentCount()-1)-labelAmount*10), scale(100), scale(7));
labelAmount++;
}
if (comp instanceof JComponent) setFontScale((JComponent) comp);

View File

@@ -1,5 +1,6 @@
package eu.midnightdust.yaytris.ui;
import eu.midnightdust.yaytris.HighScores;
import eu.midnightdust.yaytris.Tetris;
import eu.midnightdust.yaytris.util.CatppuccinColor;
@@ -114,6 +115,20 @@ public class TetrisUI extends JFrame implements KeyListener {
this.repaint();
}
public void openHighscores(ActionEvent actionEvent) {
if (this.menuPanel != null) this.remove(menuPanel);
menuPanel = new HighScoreMenu(scale(170), scale(40), scale(220), scale(226), this);
menuPanel.setBackground(CatppuccinColor.BASE.getColor());
menuPanel.setBorder(new LineBorder(CatppuccinColor.SURFACE0.getColor(), scale(2)));
this.add(menuPanel);
this.repaint();
}
public void showHighscoreDialog(int score) {
String playerName = JOptionPane.showInputDialog(null, "Gib deinen Namen ein:", "Neuer Highscore!", JOptionPane.PLAIN_MESSAGE);
HighScores.addScore(playerName, score);
}
// Source: https://stackoverflow.com/a/19746437
private void setWindowPosition(JFrame window, int screen) {
GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();

View File

@@ -117,7 +117,7 @@ public class NightJson {
Iterator<String> it = Arrays.stream(currentString.substring(1, currentString.length()-1).split(",")).iterator();
while (it.hasNext()) {
String pair = it.next();
System.out.println(pair);
if (!pair.contains(":")) break;
int semicolonPos = pair.indexOf(":");
Class<?> keyType = getPrimitiveType((Class<?>) ((ParameterizedType) field.getGenericType()).getActualTypeArguments()[0]);
Class<?> valType = getPrimitiveType((Class<?>) ((ParameterizedType) field.getGenericType()).getActualTypeArguments()[1]);

View File

@@ -1,3 +1,3 @@
{
"scores": {"1754065988809": 105,"1754067853918": 113,"1754067067271": 49}
"scores": {"Martin": 5703}
}

View File

@@ -1,7 +1,7 @@
{
"musicVolume": 25,
"musicVolume": 19,
"soundVolume": 100,
"guiScale": 6.0,
"shouldScaleSpeed": false,
"shouldScaleSpeed": true,
"difficulty": "Normal"
}