diff --git a/assets/HUD/lifes_icon.png b/assets/HUD/lifes_icon.png index 720c008..3bb3c17 100644 Binary files a/assets/HUD/lifes_icon.png and b/assets/HUD/lifes_icon.png differ diff --git a/project.godot b/project.godot index ce4070c..4816a2d 100644 --- a/project.godot +++ b/project.godot @@ -60,6 +60,7 @@ config/icon="res://icon.png" [autoload] AudioManager="*res://src/Singletons/AudioManager.tscn" +GameState="*res://src/Singletons/GameState.gd" [display] diff --git a/src/Actors/Player.gd b/src/Actors/Player.gd index 7cb2628..b66b819 100644 --- a/src/Actors/Player.gd +++ b/src/Actors/Player.gd @@ -188,6 +188,7 @@ func _on_die_animation_done(): func die(): _alive = false + GameState.player_died() $AnimationPlayer.play("die") func setAbility(ability:String, enabled:bool=false): diff --git a/src/HUD/HUD.gd b/src/HUD/HUD.gd index 152237c..74768c5 100644 --- a/src/HUD/HUD.gd +++ b/src/HUD/HUD.gd @@ -7,11 +7,28 @@ onready var Lable = get_node("CoinsContainer/Label") var _paused = false; var _pause_ref; -func on_coin_collected(amount:int): - coins_amount += amount - Lable.text = str(coins_amount) +var _data_ref = null; +func _ready() -> void: + _data_ref = GameState.get_run_data() func _physics_process(delta: float) -> void: + _handle_pause() + var fresh_data = GameState.get_run_data() + for key in fresh_data: + if not fresh_data[key] == _data_ref[key]: + print("[%s]: %s -> %s" % [str(key), str(_data_ref[key]), str(fresh_data[key])]) + match(str(key)): + "coins": + $UI/CoinLabel.text = str(fresh_data.coins) + $UI/CoinLabel/AnimationPlayer.seek(0) + $UI/CoinLabel/AnimationPlayer.play("updated") + "deaths": + $UI/DeathsLabel.text = str(fresh_data.deaths) + + pass + _data_ref = fresh_data + +func _handle_pause(): if Input.is_action_just_pressed("pause"): if _paused: _pause_ref.dismiss() @@ -21,7 +38,7 @@ func _physics_process(delta: float) -> void: add_child(_pause_ref) get_tree().paused = true _paused = true - + func _on_pause_menu_dismissed(): _paused = false get_tree().paused = false diff --git a/src/HUD/HUD.tscn b/src/HUD/HUD.tscn index f465e8b..cef3a4f 100644 --- a/src/HUD/HUD.tscn +++ b/src/HUD/HUD.tscn @@ -1,31 +1,79 @@ -[gd_scene load_steps=5 format=2] +[gd_scene load_steps=7 format=2] [ext_resource path="res://src/HUD/HUD.gd" type="Script" id=1] [ext_resource path="res://src/Menu/PauseMenu.tscn" type="PackedScene" id=2] [ext_resource path="res://assets/Theme/Theme.tres" type="Theme" id=3] [ext_resource path="res://assets/HUD/coins_hud.png" type="Texture" id=4] +[ext_resource path="res://assets/HUD/lifes_icon.png" type="Texture" id=5] + +[sub_resource type="Animation" id=1] +resource_name = "updated" +length = 0.2 +tracks/0/type = "value" +tracks/0/path = NodePath(".:rect_scale") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/keys = { +"times": PoolRealArray( 0, 0.2 ), +"transitions": PoolRealArray( 0.466517, 1 ), +"update": 0, +"values": [ Vector2( 2, 2 ), Vector2( 1, 1 ) ] +} [node name="HUD" type="CanvasLayer"] script = ExtResource( 1 ) PauseMenu = ExtResource( 2 ) -[node name="CoinsContainer" type="HBoxContainer" parent="."] -margin_left = 18.0 -margin_top = 13.0 -margin_right = 87.0 -margin_bottom = 22.0 +[node name="UI" type="NinePatchRect" parent="."] +anchor_right = 1.0 +anchor_bottom = 1.0 __meta__ = { "_edit_use_anchors_": false } -[node name="TextureRect" type="TextureRect" parent="CoinsContainer"] -margin_right = 9.0 -margin_bottom = 9.0 +[node name="Coin" type="TextureRect" parent="UI"] +margin_left = 18.0 +margin_top = 13.0 +margin_right = 27.0 +margin_bottom = 22.0 texture = ExtResource( 4 ) +__meta__ = { +"_edit_use_anchors_": false +} -[node name="Label" type="Label" parent="CoinsContainer"] -margin_left = 13.0 -margin_right = 19.0 -margin_bottom = 9.0 +[node name="CoinLabel" type="Label" parent="UI"] +margin_left = 38.0 +margin_top = 13.0 +margin_right = 44.0 +margin_bottom = 22.0 theme = ExtResource( 3 ) text = "0" +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="AnimationPlayer" type="AnimationPlayer" parent="UI/CoinLabel"] +anims/updated = SubResource( 1 ) + +[node name="Deaths" type="TextureRect" parent="UI"] +margin_left = 11.0 +margin_top = 22.0 +margin_right = 33.0 +margin_bottom = 44.0 +texture = ExtResource( 5 ) +expand = true + +[node name="DeathsLabel" type="Label" parent="UI"] +margin_left = 38.0 +margin_top = 30.0 +margin_right = 78.0 +margin_bottom = 44.0 +theme = ExtResource( 3 ) +text = "0" +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="AnimationPlayer" type="AnimationPlayer" parent="UI/DeathsLabel"] diff --git a/src/Intro/Intro.gd b/src/Intro/Intro.gd index 6ba654e..33c7449 100644 --- a/src/Intro/Intro.gd +++ b/src/Intro/Intro.gd @@ -10,7 +10,7 @@ func _ready() -> void: func load_next_scene(): # var next_scene = load("res://src/Levels/LevelTemplate/LevelTemplate.tscn") - get_tree().change_scene_to(next_scene) + GameState.go_to_main_menu() queue_free() func stop_splash_voice(): diff --git a/src/Items/Coin.gd b/src/Items/Coin.gd index 5dd7a26..9eb8c6d 100644 --- a/src/Items/Coin.gd +++ b/src/Items/Coin.gd @@ -10,6 +10,7 @@ func _on_body_entered(body: Node) -> void: if body.name == "Player": $Label.text = str(value) AudioManager.play_sfx(AudioManager.Sfx.COIN_COLLECTION) - emit_signal("collected", value) +# emit_signal("collected", value) + GameState.coin_collected() $AnimationPlayer.play("collected") pass # Replace with function body. diff --git a/src/Items/Coin.tscn b/src/Items/Coin.tscn index b5a5aef..71f27a6 100644 --- a/src/Items/Coin.tscn +++ b/src/Items/Coin.tscn @@ -190,11 +190,11 @@ collision_layer = 16 script = ExtResource( 2 ) [node name="Sprite" type="Sprite" parent="."] -position = Vector2( 0, -4 ) +position = Vector2( 0, -8 ) texture = ExtResource( 1 ) vframes = 2 hframes = 6 -frame = 6 +frame = 8 [node name="CollisionShape2D" type="CollisionShape2D" parent="."] visible = false diff --git a/src/Menu/MainMenu.gd b/src/Menu/MainMenu.gd index 52bd097..6e8fbd6 100644 --- a/src/Menu/MainMenu.gd +++ b/src/Menu/MainMenu.gd @@ -14,8 +14,7 @@ func _on_ControlsBtn_pressed() -> void: func _on_NewGameBtn_pressed() -> void: - var next_scene = load("res://src/Levels/LevelTemplate/LevelTemplate.tscn") - get_tree().change_scene_to(next_scene) + GameState.start_new_game() queue_free() func _input(event: InputEvent) -> void: diff --git a/src/Menu/PauseMenu.gd b/src/Menu/PauseMenu.gd index a4eb634..22503cc 100644 --- a/src/Menu/PauseMenu.gd +++ b/src/Menu/PauseMenu.gd @@ -28,10 +28,9 @@ func _on_ResumeBtn_pressed() -> void: func _on_ExitToMainMenuBtn_pressed() -> void: $AnimationPlayer.play_backwards("fade") yield($AnimationPlayer, "animation_finished"); - var next_scene = load("res://src/Menu/MainMenu.tscn") emit_signal("dismissed") AudioManager.play_music(AudioManager.Music.Intro, .2) - get_tree().change_scene_to(next_scene) + GameState.go_to_main_menu() queue_free() @@ -39,7 +38,7 @@ func _on_NewGameBtn_pressed() -> void: $AnimationPlayer.play_backwards("fade") yield($AnimationPlayer, "animation_finished"); emit_signal("dismissed") - get_tree().reload_current_scene() + GameState.start_new_game() pass # Replace with function body. diff --git a/src/Singletons/GameState.gd b/src/Singletons/GameState.gd new file mode 100644 index 0000000..a851290 --- /dev/null +++ b/src/Singletons/GameState.gd @@ -0,0 +1,96 @@ +extends Node + +enum States{ + INTRO, + MAIN_MENU, + GAME_OVER, + CONTROLS, + GAME, + PUSE, + STATS, + CUT_SCENE, +} +var _SAVE_FILE_PATH = "user://data" +# Change key in release +var _ENCRYPTION_KEY = "fas3uyf076HJsiUDs24dfI9" + +var _SCENES := { + States.MAIN_MENU: "res://src/Menu/MainMenu.tscn", + States.GAME: "res://src/Levels/LevelTemplate/LevelTemplate.tscn", +} + +var _data := { + "statistics": { + "deaths": 0, + "clears": 0, + "runs": 0, + "total_time_played": 0, + "orbs": 0, + "coins": 0, + }, + "heigh_score": { + "deaths": 0, + "score": 0, + "cleard": false, + "coins": 0, + "orbs": 0, + "time": 0, + } + } + +var _run_data:= { + "deaths": 0, + "coins": 0, + "orbs": 0, + "time": 0, + "score": 0 +} + +var _state = States.INTRO + +func _ready() -> void: + load_data() + print(get_statistics()) + +func load_data(): + var data_file = File.new() + var e = data_file.open_encrypted_with_pass(_SAVE_FILE_PATH, File.READ, _ENCRYPTION_KEY) + if e != 0: + data_file.close() + save_data() + else: + _data = data_file.get_var() + data_file.close() + pass + +func save_data(): + var data_file = File.new() + print(data_file.open_encrypted_with_pass(_SAVE_FILE_PATH, File.WRITE, _ENCRYPTION_KEY)) + print(data_file.store_var(_data)) + data_file.close() + pass + +func start_new_game(): + for key in _run_data.keys(): + _run_data[key] = 0 + _state = States.GAME + _data.statistics.runs += 1 + save_data() + get_tree().change_scene_to(load(_SCENES[_state])) +func get_heigh_score(): + return _data.heigh_score.duplicate() +func get_statistics(): + return _data.statistics.duplicate() +func get_run_data(): + return _run_data.duplicate() + +func go_to_main_menu(): + _state = States.MAIN_MENU + save_data() + get_tree().change_scene_to(load(_SCENES[_state])) +func player_died(): + _run_data.deaths += 1 + _data.statistics.deaths += 1 +func coin_collected(): + _run_data.coins += 10 + _data.statistics.coins += 10