From 491395e6b90c4382c4e9b2e0e2230dbf80d3fdb9 Mon Sep 17 00:00:00 2001 From: Dan Date: Thu, 9 May 2024 15:42:04 +0100 Subject: [PATCH] Add utility strings, update game state with drone count and points calculation. --- project.godot | 1 + scenes/scripts/drone_manager.gd | 3 +++ ui/LevelCompleteComponent.tscn | 22 ++++++++++++++- ui/scripts/level_complete_component.gd | 10 +++++++ ui/scripts/ui_component.gd | 5 +++- utility/game_state.gd | 32 +++++++++++++++++++--- utility/utility_strings.gd | 37 ++++++++++++++++++++++++++ 7 files changed, 105 insertions(+), 5 deletions(-) create mode 100644 utility/utility_strings.gd diff --git a/project.godot b/project.godot index 5280c24..57d0046 100644 --- a/project.godot +++ b/project.godot @@ -18,6 +18,7 @@ config/icon="res://icon.svg" [autoload] GameState="*res://utility/game_state.gd" +Str="*res://utility/utility_strings.gd" [display] diff --git a/scenes/scripts/drone_manager.gd b/scenes/scripts/drone_manager.gd index acca62f..c732dff 100644 --- a/scenes/scripts/drone_manager.gd +++ b/scenes/scripts/drone_manager.gd @@ -53,6 +53,7 @@ func spawn_drone(drone_type : String) -> void: new_drone = dancer_drone.instantiate() # Hide the dancer button %SpawnDancer.visible = false + GameState.game_start() # Start the game when the first dancer is placed elif drone_type == "distractor": new_drone = distractor_drone.instantiate() elif drone_type == "collector": @@ -73,6 +74,8 @@ func spawn_drone(drone_type : String) -> void: reset_node_highlights() + GameState.add_drone() ## Increase drone count on the game state + func place_drone(drone_type : String) -> void: if !spawning_drone: Input.set_custom_mouse_cursor(cursor, Input.CURSOR_ARROW, Vector2(32, 32)) diff --git a/ui/LevelCompleteComponent.tscn b/ui/LevelCompleteComponent.tscn index e5acceb..8f2b81c 100644 --- a/ui/LevelCompleteComponent.tscn +++ b/ui/LevelCompleteComponent.tscn @@ -37,7 +37,27 @@ theme_override_constants/margin_bottom = 10 [node name="CenterContainer" type="CenterContainer" parent="MarginContainer"] layout_mode = 2 -[node name="Label" type="Label" parent="MarginContainer/CenterContainer"] +[node name="VBoxContainer" type="VBoxContainer" parent="MarginContainer/CenterContainer"] +layout_mode = 2 + +[node name="HappyBees" type="Label" parent="MarginContainer/CenterContainer/VBoxContainer"] layout_mode = 2 text = "The Bees Are Happy!" label_settings = SubResource("LabelSettings_phhcy") + +[node name="TimeSpent" type="Label" parent="MarginContainer/CenterContainer/VBoxContainer"] +unique_name_in_owner = true +layout_mode = 2 +text = "Time Spent: " + +[node name="DronesUsed" type="Label" parent="MarginContainer/CenterContainer/VBoxContainer"] +unique_name_in_owner = true +layout_mode = 2 +text = "Drones Used:" + +[node name="TotalPoints" type="Label" parent="MarginContainer/CenterContainer/VBoxContainer"] +unique_name_in_owner = true +layout_mode = 2 +size_flags_horizontal = 4 +theme_override_font_sizes/font_size = 18 +text = "Total Points: " diff --git a/ui/scripts/level_complete_component.gd b/ui/scripts/level_complete_component.gd index 263a787..e5f987d 100644 --- a/ui/scripts/level_complete_component.gd +++ b/ui/scripts/level_complete_component.gd @@ -1,8 +1,18 @@ extends Control +@onready var time_label = get_node("%TimeSpent") +@onready var drones_label = get_node("%DronesUsed") +@onready var points_label = get_node("%TotalPoints") + func _ready(): visible = false func _process(_delta): if GameState.level_complete == true: + update_points() visible = true + +func update_points(): + time_label.text = "Time Spent: " + Str.seconds_to_hms(GameState.level_timer) + drones_label.text = "Drones Used: " + str(GameState.drones_used) + points_label.text = "Total Points: " + Str.format_number(GameState.level_points) \ No newline at end of file diff --git a/ui/scripts/ui_component.gd b/ui/scripts/ui_component.gd index 9448137..f8b82e9 100644 --- a/ui/scripts/ui_component.gd +++ b/ui/scripts/ui_component.gd @@ -8,6 +8,7 @@ var last_update : float = 0 @onready var help_text_container = get_node("%HelpTextContainer") @onready var help_text_items = help_text_container.get_children() @onready var level_text_label = get_node("%LevelText") +@onready var level_timer_label = get_node("%LevelTimer") func _ready(): @@ -24,10 +25,12 @@ func _process(delta): if GameState.level_complete: update_ui() + level_timer_label.text = Str.seconds_to_hms(GameState.level_timer) + func update_ui(): nectar_bar.value = GameState.gathered_nectar nectar_bar.max_value = GameState.required_nectar - + func hide_help_text(): for item in help_text_items: item.hide() diff --git a/utility/game_state.gd b/utility/game_state.gd index 67e44f3..69dc403 100644 --- a/utility/game_state.gd +++ b/utility/game_state.gd @@ -1,7 +1,9 @@ class_name GameStateManager extends Node +var level_timer : float = 0.0 + +var level_started : bool = false var level_complete : bool = false -var level_complete_time : float = 0.0 var gathered_nectar : int = 0 : get: @@ -13,13 +15,37 @@ var gathered_nectar : int = 0 : @export var required_nectar : int = 100 @export var level_par : int = 2 -@export var level_text : String = "" +@export var drones_used : int = 0 + +var level_points : int = 0 : + get: + return required_nectar * 100 - round(level_timer) * 10 - drones_used * 100 + +var judge_level_par : int = 0 : + get: + ## Return an amount of points based on the difference between the number of drones_used and the level_par + ## Using more drones than the par is bad and should result in less points + var diff = drones_used - level_par + if diff > 0: + return -diff * 100 + else: + return 0 + +func _process(delta): + if level_started and !level_complete: + level_timer += delta func add_nectar(): gathered_nectar += 1 +func add_drone(): + drones_used += 1 + +func remove_drone(): + drones_used -= 1 + func game_start(): - pass + level_started = true func game_win(): Log.pr("Game win") diff --git a/utility/utility_strings.gd b/utility/utility_strings.gd new file mode 100644 index 0000000..e9c4cbd --- /dev/null +++ b/utility/utility_strings.gd @@ -0,0 +1,37 @@ +class_name StringUtilities extends Node + +func seconds_to_hms(seconds: float) -> String: + var ms = fmod(seconds, 1) * 100 + var s = fmod(seconds, 60) + var m = fmod(seconds, 3600) / 60 + + var formatted : String = "%02d:%02d:%02d" % [m, s, ms] + + return formatted + +#### +## Formats the given number with commas every 3 digits. +#### +func format_number(number: int) -> String: + # Handle negative numbers by adding the "minus" sign in advance, as we discard it + # when looping over the number. + var formatted_number := "-" if sign(number) == -1 else "" + var index := 0 + var number_string := str(abs(number)) + + for digit in number_string: + formatted_number += digit + + var counter := number_string.length() - index + + # Don't add a comma at the end of the number, but add a comma every 3 digits + # (taking into account the number's length). + if counter >= 2 and counter % 3 == 1: + formatted_number += "," + + index += 1 + + return formatted_number + +func float_to_percentage(value: float) -> String: + return "%d%%" % int(value * 100) \ No newline at end of file