add map highscores for singleplayer

This commit is contained in:
interfisch 2025-01-01 22:07:02 +01:00
parent 5194eab229
commit 0b63997ce4
5 changed files with 121 additions and 15 deletions

View file

@ -19,6 +19,7 @@ config/icon="res://icon.svg"
Gamestate="*res://scripts/gamestate.gd" Gamestate="*res://scripts/gamestate.gd"
ConfigFileHandler="*res://scripts/configFileHandler.gd" ConfigFileHandler="*res://scripts/configFileHandler.gd"
HighscoreHandler="*res://scripts/highscoreHandler.gd"
[display] [display]

View file

@ -260,15 +260,39 @@ text = "0.000"
vertical_alignment = 1 vertical_alignment = 1
[node name="countdown_label" type="Label" parent="hud"] [node name="countdown_label" type="Label" parent="hud"]
offset_left = 604.0 anchors_preset = 8
offset_top = 312.0 anchor_left = 0.5
offset_right = 644.0 anchor_top = 0.5
offset_bottom = 342.0 anchor_right = 0.5
anchor_bottom = 0.5
offset_left = -20.0
offset_top = -34.5
offset_right = 20.0
offset_bottom = 34.5
grow_horizontal = 2
grow_vertical = 2
theme_override_font_sizes/font_size = 50 theme_override_font_sizes/font_size = 50
text = "3" text = "3"
horizontal_alignment = 1 horizontal_alignment = 1
vertical_alignment = 1 vertical_alignment = 1
[node name="highscore_label" type="Label" parent="hud"]
visible = false
anchors_preset = 8
anchor_left = 0.5
anchor_top = 0.5
anchor_right = 0.5
anchor_bottom = 0.5
offset_left = -57.5
offset_top = 2.70999
offset_right = 57.5
offset_bottom = 71.71
grow_horizontal = 2
grow_vertical = 2
theme_override_font_sizes/font_size = 50
horizontal_alignment = 1
vertical_alignment = 1
[node name="overlaycolor" type="ColorRect" parent="hud"] [node name="overlaycolor" type="ColorRect" parent="hud"]
self_modulate = Color(1, 1, 1, 0) self_modulate = Color(1, 1, 1, 0)
offset_left = -25.0 offset_left = -25.0

View file

@ -11,6 +11,8 @@ extends Node2D
@onready var times_container: HFlowContainer = $hud/times_container @onready var times_container: HFlowContainer = $hud/times_container
@onready var timer_close: Timer = $timer_close @onready var timer_close: Timer = $timer_close
@onready var highscore_label: Label = $hud/highscore_label
const caroffset= 32+4 #space cars on start line const caroffset= 32+4 #space cars on start line
const caroffset_side= 16 const caroffset_side= 16
@ -35,6 +37,7 @@ var game_ended=false
# Called when the node enters the scene tree for the first time. # Called when the node enters the scene tree for the first time.
func _ready() -> void: func _ready() -> void:
Gamestate.resetTimeElapsed() Gamestate.resetTimeElapsed()
#countdown.start() #countdown.start()
@ -83,6 +86,8 @@ func _ready() -> void:
print("i_position="+str(i_position)+" carpos is ="+str(newcarinstance.getPosition())+" instancepos="+str(newcarinstance.position)+" colori="+str(player.colori)+" color="+str(player.color)) print("i_position="+str(i_position)+" carpos is ="+str(newcarinstance.getPosition())+" instancepos="+str(newcarinstance.position)+" colori="+str(player.colori)+" color="+str(player.color))
i+=1 i+=1
print("mapname="+str(Gamestate.getSelectedMapName()+"_"+str(Gamestate.getRounds())))
func custom_array_sort_rank(a, b): func custom_array_sort_rank(a, b):
return a.rank > b.rank #a>b = higher rank (more wins) -> better start position return a.rank > b.rank #a>b = higher rank (more wins) -> better start position
@ -110,11 +115,14 @@ func _process(delta: float) -> void:
if Input.is_action_pressed(Gamestate.userinput_prefix+str(id)): if Input.is_action_pressed(Gamestate.userinput_prefix+str(id)):
anyplayerkeypressed=true anyplayerkeypressed=true
id+=1 id+=1
if anyplayerkeypressed and timer_close.time_left<time_close_keypressed: if anyplayerkeypressed and timer_close.time_left<time_close_keypressed:
timer_close.wait_time=time_close_keypressed #set time back timer_close.wait_time=time_close_keypressed #set time back
timer_close.stop() #prepare for restarting at this time timer_close.stop() #prepare for restarting at this time
if !anyplayerkeypressed and timer_close.is_stopped(): if !anyplayerkeypressed and timer_close.is_stopped():
timer_close.start() #start timer when no key is pressed timer_close.start() #start timer when no key is pressed
func updateCameraMovement(delta: float): func updateCameraMovement(delta: float):
@ -234,6 +242,24 @@ func finishGame():
p.rank=p.rank+min(max((floatrank-p.rank),rankchangedown),rankchangeup) p.rank=p.rank+min(max((floatrank-p.rank),rankchangedown),rankchangeup)
print(" changed to rank "+str(p.rank)) print(" changed to rank "+str(p.rank))
i+=1 i+=1
if Gamestate.getPlayers().size()==1: #was played in singleplayer
var timediff=HighscoreHandler.updateHighscore(Gamestate.getSelectedMapName()+"_"+str(Gamestate.getRounds()),getfinalTimeByPlayer(Gamestate.getPlayers()[0]))
print("Timediff="+str(timediff))
timediff=round(timediff*1000)/1000
highscore_label.visible=true
if timediff==0: #same time or first entry
highscore_label.text=str(timediff)
highscore_label.modulate=Color(200,200,0)
elif timediff<0: #new highscore
highscore_label.text=str(timediff)
highscore_label.modulate=Color(0,0,200)
elif timediff>0: #worse time
highscore_label.text="+"+str(timediff)
highscore_label.modulate=Color(200,0,0)
game_hud_animations.play("game_end") game_hud_animations.play("game_end")
timer_close.start() timer_close.start()
@ -241,16 +267,26 @@ func finishGame():
func custom_array_sort_player_finaltime(a, b): func custom_array_sort_player_finaltime(a, b):
var cars=cars.get_children() #var cars=cars.get_children()
var finalTimeA=-1 var finalTimeA=getfinalTimeByPlayer(a)
var finalTimeB=-1 var finalTimeB=getfinalTimeByPlayer(b)
for c in cars: if finalTimeA != null and finalTimeB != null:
if c.reference_gamestateplayer==a: return finalTimeA < finalTimeB
finalTimeA=c.getCharacterBody().finalTime else:
elif c.reference_gamestateplayer==b: return false
finalTimeB=c.getCharacterBody().finalTime #for c in cars:
return finalTimeA < finalTimeB # if c.reference_gamestateplayer==a:
#finalTimeA=c.getCharacterBody().finalTime
#elif c.reference_gamestateplayer==b:
#finalTimeB=c.getCharacterBody().finalTime
func getfinalTimeByPlayer(player):
var cars=cars.get_children()
for c in cars:
if c.reference_gamestateplayer==player:
return c.getCharacterBody().finalTime
return null
func _on_timer_close_timeout() -> void: func _on_timer_close_timeout() -> void:
print("Close Map") print("Close Map")

