Compare commits
3 Commits
f58cd493bb
...
f881427a67
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f881427a67 | ||
|
|
db537f84ae | ||
|
|
5490ff8b5d |
@@ -4,14 +4,15 @@ Erstellt für das Modul "Anwendungsorientierte Programmierung" im Studiengang Me
|
|||||||
Dieser Code wurde vollständig von mir und ohne die Verwendung von LLMs geschrieben.
|
Dieser Code wurde vollständig von mir und ohne die Verwendung von LLMs geschrieben.
|
||||||
An einigen Stellen wurde auf Wissen von StackOverflow und Baeldung zugegriffen – dies ist immer in den JavaDocs gekennzeichnet.
|
An einigen Stellen wurde auf Wissen von StackOverflow und Baeldung zugegriffen – dies ist immer in den JavaDocs gekennzeichnet.
|
||||||
Die Commit-Historie ist [auf meinem Gitea](https://git.midnightdust.eu/Motschen/TetrisClone/commits/branch/main) einsehbar.
|
Die Commit-Historie ist [auf meinem Gitea](https://git.midnightdust.eu/Motschen/TetrisClone/commits/branch/main) einsehbar.
|
||||||
|
Gradle ist als Build-Tool eingerichtet, um elegant Jar-Dateien zu bauen, dabei aber völlig optional.
|
||||||
|
|
||||||
Können Sie meinen Highscore schlagen?
|
Können Sie meinen Highscore schlagen?
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
## Im Falle einer IllegalArgumentException
|
## Im Falle einer IllegalArgumentException
|
||||||
Eclipse ist unfähig Java-Konventionen zu befolgen und fügt den resources-Ordner nicht automatisch zum classpath hinzu.
|
Eclipse ist unfähig, Java-Konventionen zu befolgen und fügt den 'resources'-Ordner nicht automatisch zum classpath hinzu.
|
||||||
Um das zu beheben, gehen Sie in die Projekteinstellungen -> Java Build Path -> Source und fügen Sie den resources-Ordner manuell hinzu.
|
Um das zu beheben, gehen Sie in die Projekteinstellungen -> Java Build Path -> Source und fügen Sie den Ordner `src/main/resources` manuell hinzu.
|
||||||
|
|
||||||
## Rechtliche Hinweise
|
## Rechtliche Hinweise
|
||||||
»Tetris« ist eine eingetragene Marke von The Tetris Company, Inc.
|
»Tetris« ist eine eingetragene Marke von The Tetris Company, Inc.
|
||||||
|
|||||||
@@ -1,13 +1,22 @@
|
|||||||
package eu.midnightdust.yaytris;
|
package eu.midnightdust.yaytris;
|
||||||
|
|
||||||
|
import eu.midnightdust.yaytris.util.Difficulty;
|
||||||
|
import eu.midnightdust.yaytris.util.json.Comment;
|
||||||
import eu.midnightdust.yaytris.util.json.NightJson;
|
import eu.midnightdust.yaytris.util.json.NightJson;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
@SuppressWarnings("unused") // Comments are unused in code, but are added to the JSON file for readability
|
||||||
public class HighScores {
|
public class HighScores {
|
||||||
private static final NightJson json = new NightJson(HighScores.class, "tetris_scores.json5");
|
private static final NightJson json = new NightJson(HighScores.class, "tetris_scores.json5");
|
||||||
public static Map<String, Integer> scores = new HashMap<>();
|
public static Comment c1 = new Comment("Highscores for each difficulty");
|
||||||
|
public static Map<String, Integer> Noob = new HashMap<>();
|
||||||
|
public static Map<String, Integer> Easy = new HashMap<>();
|
||||||
|
public static Map<String, Integer> Normal = new HashMap<>();
|
||||||
|
public static Map<String, Integer> Hard = new HashMap<>();
|
||||||
|
public static Map<String, Integer> Extreme = new HashMap<>();
|
||||||
|
public static Map<String, Integer> WTF = new HashMap<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Saves a new high score for the specified player
|
* Saves a new high score for the specified player
|
||||||
@@ -16,10 +25,21 @@ public class HighScores {
|
|||||||
* @param score the score to save
|
* @param score the score to save
|
||||||
*/
|
*/
|
||||||
public static void addScore(String playerName, int score) {
|
public static void addScore(String playerName, int score) {
|
||||||
scores.put(playerName, score);
|
diffToMap(Settings.difficulty).put(playerName, score);
|
||||||
write();
|
write();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Map<String, Integer> diffToMap(Difficulty difficulty) {
|
||||||
|
switch (difficulty) {
|
||||||
|
case EASY: return Easy;
|
||||||
|
case NORMAL: return Normal;
|
||||||
|
case HARD: return Hard;
|
||||||
|
case EXTREME: return Extreme;
|
||||||
|
case WTF: return WTF;
|
||||||
|
default: return Noob;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static void load() {
|
public static void load() {
|
||||||
json.readJson();
|
json.readJson();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -97,7 +97,7 @@ public class Tetris {
|
|||||||
timer.purge();
|
timer.purge();
|
||||||
if (ui.getMenuPanel() instanceof ScoreMenu) ((ScoreMenu) ui.getMenuPanel()).gameOver();
|
if (ui.getMenuPanel() instanceof ScoreMenu) ((ScoreMenu) ui.getMenuPanel()).gameOver();
|
||||||
ui.transferFocus();
|
ui.transferFocus();
|
||||||
if (HighScores.scores.values().stream().noneMatch(hs -> hs > space.getScore())) ui.showHighscoreDialog(space.getScore());
|
if (HighScores.diffToMap(Settings.difficulty).values().stream().noneMatch(hs -> hs > space.getScore())) ui.showHighscoreDialog(space.getScore());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -125,12 +125,12 @@ public class Tetris {
|
|||||||
* @see ScoreMenu
|
* @see ScoreMenu
|
||||||
*/
|
*/
|
||||||
public static void updateLevel(int score) {
|
public static void updateLevel(int score) {
|
||||||
int newLevel = Math.max(0, (int) (score / 1000f));
|
int newLevel = Math.max(0, (int) (score / 1400f));
|
||||||
if (newLevel != space.level) {
|
if (newLevel != space.level) {
|
||||||
if (gravityTask != null && Settings.shouldScaleSpeed) {
|
if (gravityTask != null && Settings.shouldScaleSpeed) {
|
||||||
gravityTask.cancel();
|
gravityTask.cancel();
|
||||||
gravityTask = new GravityTimerTask();
|
gravityTask = new GravityTimerTask();
|
||||||
timer.scheduleAtFixedRate(gravityTask, 0, Math.max(10, Settings.difficulty.getTimerPeriod() - (Settings.difficulty.getTimerPeriod() / 8) * newLevel));
|
timer.scheduleAtFixedRate(gravityTask, 0, Math.max(10, Settings.difficulty.getTimerPeriod() - (Settings.difficulty.getTimerPeriod() / 16) * newLevel));
|
||||||
}
|
}
|
||||||
space.level = newLevel;
|
space.level = newLevel;
|
||||||
if (ui.getMenuPanel() instanceof ScoreMenu) ((ScoreMenu) ui.getMenuPanel()).updateLevel(newLevel);
|
if (ui.getMenuPanel() instanceof ScoreMenu) ((ScoreMenu) ui.getMenuPanel()).updateLevel(newLevel);
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package eu.midnightdust.yaytris.ui;
|
package eu.midnightdust.yaytris.ui;
|
||||||
|
|
||||||
import eu.midnightdust.yaytris.HighScores;
|
import eu.midnightdust.yaytris.HighScores;
|
||||||
|
import eu.midnightdust.yaytris.Settings;
|
||||||
import eu.midnightdust.yaytris.util.CatppuccinColor;
|
import eu.midnightdust.yaytris.util.CatppuccinColor;
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
@@ -8,6 +9,7 @@ import javax.swing.border.LineBorder;
|
|||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import static eu.midnightdust.yaytris.Translation.t;
|
import static eu.midnightdust.yaytris.Translation.t;
|
||||||
import static eu.midnightdust.yaytris.ui.TetrisUI.scale;
|
import static eu.midnightdust.yaytris.ui.TetrisUI.scale;
|
||||||
@@ -20,11 +22,12 @@ public class HighScoreMenu extends JPanel {
|
|||||||
this.setBounds(x, y, width, height);
|
this.setBounds(x, y, width, height);
|
||||||
this.setLayout(null);
|
this.setLayout(null);
|
||||||
|
|
||||||
this.add(new JLabel(t("highscores.title")));
|
this.add(new JLabel(t("highscores.title", Settings.difficulty)));
|
||||||
|
|
||||||
List<String> highscores = new ArrayList<>();
|
List<String> highscores = new ArrayList<>();
|
||||||
for (String key : HighScores.scores.keySet()) {
|
Map<String, Integer> scores = HighScores.diffToMap(Settings.difficulty);
|
||||||
highscores.add(String.format("%s – %s", HighScores.scores.get(key), key));
|
for (String key : scores.keySet()) {
|
||||||
|
highscores.add(String.format("%s – %s", scores.get(key), key));
|
||||||
}
|
}
|
||||||
highscores.sort((s1, s2) -> Integer.compare(Integer.parseInt(s2.split("–")[0].replace(" ", "")), Integer.parseInt(s1.split("–")[0].replace(" ", ""))));
|
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));
|
JList<String> highscoreList = new JList<>(highscores.toArray(String[]::new));
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ import java.util.regex.Pattern;
|
|||||||
* Concept inspired by GSON
|
* Concept inspired by GSON
|
||||||
*/
|
*/
|
||||||
public class NightJson {
|
public class NightJson {
|
||||||
private static final String KEY_PATTERN = "\"(-?[A-Za-z-_.]*)\":";
|
private static final String KEY_PATTERN = "\"(.*)\":";
|
||||||
Class<?> jsonClass;
|
Class<?> jsonClass;
|
||||||
Field jsonMap;
|
Field jsonMap;
|
||||||
String fileLocation;
|
String fileLocation;
|
||||||
@@ -175,21 +175,8 @@ public class NightJson {
|
|||||||
private Object getValue(String s, String key, Function<String, Class<?>> keyToType, Iterator<String> pairIterator) {
|
private Object getValue(String s, String key, Function<String, Class<?>> keyToType, Iterator<String> pairIterator) {
|
||||||
String val = s.split(KEY_PATTERN, 2)[1];
|
String val = s.split(KEY_PATTERN, 2)[1];
|
||||||
|
|
||||||
if (s.contains("{")) { // Handle maps recursively
|
if (s.contains("{")) {
|
||||||
StringBuilder submapString = new StringBuilder();
|
return readJsonMap(key, pairIterator, val);
|
||||||
int level = charAmount(s, '{');
|
|
||||||
submapString.append(val);
|
|
||||||
if (pairIterator.hasNext()) submapString.append(",");
|
|
||||||
while (pairIterator.hasNext()) {
|
|
||||||
String next = pairIterator.next();
|
|
||||||
submapString.append(next);
|
|
||||||
level += charAmount(next, '{');
|
|
||||||
level -= charAmount(next, '}');
|
|
||||||
if (level <= 0) break;
|
|
||||||
if (pairIterator.hasNext()) submapString.append(",");
|
|
||||||
}
|
|
||||||
Optional<Field> field = getField(key);
|
|
||||||
return jsonToMap(String.valueOf(submapString), k -> field.isPresent() ? getTypeArgument(field.get(), 1) : String.class);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
while (val.startsWith(" ")) val = val.substring(1);
|
while (val.startsWith(" ")) val = val.substring(1);
|
||||||
@@ -200,6 +187,27 @@ public class NightJson {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle maps recursively
|
||||||
|
*/
|
||||||
|
private Map<String, Object> readJsonMap(String key, Iterator<String> pairIterator, String val) {
|
||||||
|
StringBuilder submapString = new StringBuilder();
|
||||||
|
String next = val;
|
||||||
|
int level = 0;
|
||||||
|
while (next != null) {
|
||||||
|
submapString.append(next);
|
||||||
|
level += charAmount(next, '{');
|
||||||
|
level -= charAmount(next, '}');
|
||||||
|
if (level <= 0) break;
|
||||||
|
if (!pairIterator.hasNext()) {
|
||||||
|
submapString.append(",");
|
||||||
|
next = pairIterator.next();
|
||||||
|
} else next = null;
|
||||||
|
}
|
||||||
|
Optional<Field> field = getField(key);
|
||||||
|
return jsonToMap(String.valueOf(submapString), k -> field.isPresent() ? getTypeArgument(field.get(), 1) : String.class);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Count the amount of appearances of a char in a string.
|
* Count the amount of appearances of a char in a string.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
"game.over": "Game over :(",
|
"game.over": "Game over :(",
|
||||||
"game.score": "Score: %s",
|
"game.score": "Score: %s",
|
||||||
"game.time": "Zeit: %s",
|
"game.time": "Zeit: %s",
|
||||||
"highscores.title": "Highscores:",
|
"highscores.title": "Highscores (%s):",
|
||||||
"menu.exit": "Spiel verlassen",
|
"menu.exit": "Spiel verlassen",
|
||||||
"menu.highscores": "Highscores",
|
"menu.highscores": "Highscores",
|
||||||
"menu.settings": "Einstellungen",
|
"menu.settings": "Einstellungen",
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
"game.over": "Game over :(",
|
"game.over": "Game over :(",
|
||||||
"game.score": "Score: %s",
|
"game.score": "Score: %s",
|
||||||
"game.time": "Time: %s",
|
"game.time": "Time: %s",
|
||||||
"highscores.title": "Highscores:",
|
"highscores.title": "Highscores (%s):",
|
||||||
"menu.exit": "Exit Game",
|
"menu.exit": "Exit Game",
|
||||||
"menu.highscores": "Highscores",
|
"menu.highscores": "Highscores",
|
||||||
"menu.settings": "Settings",
|
"menu.settings": "Settings",
|
||||||
|
|||||||
@@ -1,5 +1,11 @@
|
|||||||
{
|
{
|
||||||
"scores": {
|
// Highscores for each difficulty
|
||||||
"MartinProkoph": 8040
|
"Noob": {},
|
||||||
}
|
"Easy": {},
|
||||||
|
"Normal": {
|
||||||
|
"Martin": 10593
|
||||||
|
},
|
||||||
|
"Hard": {},
|
||||||
|
"Extreme": {},
|
||||||
|
"WTF": {}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user