diff --git a/assets/contraption/ShieldVendingMachine.aseprite b/assets/contraption/ShieldVendingMachine.aseprite index ab33c80..68d9c31 100644 Binary files a/assets/contraption/ShieldVendingMachine.aseprite and b/assets/contraption/ShieldVendingMachine.aseprite differ diff --git a/assets/contraption/ShieldVendingMachine.png b/assets/contraption/ShieldVendingMachine.png index ff0b698..8c1f5a1 100644 Binary files a/assets/contraption/ShieldVendingMachine.png and b/assets/contraption/ShieldVendingMachine.png differ diff --git a/project.godot b/project.godot index 185241d..6b12a23 100644 --- a/project.godot +++ b/project.godot @@ -320,6 +320,7 @@ common/enable_object_picking=false [rendering] +2d/options/use_nvidia_rect_flicker_workaround=true quality/intended_usage/framebuffer_allocation=0 quality/intended_usage/framebuffer_allocation.mobile=0 threads/thread_model=2 diff --git a/src/Actors/Enemies/DartingEnemy.gd b/src/Actors/Enemies/Vacuum.gd similarity index 100% rename from src/Actors/Enemies/DartingEnemy.gd rename to src/Actors/Enemies/Vacuum.gd diff --git a/src/Actors/Enemies/DartingEnemy.tscn b/src/Actors/Enemies/Vacuum.tscn similarity index 95% rename from src/Actors/Enemies/DartingEnemy.tscn rename to src/Actors/Enemies/Vacuum.tscn index cf85da4..8c8c2d6 100644 --- a/src/Actors/Enemies/DartingEnemy.tscn +++ b/src/Actors/Enemies/Vacuum.tscn @@ -1,7 +1,7 @@ [gd_scene load_steps=6 format=2] [ext_resource path="res://assets/enemy/VacuumRobot.png" type="Texture" id=1] -[ext_resource path="res://src/Actors/Enemies/DartingEnemy.gd" type="Script" id=2] +[ext_resource path="res://src/Actors/Enemies/Vacuum.gd" type="Script" id=2] [sub_resource type="RectangleShape2D" id=1] extents = Vector2( 14, 7 ) @@ -16,6 +16,8 @@ extents = Vector2( 15, 6.5 ) collision_layer = 2 collision_mask = 9 script = ExtResource( 2 ) +speed = 180 +acceleration = 100 [node name="Sprite" type="Sprite" parent="."] position = Vector2( 0, -3 ) diff --git a/src/Autoload/GlobalState.gd b/src/Autoload/GlobalState.gd index ffa239f..9718909 100644 --- a/src/Autoload/GlobalState.gd +++ b/src/Autoload/GlobalState.gd @@ -7,74 +7,125 @@ extends Node export(Resource) var gsr var sound_library = {} + func _ready(): - load_sounds() + load_sounds() + func load_sounds() -> void: - var paths = ["res://assets/sounds","res://assets/music"] - for path in paths: - var dir = Directory.new() - dir.open(path) - dir.list_dir_begin() - while true: - var file_name = dir.get_next() - if file_name == "": - break - var sound_file - if file_name.ends_with(".import"): - sound_file = load(path + "/" + file_name.split(".import")[0]) - sound_library[sound_file.resource_path] = sound_file - dir.list_dir_end() + var paths = ["res://assets/sounds", "res://assets/music"] + for path in paths: + var dir = Directory.new() + dir.open(path) + dir.list_dir_begin() + while true: + var file_name = dir.get_next() + if file_name == "": + break + var sound_file + if file_name.ends_with(".import"): + sound_file = load(path + "/" + file_name.split(".import")[0]) + sound_library[sound_file.resource_path] = sound_file + dir.list_dir_end() + func set_progress(value) -> void: - gsr.progress_dict = value - SaveManager.save_default() + gsr.progress_dict = value + SaveManager.save_default() + func get_progress() -> Dictionary: - return gsr.progress_dict + return gsr.progress_dict + func save() -> void: - SaveManager.save_default() + SaveManager.save_default() + + +func get_level_completed(levelName: String) -> bool: + if gsr.progress_dict.has(levelName) && gsr.progress_dict[levelName].has("levelcompleted"): + return gsr.progress_dict[levelName]["levelcompleted"] + else: + return false + + +func set_level_completed(levelName: String, state: bool) -> void: + if !gsr.progress_dict.has(levelName): + gsr.progress_dict[levelName] = {} + gsr.progress_dict[levelName]["levelcompleted"] = state + SaveManager.save_default() + + +func set_leveltime(levelName: String, time: float) -> void: + if !gsr.progress_dict.has(levelName): + gsr.progress_dict[levelName] = {} + gsr.progress_dict[levelName]["leveltime"] = time + SaveManager.save_default() + +func get_level_time(levelName: String) -> float: + if gsr.progress_dict.has(levelName) && gsr.progress_dict[levelName].has("leveltime"): + return gsr.progress_dict[levelName]["leveltime"] + else: + return INF + +func set_uncompleted_level_time(levelName: String, time: float) -> void: + if !gsr.progress_dict.has(levelName): + gsr.progress_dict[levelName] = {} + gsr.progress_dict[levelName]["uncompletedleveltime"] = time + SaveManager.save_default() + +func get_uncompleted_level_time(levelName: String) -> float: + if gsr.progress_dict.has(levelName) && gsr.progress_dict[levelName].has("uncompletedleveltime"): + return gsr.progress_dict[levelName]["uncompletedleveltime"] + else: + return INF + func set_savepoint(levelName: String, position: Vector2) -> void: - #TODO You can free a frog, go to the checkpoint and it will be - # saved as freed forever - if(!gsr.progress_dict.has(levelName)): - gsr.progress_dict[levelName] = {} - gsr.progress_dict[levelName]["savepoint"] = position - SaveManager.save_default() - + #TODO You can free a frog, go to the checkpoint and it will be + # saved as freed forever + if !gsr.progress_dict.has(levelName): + gsr.progress_dict[levelName] = {} + gsr.progress_dict[levelName]["savepoint"] = position + SaveManager.save_default() + + func remove_savepoint(levelName: String) -> void: - if(!gsr.progress_dict.has(levelName)): - return - gsr.progress_dict[levelName].erase(levelName) - SaveManager.save_default() - + if !gsr.progress_dict.has(levelName): + return + gsr.progress_dict[levelName].erase(levelName) + SaveManager.save_default() + + + func get_property_value(levelName: String, propertyName: String) -> int: - if gsr.progress_dict.has(levelName) && gsr.progress_dict[levelName].has(propertyName): - return gsr.progress_dict[levelName][propertyName] - else: - return 0 + if gsr.progress_dict.has(levelName) && gsr.progress_dict[levelName].has(propertyName): + return gsr.progress_dict[levelName][propertyName] + else: + return 0 + func get_savepoint(levelName: String) -> Vector2: - if gsr.progress_dict.has(levelName) && gsr.progress_dict[levelName].has("savepoint"): - return gsr.progress_dict[levelName]["savepoint"] - else: - return Vector2() + if gsr.progress_dict.has(levelName) && gsr.progress_dict[levelName].has("savepoint"): + return gsr.progress_dict[levelName]["savepoint"] + else: + return Vector2() + # TODO This is permanent immediatly func set_wallet(value) -> void: - gsr.wallet = value - SaveManager.save_default() + gsr.wallet = value + SaveManager.save_default() + func reinstate() -> void: - if gsr.input_map.size() <= 1: - InputMap.load_from_globals() - return - for action in gsr.input_map: - InputMap.action_erase_events(action) - # if(gsr.input_map[action].size() > 0 && gsr.input_map[action].size() < 2): - # InputMap.load_from_globals() - for input_event in gsr.input_map[action]: - InputMap.action_add_event(action, input_event) + if gsr.input_map.size() <= 1: + InputMap.load_from_globals() + return + for action in gsr.input_map: + InputMap.action_erase_events(action) + # if(gsr.input_map[action].size() > 0 && gsr.input_map[action].size() < 2): + # InputMap.load_from_globals() + for input_event in gsr.input_map[action]: + InputMap.action_add_event(action, input_event) diff --git a/src/BenefitialObjects/Coin.gd b/src/BenefitialObjects/Coin.gd index e175393..81cc337 100644 --- a/src/BenefitialObjects/Coin.gd +++ b/src/BenefitialObjects/Coin.gd @@ -8,7 +8,7 @@ export var currencyValue: = 1 func _on_body_entered(_body: Node) -> void: if $AudioStreamPlayer.playing: return - level_state.currency += currencyValue + level_state.set_currency(level_state.get_currency() + currencyValue) $CollisionShape2D.disabled = true set_deferred("monitoring", false) $AudioStreamPlayer.play() diff --git a/src/BenefitialObjects/SavePoint.gd b/src/BenefitialObjects/SavePoint.gd index b83cecc..3632b84 100644 --- a/src/BenefitialObjects/SavePoint.gd +++ b/src/BenefitialObjects/SavePoint.gd @@ -15,4 +15,4 @@ func _on_SaveArea_area_entered(area: Area2D) -> void: if(!GlobalState.get_savepoint(level_state.levelName) == global_position + Vector2(0,18)): $AnimationPlayer.play("rolloutflag") $AudioStreamPlayer.play() - GlobalState.set_savepoint(level_state.levelName, global_position + Vector2(0,18)) + level_state.set_savepoint(global_position + Vector2(0,18)) diff --git a/src/Contraptions/Portal/Portal.gd b/src/Contraptions/Portal/Portal.gd index d84c65a..1421752 100644 --- a/src/Contraptions/Portal/Portal.gd +++ b/src/Contraptions/Portal/Portal.gd @@ -20,7 +20,6 @@ func _get_configuration_warning() -> String: return "The next scene property can't be empty" if not next_scene else "" func level_completion() -> void: - GlobalState.remove_savepoint(levelName) signal_manager.emit_signal("level_completed") func activate_portal(_time: float) -> void: diff --git a/src/Contraptions/Triggers/ElevatorButton.gd b/src/Contraptions/Triggers/ElevatorButton.gd index 09d14c7..d8a5134 100644 --- a/src/Contraptions/Triggers/ElevatorButton.gd +++ b/src/Contraptions/Triggers/ElevatorButton.gd @@ -2,8 +2,6 @@ extends Node2D onready var buttonPlayer = $"%ButtonPlayer" onready var activatorArea = $"%ActivatorArea" -onready var indicatorPlayer = $"%IndicatorPlayer" -onready var elevator = get_node("./Portal") onready var signal_manager := get_tree().root.get_child(4).get_node("%SignalManager") onready var unactivatable_timer := $Timer onready var get_back_timer := $GetBackTimer diff --git a/src/Contraptions/Triggers/FrogFreeButton.gd b/src/Contraptions/Triggers/FrogFreeButton.gd index 8db2fc4..f184433 100644 --- a/src/Contraptions/Triggers/FrogFreeButton.gd +++ b/src/Contraptions/Triggers/FrogFreeButton.gd @@ -8,35 +8,21 @@ onready var signal_manager := get_tree().root.get_child(4).get_node("%SignalMana onready var unactivatable_timer := $Timer export(int) var frog_number := 0 -var activatable = false +var activatable = true func _ready() -> void: $Digit.frame = frog_number -func _input(event: InputEvent) -> void: - if activatable && Input.is_action_just_released("interact"): - selfActivate() - self.emit_signal("button_pushed") - func selfActivate(): indicatorPlayer.play("onning") #TODO dis importante + self.emit_signal("button_pushed") activatorArea.set_deferred("monitoring", false) func _on_ActivatorArea_area_entered(area:Area2D) -> void: - $Label.visible = true $Highlight.visible = true - activatable = true - -func _on_ActivatorArea_area_exited(area:Area2D) -> void: - unactivatable_timer.start() - -func _on_Timer_timeout(): - for body in activatorArea.get_overlapping_bodies(): - if body.is_in_group("player"): - return - $Label.visible = false - $Highlight.visible = false - activatable = false + if activatable: + selfActivate() + activatable = false diff --git a/src/Contraptions/Triggers/GateButton.gd b/src/Contraptions/Triggers/GateButton.gd index e03abfc..c71f10d 100644 --- a/src/Contraptions/Triggers/GateButton.gd +++ b/src/Contraptions/Triggers/GateButton.gd @@ -5,7 +5,7 @@ onready var indicatorPlayer = $"%IndicatorPlayer" onready var signal_manager := get_tree().root.get_child(4).get_node("%SignalManager") onready var unactivatable_timer := $Timer -var activatable = false +var activatable = true func _input(event: InputEvent) -> void: if activatable && Input.is_action_just_released("interact"): @@ -18,23 +18,10 @@ func selfActivate(): activatorArea.set_deferred("monitoring", false) #TODO Close gate again? signal_manager.emit_signal("unlocked", "gateblock") - activatable = false func _on_ActivatorArea_area_entered(area:Area2D) -> void: - $Label.visible = true $Highlight.visible = true - activatable = true - if(area.get_parent().name == "WhatAreFrog"): + if activatable: selfActivate() - -func _on_ActivatorArea_area_exited(area:Area2D) -> void: - unactivatable_timer.start() - -func _on_Timer_timeout(): - for body in activatorArea.get_overlapping_bodies(): - if body.is_in_group("player"): - return - $Label.visible = false - $Highlight.visible = false - activatable = false + activatable = false diff --git a/src/Contraptions/VendingMachine.tscn b/src/Contraptions/VendingMachine.tscn index 642ecfb..dd6fb72 100644 --- a/src/Contraptions/VendingMachine.tscn +++ b/src/Contraptions/VendingMachine.tscn @@ -11,8 +11,8 @@ colors = PoolColorArray( 1, 1, 1, 0.752941, 0, 0, 0, 0 ) [sub_resource type="GradientTexture2D" id=22] gradient = SubResource( 21 ) -width = 60 -height = 60 +width = 75 +height = 75 fill = 1 fill_from = Vector2( 0.5, 0.5 ) fill_to = Vector2( 0.155994, 0.791965 ) @@ -21,32 +21,32 @@ fill_to = Vector2( 0.155994, 0.791965 ) radius = 18.0 [node name="VendingMachine" type="Node2D"] +position = Vector2( 0, -1 ) z_index = -1 script = ExtResource( 2 ) [node name="Highlight" type="TextureRect" parent="."] -visible = false anchor_left = 0.5 anchor_top = 0.5 anchor_right = 0.5 anchor_bottom = 0.5 -margin_left = -30.0 -margin_top = -31.0 -margin_right = 30.0 -margin_bottom = 29.0 +margin_left = -37.0 +margin_top = -41.0 +margin_right = 38.0 +margin_bottom = 34.0 texture = SubResource( 22 ) [node name="Label" type="Label" parent="."] -visible = false margin_left = -18.0 -margin_top = -24.0 +margin_top = -30.0 margin_right = 48.0 -margin_bottom = -10.0 +margin_bottom = -16.0 rect_scale = Vector2( 0.590909, 0.627907 ) custom_fonts/font = ExtResource( 3 ) text = "[purchase]" [node name="Sprite" type="Sprite" parent="."] +position = Vector2( 0, -4 ) texture = ExtResource( 1 ) [node name="ActivatorArea" type="Area2D" parent="."] diff --git a/src/Levels/Legacy/Actual Level 1.tscn b/src/Levels/Legacy/Actual Level 1.tscn index c4d317d..09bd1ba 100644 --- a/src/Levels/Legacy/Actual Level 1.tscn +++ b/src/Levels/Legacy/Actual Level 1.tscn @@ -1,6 +1,6 @@ [gd_scene load_steps=28 format=2] -[ext_resource path="res://src/Actors/Enemies/DartingEnemy.tscn" type="PackedScene" id=1] +[ext_resource path="res://src/Actors/Enemies/Vacuum.tscn" type="PackedScene" id=1] [ext_resource path="res://src/Utilities/SignalManager.tscn" type="PackedScene" id=2] [ext_resource path="res://src/BenefitialObjects/Coin.tscn" type="PackedScene" id=3] [ext_resource path="res://src/Actors/Enemies/Flyer.tscn" type="PackedScene" id=4] diff --git a/src/Levels/Legacy/xEnemy Test Level.tscn b/src/Levels/Legacy/xEnemy Test Level.tscn index 2d2f5be..5a11496 100644 --- a/src/Levels/Legacy/xEnemy Test Level.tscn +++ b/src/Levels/Legacy/xEnemy Test Level.tscn @@ -8,7 +8,7 @@ [ext_resource path="res://src/Actors/Enemies/SimpleEnemy.tscn" type="PackedScene" id=6] [ext_resource path="res://src/ObstacleObjects/Spikes.tscn" type="PackedScene" id=7] [ext_resource path="res://src/Actors/Enemies/Caterpillar.tscn" type="PackedScene" id=8] -[ext_resource path="res://src/Actors/Enemies/DartingEnemy.tscn" type="PackedScene" id=9] +[ext_resource path="res://src/Actors/Enemies/Vacuum.tscn" type="PackedScene" id=9] [ext_resource path="res://src/Actors/Blobby/Blobby.tscn" type="PackedScene" id=10] [ext_resource path="res://src/UserInterface/UserInterface.tscn" type="PackedScene" id=11] diff --git a/src/Levels/Level 0.1.tscn b/src/Levels/Level 0.1.tscn index dca3788..ae69034 100644 --- a/src/Levels/Level 0.1.tscn +++ b/src/Levels/Level 0.1.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=87 format=2] +[gd_scene load_steps=86 format=2] [ext_resource path="res://src/Levels/Templates/LevelTemplate.gd" type="Script" id=1] [ext_resource path="res://src/Environment/GreenHouseTiles.tres" type="TileSet" id=2] @@ -1323,9 +1323,6 @@ unique_name_in_owner = true position = Vector2( -70, 1 ) scale = Vector2( 0.878906, 0.936025 ) -[node name="BlobbySprite" parent="Blobby" index="5"] -frame = 7 - [node name="BlobbymationTree" parent="Blobby/BlobbySprite" index="0"] parameters/playback = SubResource( 33 ) parameters/jumpStretching/blend_position = 1 diff --git a/src/Levels/Level 0.2.tscn b/src/Levels/Level 0.2.tscn index 5134b25..8e2fc6b 100644 --- a/src/Levels/Level 0.2.tscn +++ b/src/Levels/Level 0.2.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=63 format=2] +[gd_scene load_steps=67 format=2] [ext_resource path="res://assets/environment/decor/platform-plants.png" type="Texture" id=1] [ext_resource path="res://src/Utilities/SceneAudio.tscn" type="PackedScene" id=2] @@ -199,6 +199,25 @@ shader_param/strength = 0.1 shader_param/noise_tex_normal = ExtResource( 20 ) shader_param/noise_tex = ExtResource( 20 ) +[sub_resource type="Gradient" id=9] +interpolation_mode = 2 +colors = PoolColorArray( 0, 0, 0, 0.784314, 0, 0, 0, 0 ) + +[sub_resource type="GradientTexture2D" id=8] +gradient = SubResource( 9 ) +width = 300 +height = 75 +fill = 1 +fill_from = Vector2( 0.5, 0.5 ) +fill_to = Vector2( 0.155994, 0.791965 ) + +[sub_resource type="DynamicFontData" id=12] +font_path = "res://assets/ui/fonts/Kenney Thick.ttf" + +[sub_resource type="DynamicFont" id=53] +size = 6 +font_data = SubResource( 12 ) + [sub_resource type="Animation" id=50] length = 0.001 tracks/0/type = "value" @@ -1152,7 +1171,7 @@ death_sound_1 = null death_sound_2 = null [node name="BlobbySprite" parent="Blobby" index="5"] -frame = 5 +frame = 7 [node name="BlobbymationTree" parent="Blobby/BlobbySprite" index="0"] parameters/playback = SubResource( 6 ) @@ -1252,9 +1271,10 @@ material = SubResource( 48 ) position = Vector2( -44, -83 ) [node name="TutorialThingy" parent="." instance=ExtResource( 9 )] +visible = true position = Vector2( 1441, -4 ) action = "interact" -tutorial_text = "Press to interact:" +tutorial_text = "Press to interact" [node name="Button" parent="TutorialThingy" index="0"] material = SubResource( 14 ) @@ -1265,6 +1285,25 @@ position = Vector2( -2, -87 ) [node name="CollisionShape2D" parent="TutorialThingy/StartTutorialArea" index="0"] position = Vector2( 0, 9 ) +[node name="TextureRect3" type="TextureRect" parent="TutorialThingy"] +anchor_right = 1.0 +anchor_bottom = 1.0 +margin_left = -149.0 +margin_top = 4.0 +margin_right = 251.0 +margin_bottom = 204.0 +texture = SubResource( 8 ) + +[node name="Label" type="Label" parent="TutorialThingy"] +margin_left = -51.0 +margin_top = 28.0 +margin_right = 51.0 +margin_bottom = 75.0 +custom_fonts/font = SubResource( 53 ) +text = "and start decontamination procedure" +align = 1 +autowrap = true + [node name="SavePoint" parent="." instance=ExtResource( 15 )] position = Vector2( 1168, -88 ) diff --git a/src/Levels/Level 0.4.tscn b/src/Levels/Level 0.4.tscn index 2e69867..701a900 100644 --- a/src/Levels/Level 0.4.tscn +++ b/src/Levels/Level 0.4.tscn @@ -5,7 +5,7 @@ [ext_resource path="res://src/Utilities/SignalManager.tscn" type="PackedScene" id=3] [ext_resource path="res://src/BenefitialObjects/Coin.tscn" type="PackedScene" id=4] [ext_resource path="res://src/Actors/BlobbyCam.tscn" type="PackedScene" id=5] -[ext_resource path="res://src/Actors/Enemies/DartingEnemy.tscn" type="PackedScene" id=6] +[ext_resource path="res://src/Actors/Enemies/Vacuum.tscn" type="PackedScene" id=6] [ext_resource path="res://src/Actors/Blobby/Blobby.tscn" type="PackedScene" id=7] [ext_resource path="res://src/Utilities/LevelState.tscn" type="PackedScene" id=8] [ext_resource path="res://src/Platforms/FlyingPlatform.tscn" type="PackedScene" id=9] diff --git a/src/Levels/Level 0.6.tscn b/src/Levels/Level 0.6.tscn index b13e7de..294347d 100644 --- a/src/Levels/Level 0.6.tscn +++ b/src/Levels/Level 0.6.tscn @@ -132,6 +132,9 @@ jump_buffer_filled = null death_sound_1 = null death_sound_2 = null +[node name="BlobbySprite" parent="Blobby" index="5"] +frame = 7 + [node name="BlobbymationTree" parent="Blobby/BlobbySprite" index="0"] parameters/playback = SubResource( 53 ) diff --git a/src/Levels/Level 1.tscn b/src/Levels/Level 1.tscn index 04c5dc7..f5a0163 100644 --- a/src/Levels/Level 1.tscn +++ b/src/Levels/Level 1.tscn @@ -19,7 +19,7 @@ [ext_resource path="res://src/Actors/Friendlies/BoundFrog.tscn" type="PackedScene" id=17] [ext_resource path="res://src/Contraptions/Triggers/FrogFreeButton.tscn" type="PackedScene" id=18] [ext_resource path="res://src/Contraptions/Triggers/GateButton.tscn" type="PackedScene" id=19] -[ext_resource path="res://src/Actors/Enemies/DartingEnemy.tscn" type="PackedScene" id=20] +[ext_resource path="res://src/Actors/Enemies/Vacuum.tscn" type="PackedScene" id=20] [ext_resource path="res://src/BenefitialObjects/Coin.tscn" type="PackedScene" id=21] [sub_resource type="Shader" id=7] diff --git a/src/Levels/Level 3.tscn b/src/Levels/Level 3.tscn index 5d4a7d2..2e653b7 100644 --- a/src/Levels/Level 3.tscn +++ b/src/Levels/Level 3.tscn @@ -1009,9 +1009,6 @@ unique_name_in_owner = true position = Vector2( -88, 96 ) scale = Vector2( 0.878906, 0.936025 ) -[node name="BlobbySprite" parent="Blobby" index="5"] -frame = 7 - [node name="BlobbymationTree" parent="Blobby/BlobbySprite" index="0"] parameters/playback = SubResource( 6 ) @@ -1229,6 +1226,7 @@ elevator_time = 15 [node name="Portal" parent="." instance=ExtResource( 7 )] position = Vector2( 319, -224 ) +next_scene = "res://src/Levels/Level 4.tscn" [node name="BoundFrog" parent="." instance=ExtResource( 56 )] position = Vector2( 203, -45 ) diff --git a/src/Levels/Level 4.tscn b/src/Levels/Level 4.tscn index ccdf068..609d08a 100644 --- a/src/Levels/Level 4.tscn +++ b/src/Levels/Level 4.tscn @@ -13,7 +13,7 @@ [ext_resource path="res://src/Actors/BlobbyCam.tscn" type="PackedScene" id=11] [ext_resource path="res://assets/environment/decor/platform-plants.png" type="Texture" id=12] [ext_resource path="res://src/Platforms/FlyingLaserCutter.tscn" type="PackedScene" id=13] -[ext_resource path="res://src/Actors/Enemies/DartingEnemy.tscn" type="PackedScene" id=14] +[ext_resource path="res://src/Actors/Enemies/Vacuum.tscn" type="PackedScene" id=14] [ext_resource path="res://src/ObstacleObjects/Spikes.tscn" type="PackedScene" id=15] [ext_resource path="res://src/Platforms/Spring/Spring.tscn" type="PackedScene" id=56] [ext_resource path="res://src/Contraptions/Portal/Portal.tscn" type="PackedScene" id=57] @@ -162,7 +162,7 @@ format = 1 [node name="Portal" parent="." instance=ExtResource( 57 )] position = Vector2( 421, -1103 ) -next_scene = "res://src/Levels/Actual Level 1.tscn" +next_scene = "res://src/Levels/Level 5.tscn" is_active = true [node name="SavePoint" parent="." instance=ExtResource( 7 )] diff --git a/src/Levels/Level 5.tscn b/src/Levels/Level 5.tscn index 389f83b..f4312a2 100644 --- a/src/Levels/Level 5.tscn +++ b/src/Levels/Level 5.tscn @@ -179,26 +179,19 @@ size_flags_vertical = 3 [node name="UserInterface" parent="." instance=ExtResource( 6 )] unique_name_in_owner = true -[node name="BlobbyCam" parent="." instance=ExtResource( 9 )] -unique_name_in_owner = true -drag_margin_top = 0.12 -drag_margin_bottom = 0.12 - -[node name="TextureRect" parent="BlobbyCam/ParallaxBackground/ParallaxLayer4" index="5"] -margin_left = -585.0 -margin_right = 565.0 - [node name="Blobby" parent="." instance=ExtResource( 2 )] unique_name_in_owner = true position = Vector2( -45, -5.96046e-08 ) scale = Vector2( 0.878906, 0.936025 ) [node name="BlobbySprite" parent="Blobby" index="5"] -frame = 5 +frame = 8 [node name="BlobbymationTree" parent="Blobby/BlobbySprite" index="0"] parameters/playback = SubResource( 6 ) +[node name="BlobbyCam" parent="." instance=ExtResource( 9 )] + [node name="SavePoint" parent="." instance=ExtResource( 18 )] position = Vector2( 520, -8 ) @@ -394,7 +387,6 @@ position = Vector2( 286, -16 ) [editable path="LevelState"] [editable path="UserInterface"] [editable path="UserInterface/HUD"] -[editable path="BlobbyCam"] [editable path="Blobby"] [editable path="FlyingPlatformSmol"] [editable path="FlyingPlatformSmol2"] diff --git a/src/Levels/Templates/LevelTemplate.gd b/src/Levels/Templates/LevelTemplate.gd index db6aa78..3e2e6ef 100644 --- a/src/Levels/Templates/LevelTemplate.gd +++ b/src/Levels/Templates/LevelTemplate.gd @@ -9,21 +9,23 @@ export(float) var level_ambiance_attenuation = -23 onready var signal_manager := $"%SignalManager" onready var level_state := $"%LevelState" - func _ready() -> void: - $TransitionLayer.visible = true - var transition_tween = Tween.new() - add_child(transition_tween) - var property = "shader_param/position" - var node = $TransitionLayer/SceneTransition - transition_tween.interpolate_property(node.material, property,-1.5, 1.0, 0.94, Tween.TRANS_LINEAR, Tween.EASE_IN_OUT) - transition_tween.start() - # should spawn the tutorial thingies which are still remembered in the progress dictionary - signal_manager.connect("terminal_activated", self, "stop_level_music") - signal_manager.emit_signal("level_loaded") - get_tree().paused = false - $SceneAudio.play_parallel_sound(level_music, level_music_attenuation, false, 1.0, 0, "Music") - $SceneAudio.play_parallel_sound(level_ambiance, level_ambiance_attenuation) + $TransitionLayer.visible = true + var transition_tween = Tween.new() + add_child(transition_tween) + var property = "shader_param/position" + var node = $TransitionLayer/SceneTransition + transition_tween.interpolate_property( + node.material, property, -1.5, 1.0, 0.94, Tween.TRANS_LINEAR, Tween.EASE_IN_OUT + ) + transition_tween.start() + # should spawn the tutorial thingies which are still remembered in the progress dictionary + signal_manager.connect("terminal_activated", self, "stop_level_music") + signal_manager.emit_signal("level_loaded") + get_tree().paused = false + $SceneAudio.play_parallel_sound(level_music, level_music_attenuation, false, 1.0, 0, "Music") + $SceneAudio.play_parallel_sound(level_ambiance, level_ambiance_attenuation) + func stop_level_music(_unused: float) -> void: - $SceneAudio.stop_parallel_sound(level_music) + $SceneAudio.stop_parallel_sound(level_music) diff --git a/src/StateMachines/BlobbyStateMachine.gd b/src/StateMachines/BlobbyStateMachine.gd index 1c382dc..473e558 100644 --- a/src/StateMachines/BlobbyStateMachine.gd +++ b/src/StateMachines/BlobbyStateMachine.gd @@ -46,7 +46,7 @@ func _ready(): set_state(states.idle) # Zero Vector is false - if GlobalState.get_savepoint(level_state.levelName): + if level_state.load_savepoint(): parent.global_position = GlobalState.get_savepoint(level_state.levelName) diff --git a/src/UserInterface/Screens/HUD.tscn b/src/UserInterface/Screens/HUD.tscn index 4c07390..ab723b0 100644 --- a/src/UserInterface/Screens/HUD.tscn +++ b/src/UserInterface/Screens/HUD.tscn @@ -116,6 +116,7 @@ anims/Redlight = SubResource( 2 ) [node name="Currency" type="Label" parent="."] unique_name_in_owner = true +visible = false anchor_top = 1.0 anchor_bottom = 1.0 margin_left = 9.0 diff --git a/src/UserInterface/Screens/MainMenu/LevelCheckBox.gd b/src/UserInterface/Screens/MainMenu/LevelCheckBox.gd index 3b91756..df9b540 100644 --- a/src/UserInterface/Screens/MainMenu/LevelCheckBox.gd +++ b/src/UserInterface/Screens/MainMenu/LevelCheckBox.gd @@ -9,6 +9,11 @@ func initialize_with_progress(levelFullName: String) -> void: for key in froggies.keys(): register_froggy(int(key), froggies[key]) + var level_time : float = GlobalState.get_level_time(levelFullName) + if(GlobalState.get_level_completed(levelFullName)): + $LevelTime.visible = true + $LevelTime.text = "Time " + str(round(level_time*1000)/1000) + " sec" + func register_froggy(var count : int = 0, var freed: bool = false) -> void: var frogo: String = "%FreedFroggy" + str(count + 1) diff --git a/src/UserInterface/Screens/MainMenu/LevelCheckBox.tscn b/src/UserInterface/Screens/MainMenu/LevelCheckBox.tscn index 69acaab..8d8cf55 100644 --- a/src/UserInterface/Screens/MainMenu/LevelCheckBox.tscn +++ b/src/UserInterface/Screens/MainMenu/LevelCheckBox.tscn @@ -1,9 +1,24 @@ -[gd_scene load_steps=5 format=2] +[gd_scene load_steps=9 format=2] [ext_resource path="res://assets/ui/froggy-freed-ui.png" type="Texture" id=1] [ext_resource path="res://assets/ui/froggy-imprisoned-ui.png" type="Texture" id=2] [ext_resource path="res://src/UserInterface/Screens/MainMenu/LevelCheckBox.gd" type="Script" id=3] [ext_resource path="res://src/UserInterface/Buttons/AudibleCheckbox.gd" type="Script" id=4] +[ext_resource path="res://assets/ui/sci-fi-godot-theme/sci-fi-theme.tres" type="Theme" id=5] + +[sub_resource type="DynamicFontData" id=12] +font_path = "res://assets/ui/fonts/Kenney Thick.ttf" + +[sub_resource type="DynamicFont" id=14] +size = 8 +extra_spacing_top = 4 +extra_spacing_bottom = 4 +font_data = SubResource( 12 ) + +[sub_resource type="DynamicFont" id=13] +size = 6 +extra_spacing_top = 4 +font_data = SubResource( 12 ) [node name="LevelCheckBox" type="VBoxContainer"] margin_right = 116.0 @@ -11,13 +26,16 @@ margin_bottom = 56.0 focus_mode = 2 size_flags_horizontal = 3 size_flags_vertical = 3 +theme = ExtResource( 5 ) +custom_constants/separation = 4 script = ExtResource( 3 ) [node name="CheckBox" type="CheckBox" parent="."] -margin_right = 119.0 -margin_bottom = 24.0 +margin_right = 126.0 +margin_bottom = 17.0 grow_horizontal = 0 grow_vertical = 0 +custom_fonts/font = SubResource( 14 ) text = "This is a level " align = 1 icon_align = 1 @@ -144,10 +162,21 @@ size_flags_horizontal = 3 size_flags_vertical = 3 texture = ExtResource( 2 ) -[node name="HSeparator" type="HSeparator" parent="."] -margin_top = 28.0 -margin_right = 119.0 +[node name="LevelTime" type="Label" parent="."] +visible = false +margin_top = 21.0 +margin_right = 126.0 margin_bottom = 32.0 +custom_colors/font_color = Color( 0.717647, 0.717647, 0.717647, 1 ) +custom_fonts/font = SubResource( 13 ) +text = "Time: 10 sec" +align = 1 +autowrap = true + +[node name="HSeparator" type="HSeparator" parent="."] +margin_top = 21.0 +margin_right = 126.0 +margin_bottom = 25.0 [connection signal="focus_entered" from="." to="." method="_on_LevelCheckBox_focus_entered"] [connection signal="pressed" from="CheckBox" to="." method="_on_CheckBox_pressed"] diff --git a/src/UserInterface/Screens/MainMenu/MainScreen.tscn b/src/UserInterface/Screens/MainMenu/MainScreen.tscn index 914e56a..6243b03 100644 --- a/src/UserInterface/Screens/MainMenu/MainScreen.tscn +++ b/src/UserInterface/Screens/MainMenu/MainScreen.tscn @@ -225,7 +225,8 @@ scroll_horizontal_enabled = false script = ExtResource( 11 ) [node name="VBoxContainer" type="VBoxContainer" parent="MenuContainer/Panel/LevelList"] -margin_right = 119.0 +margin_right = 123.0 +margin_bottom = 102.0 grow_horizontal = 2 grow_vertical = 2 size_flags_horizontal = 3 @@ -234,7 +235,7 @@ alignment = 1 [node name="InvisibleCunt" type="CheckBox" parent="MenuContainer/Panel/LevelList/VBoxContainer"] visible = false -margin_right = 216.0 +margin_right = 123.0 margin_bottom = 102.0 grow_horizontal = 2 grow_vertical = 2 diff --git a/src/UserInterface/TutorialThingy.tscn b/src/UserInterface/TutorialThingy.tscn index e8162cf..48946ed 100644 --- a/src/UserInterface/TutorialThingy.tscn +++ b/src/UserInterface/TutorialThingy.tscn @@ -186,6 +186,7 @@ custom_fonts/font = ExtResource( 5 ) text = "This is a test " align = 1 +autowrap = true uppercase = true [node name="TextureRect2" type="TextureRect" parent="."] diff --git a/src/Utilities/LevelState.gd b/src/Utilities/LevelState.gd index afa6b1f..f495e8e 100644 --- a/src/Utilities/LevelState.gd +++ b/src/Utilities/LevelState.gd @@ -4,112 +4,158 @@ onready var signal_manager := get_tree().root.get_child(4).get_node("%SignalMana onready var levelName := get_tree().current_scene.filename #TODO Easteregg pls -var currency: = 0 setget set_currency -var deaths: = 0 setget set_deaths +var currency := 0 setget set_currency, get_currency +var deaths := 0 setget set_deaths var freed_frogs := [] # TODO Rename probs -var is_dead: = false setget set_dead +var is_dead := false setget set_dead + +var level_time := 0.0 func _ready() -> void: - GlobalState.gsr.last_played_level = levelName - SaveManager.save_default() - signal_manager.connect("level_completed", self, "_on_level_completed") - signal_manager.connect("player_died", self, "player_dying") + GlobalState.gsr.last_played_level = levelName + SaveManager.save_default() + if GlobalState.get_level_completed(levelName): + GlobalState.set_level_completed(levelName, false) + signal_manager.connect("level_completed", self, "_on_level_completed") + signal_manager.connect("player_died", self, "player_dying") + + +func _physics_process(delta: float) -> void: + level_time += delta + func reset() -> void: - deaths = 0 - currency = 0 - freed_frogs = [] - # TODO Maybe not the place for this? - if GlobalState.gsr.progress_dict.has(levelName): - GlobalState.gsr.progress_dict[levelName].erase("savepoint") + deaths = 0 + currency = 0 + freed_frogs = [] + # TODO Maybe not the place for this? + if GlobalState.gsr.progress_dict.has(levelName): + GlobalState.gsr.progress_dict[levelName].erase("savepoint") + func set_currency(value: int) -> void: - currency = value - signal_manager.emit_signal("currency_updated") + currency = value + signal_manager.emit_signal("currency_updated") + +func get_currency() -> int: + return GlobalState.gsr.wallet + currency func set_deaths(value: int) -> void: - deaths = value + deaths = value + func set_dead(value: bool) -> void: - is_dead = value + is_dead = value +func set_savepoint(pos: Vector2) -> void: + GlobalState.set_savepoint(levelName, pos) + GlobalState.set_uncompleted_level_time(levelName, level_time) + +func load_savepoint() -> bool: + if !GlobalState.get_savepoint(levelName): + return false + level_time = GlobalState.get_uncompleted_level_time(levelName) + return true + +# Registers a new frog which exists in the loaded level, with the progress resource func register_frog(number: int, freed: bool = false) -> void: - update_global_state() - if(!GlobalState.gsr.progress_dict[levelName]["froggies"].has(number)): - GlobalState.gsr.progress_dict[levelName]["froggies"][number] = freed - GlobalState.save() + update_global_state() + if !GlobalState.gsr.progress_dict[levelName]["froggies"].has(number): + GlobalState.gsr.progress_dict[levelName]["froggies"][number] = freed + GlobalState.save() + func free_a_frog(number: int) -> void: - freed_frogs.append(number) + freed_frogs.append(number) + func needs_tutorial(lesson: String) -> bool: - if(!GlobalState.gsr.tutorial_prompts.has(lesson)): - return false - return GlobalState.gsr.tutorial_prompts[lesson] + if !GlobalState.gsr.tutorial_prompts.has(lesson): + return false + return GlobalState.gsr.tutorial_prompts[lesson] + func register_tutorial(lesson: String) -> void: - if(GlobalState.gsr.tutorial_prompts.has(lesson)): - return - GlobalState.gsr.tutorial_prompts[lesson] = true - GlobalState.save() + if GlobalState.gsr.tutorial_prompts.has(lesson): + return + GlobalState.gsr.tutorial_prompts[lesson] = true + GlobalState.save() + func absolved_tutorial(lesson: String) -> void: - if(!GlobalState.gsr.tutorial_prompts.has(lesson)): - return - GlobalState.gsr.tutorial_prompts[lesson] = false - GlobalState.save() + if !GlobalState.gsr.tutorial_prompts.has(lesson): + return + GlobalState.gsr.tutorial_prompts[lesson] = false + GlobalState.save() + # Spends the currency when enough is available # and returns true if so. Else it does not spend and return false. func spend_currency(cost: int) -> bool: - # TODO member that - if(OS.is_debug_build()): - return true - if GlobalState.gsr.wallet + currency < cost: - return false - var remainder = currency - cost - if remainder >= 0: - currency = remainder - else: - currency = 0 - GlobalState.set_wallet(GlobalState.gsr.wallet + remainder) - return true + # TODO member that + if OS.is_debug_build(): + return true + if get_currency() < cost: + return false + var remainder = currency - cost + if remainder >= 0: + set_currency(remainder) + # When level collected currency is not enough, deplete saved up currency in global state + else: + currency = 0 + GlobalState.set_wallet(GlobalState.gsr.wallet + remainder) + return true + func _on_level_completed(): - #if(OS.is_debug_build()): - # return - update_global_state() - reset() + #if(OS.is_debug_build()): + # return + # TODO Extra screen for new best time + GlobalState.set_level_completed(levelName, true) + if(GlobalState.get_level_time(levelName) > level_time ): + GlobalState.set_leveltime(levelName, level_time) + GlobalState.set_uncompleted_level_time(levelName, INF) + GlobalState.remove_savepoint(levelName) + update_global_state() + reset() + func update_global_state() -> void: - var progress_dict : Dictionary = GlobalState.get_progress() - var levelProgress : Dictionary = {} + var progress_dict: Dictionary = GlobalState.get_progress() + var levelProgress: Dictionary = {} - levelProgress["currency"] = currency - levelProgress["deaths"] = deaths - - # TODO Doesnt account for multiple plays of same level - if !progress_dict.has(levelName): - progress_dict[levelName] = levelProgress - else: - progress_dict[levelName]["currency"] = GlobalState.get_property_value(levelName,"currency") + currency - progress_dict[levelName]["deaths"] = GlobalState.get_property_value(levelName,"deaths") + deaths - if !progress_dict[levelName].has("froggies"): - progress_dict[levelName]["froggies"] = {} - else: - for frog_number in freed_frogs: - if progress_dict[levelName]["froggies"].has(frog_number): - progress_dict[levelName]["froggies"][frog_number] = true + levelProgress["currency"] = currency + levelProgress["deaths"] = deaths + + # TODO Doesnt account for multiple plays of same level + if !progress_dict.has(levelName): + progress_dict[levelName] = levelProgress + else: + progress_dict[levelName]["currency"] = ( + GlobalState.get_property_value(levelName, "currency") + + currency + ) + progress_dict[levelName]["deaths"] = ( + GlobalState.get_property_value(levelName, "deaths") + + deaths + ) + if !progress_dict[levelName].has("froggies"): + progress_dict[levelName]["froggies"] = {} + else: + for frog_number in freed_frogs: + if progress_dict[levelName]["froggies"].has(frog_number): + progress_dict[levelName]["froggies"][frog_number] = true + + # TODO Wallet is independant from progress_dict because??? + GlobalState.set_wallet(GlobalState.gsr.wallet + currency) + GlobalState.set_progress(progress_dict) - # TODO Wallet is independant from progress_dict because??? - GlobalState.set_wallet(GlobalState.gsr.wallet + currency) - GlobalState.set_progress(progress_dict) func player_dying(animation_number: int = 0) -> void: - currency = 0 - is_dead = true - freed_frogs = [] - deaths += 1 - update_global_state() - deaths = 0 + currency = 0 + is_dead = true + freed_frogs = [] + deaths += 1 + update_global_state() + deaths = 0 diff --git a/src/Utilities/SceneAudio.gd b/src/Utilities/SceneAudio.gd index c7de026..f9d5b60 100644 --- a/src/Utilities/SceneAudio.gd +++ b/src/Utilities/SceneAudio.gd @@ -8,74 +8,76 @@ onready var static_player: AudioStreamPlayer = $StaticPlayer # Plays sound with the static player, interrupting sounds if currently playing func play_sound( - sound_name: String, - attenuation: float = 0.0, - random_pitch = false, - pitch = 1.0, - start_time = 0.0, - bus: String = "Effects" + sound_name: String, + attenuation: float = 0.0, + random_pitch = false, + pitch = 1.0, + start_time = 0.0, + bus: String = "Effects" ) -> void: - # TODO is it bad to grab the stream each time? - var stream = GlobalState.sound_library[sound_name] - if random_pitch: - stream = AudioStreamRandomPitch.new() - stream.audio_stream = GlobalState.sound_library[sound_name] - static_player.stream = stream - static_player.volume_db = attenuation - static_player.bus = bus - static_player.pitch_scale = pitch - static_player.stream_paused = false - static_player.play(start_time) + # TODO is it bad to grab the stream each time? + var stream = GlobalState.sound_library[sound_name] + if random_pitch: + stream = AudioStreamRandomPitch.new() + stream.audio_stream = GlobalState.sound_library[sound_name] + static_player.stream = stream + static_player.volume_db = attenuation + static_player.bus = bus + static_player.pitch_scale = pitch + static_player.stream_paused = false + static_player.play(start_time) func stop_sound(): - static_player.stream_paused = true + static_player.stream_paused = true # Mirrors the GlobalAudio Method which can play sounds across scenes func play_parallel_sound( - sound_name: String, - attenuation: float = 0.0, - random_pitch = false, - pitch = 1.0, - start_time = 0.0, - bus: String = "Effects", - singleton = false + sound_name: String, + attenuation: float = 0.0, + random_pitch = false, + pitch = 1.0, + start_time = 0.0, + bus: String = "Effects", + singleton = false ) -> void: - if singleton && players.has(sound_name): - return - var disposable_player = AudioStreamPlayer.new() - add_child(disposable_player) - var stream = GlobalState.sound_library[sound_name] - if random_pitch: - stream = AudioStreamRandomPitch.new() - stream.audio_stream = GlobalState.sound_library[sound_name] - disposable_player.stream = stream - disposable_player.volume_db = attenuation - disposable_player.bus = bus - disposable_player.pitch_scale = pitch - disposable_player.play(start_time) - disposable_player.connect("finished", self, "dispose_parallel_player", [weakref(disposable_player)]) - players[sound_name] = weakref(disposable_player) + if singleton && players.has(sound_name): + return + var disposable_player = AudioStreamPlayer.new() + add_child(disposable_player) + var stream = GlobalState.sound_library[sound_name] + if random_pitch: + stream = AudioStreamRandomPitch.new() + stream.audio_stream = GlobalState.sound_library[sound_name] + disposable_player.stream = stream + disposable_player.volume_db = attenuation + disposable_player.bus = bus + disposable_player.pitch_scale = pitch + disposable_player.play(start_time) + disposable_player.connect( + "finished", self, "dispose_parallel_player", [weakref(disposable_player)] + ) + players[sound_name] = weakref(disposable_player) func dispose_parallel_player(player: WeakRef) -> void: - if !player.get_ref(): - return - player.get_ref().queue_free() + if !player.get_ref(): + return + player.get_ref().queue_free() func pause_parallel_sound(sound_name: String): - if players.has(sound_name) && players[sound_name].get_ref(): - players[sound_name].set_stream_paused(true) + if players.has(sound_name) && players[sound_name].get_ref(): + players[sound_name].set_stream_paused(true) func continue_parallel_sound(sound_name: String): - if players.has(sound_name) && players[sound_name].get_ref(): - players[sound_name].set_stream_paused(false) + if players.has(sound_name) && players[sound_name].get_ref(): + players[sound_name].set_stream_paused(false) func stop_parallel_sound(sound_name: String): - if players.has(sound_name) && players[sound_name].get_ref(): - dispose_parallel_player(players[sound_name]) - players.erase(sound_name) + if players.has(sound_name) && players[sound_name].get_ref(): + dispose_parallel_player(players[sound_name]) + players.erase(sound_name)