View file

@ -10,7 +10,8 @@ var userinput_prefix="inputP"
var time_elapsed=0 var time_elapsed=0
var map_scene_name="" var map_scene_name=""
var map_scene_name_prefix="res://scenes/map_" var map_scene_path_prefix="res://scenes/"
var map_scene_name_prefix="map_"
var map_scene_name_postfix=".tscn" var map_scene_name_postfix=".tscn"
var rounds=3 var rounds=3
@ -26,9 +27,12 @@ func setRounds(r):
func getSelectedMap(): #return only short map name "00" func getSelectedMap(): #return only short map name "00"
return map_scene_name return map_scene_name
func getSelectedMapName():
return map_scene_name_prefix+map_scene_name
func getSelectedMapSceneName(): #returns full scene path "res://scenes/map_00.tscn" func getSelectedMapSceneName(): #returns full scene path "res://scenes/map_00.tscn"
return map_scene_name_prefix+map_scene_name+map_scene_name_postfix return map_scene_path_prefix+map_scene_name_prefix+map_scene_name+map_scene_name_postfix
func setSelectedMap(mapname): func setSelectedMap(mapname):
map_scene_name=mapname map_scene_name=mapname

View file

@ -0,0 +1,41 @@
extends Node
const HIGHSCORE_FILE_PATH = "highscores.json"
func updateHighscore(mapname:String,rounds:int,preset:int,time:float):
var highscores=loadHighscoreDict()
if highscores.has(mapname):
var lasthighscore=loadHighscore(mapname)
if time<lasthighscore: #better time
highscores[mapname].append({"created":Time.get_unix_time_from_system(),"time":time})
storeHighscoreDict(highscores)
return time-lasthighscore
else: #first entry
highscores[mapname]=[{"created":Time.get_unix_time_from_system(),"time":time}]
storeHighscoreDict(highscores)
return 0
func loadHighscore(mapname:String):
var highscores=loadHighscoreDict()
if highscores.has(mapname):
if highscores[mapname].size()>0:
return highscores[mapname][highscores[mapname].size()-1]["time"] #return last entry
else:
return null
func loadHighscoreDict():
var file = FileAccess.open(HIGHSCORE_FILE_PATH, FileAccess.READ)
if file == null:
return {}
var content = file.get_as_text()
return JSON.parse_string(content)
func storeHighscoreDict(content:Dictionary):
print("Saved Highscorefile:"+str(content))
var file = FileAccess.open(HIGHSCORE_FILE_PATH, FileAccess.WRITE)
file.store_string(JSON.stringify(content, "\t"))