fix highscore implementation and decrease projectile damage

This commit is contained in:
Niklas Haiden
2026-05-08 19:37:57 +02:00
parent 3fcbd8ce51
commit 514962321c
4 changed files with 52 additions and 39 deletions
+1
View File
@@ -55,6 +55,7 @@ class Endscreen:
) )
self.highscore = Highscore() self.highscore = Highscore()
self.highscore.add_score(self.player_name or "Student", self.score_ects, self.time_survived, self.won)
def run(self): def run(self):
# get events # get events
-30
View File
@@ -4,35 +4,5 @@
"ects": 55, "ects": 55,
"time": "02:00", "time": "02:00",
"won": true "won": true
},
{
"name": "Anna",
"ects": 48,
"time": "01:35",
"won": true
},
{
"name": "Kevin",
"ects": 42,
"time": "01:58",
"won": true
},
{
"name": "Lena",
"ects": 35,
"time": "01:44",
"won": false
},
{
"name": "Lukas",
"ects": 20,
"time": "00:58",
"won": false
},
{
"name": "Max",
"ects": 12,
"time": "00:30",
"won": false
} }
] ]
+49 -7
View File
@@ -3,9 +3,9 @@ import pygame
from src.settings import HIGHSCORE_COLOR_FONT, HIGHSCORE_COLOR_TABLE from src.settings import HIGHSCORE_COLOR_FONT, HIGHSCORE_COLOR_TABLE
class Highscore: class Highscore:
def __init__(self): def __init__(self, path="src/highscore.json"):
# fix path to json file with highscores # fix path to json file with highscores
self.path = "src/highscore.json" self.path = path
self.font_title = pygame.font.SysFont("Arial", 28, bold=True) self.font_title = pygame.font.SysFont("Arial", 28, bold=True)
self.font_score = pygame.font.SysFont("Arial", 18, bold=True) self.font_score = pygame.font.SysFont("Arial", 18, bold=True)
@@ -23,7 +23,9 @@ class Highscore:
:return: All scores form json file. :return: All scores form json file.
""" """
with open(self.path, "r") as f: with open(self.path, "r") as f:
return json.load(f) scores = json.load(f)
return scores if isinstance(scores, list) else []
def save_scores(self, scores): def save_scores(self, scores):
""" """
@@ -57,8 +59,7 @@ class Highscore:
} }
scores.append(new_score) scores.append(new_score)
# sort by ects descending self.sort_scores(scores)
scores.sort(key=lambda score: score["ects"], reverse=True)
# keep only top 50 elements # keep only top 50 elements
scores = scores[:50] scores = scores[:50]
@@ -71,9 +72,50 @@ class Highscore:
:return: Return top 5 scores as list. :return: Return top 5 scores as list.
""" """
scores = self.load_scores() scores = self.load_scores()
scores.sort(key=lambda score: score["ects"], reverse=True) self.sort_scores(scores)
return scores[:5] return scores[:5]
@classmethod
def sort_scores(cls, scores):
scores.sort(key=cls.get_rank_key)
@staticmethod
def get_rank_key(score):
return (
not bool(score.get("won", False)),
-Highscore.safe_int(score.get("ects", 0)),
-Highscore.parse_time(score.get("time", 0)),
str(score.get("name", "")).lower(),
)
@staticmethod
def safe_int(value):
try:
return int(value)
except (TypeError, ValueError):
return 0
@staticmethod
def parse_time(value):
if isinstance(value, (int, float)):
return int(value)
if isinstance(value, str):
parts = value.split(":")
try:
if len(parts) == 2:
return int(parts[0]) * 60 + int(parts[1])
return int(value)
except ValueError:
return 0
return 0
@staticmethod
def format_time(value):
total_seconds = Highscore.parse_time(value)
minutes = total_seconds // 60
seconds = total_seconds % 60
return f"{minutes:02}:{seconds:02}"
def get_top_scores_formatted(self): def get_top_scores_formatted(self):
""" """
Get top 5 scores from highscore file in nice format. Get top 5 scores from highscore file in nice format.
@@ -88,7 +130,7 @@ class Highscore:
line = ( line = (
f"{index + 1}. {score['name']} | " f"{index + 1}. {score['name']} | "
f"ECTS: {score['ects']} | " f"ECTS: {score['ects']} | "
f"Time: {score['time']} | " f"Time: {self.format_time(score['time'])} | "
f"Result: {result}" f"Result: {result}"
) )
+2 -2
View File
@@ -64,7 +64,7 @@ COFFEE_HEAL_VALUE = 20
# --- TOWER --- # --- TOWER ---
TOWER_COST = 10 TOWER_COST = 10
PROJECTILE_DMG = 7 PROJECTILE_DMG = 4
PROJECTILE_SPEED = 7 PROJECTILE_SPEED = 7
COLOR_PROJECTILE = (200, 200, 0) COLOR_PROJECTILE = (200, 200, 0)
TOWER_TIMER = 30000 # how long the tower stays and attack before it disappears TOWER_TIMER = 30000 # how long the tower stays and attack before it disappears
@@ -90,7 +90,7 @@ MONSTER_MAX_COUNT = 1
MONSTER_SPAWN_INTERVAL = 8000 # ms until a replacement monster spawns MONSTER_SPAWN_INTERVAL = 8000 # ms until a replacement monster spawns
MONSTER_SPEED = 90.0 MONSTER_SPEED = 90.0
MONSTER_DOOR_DAMAGE = ZOMBIE_MEDIUM_DMG MONSTER_DOOR_DAMAGE = ZOMBIE_MEDIUM_DMG
MONSTER_ATTACK_INTERVAL = 1000 # ms between door attacks MONSTER_ATTACK_INTERVAL = 2000 # ms between door attacks
# --- HUD --- # --- HUD ---
HUD_FONT = "Arial" HUD_FONT = "Arial"