feat: Level completion time, vacuum behavior, button behavior, Vending Machine sprite

This commit is contained in:
Jakob Feldmann 2023-10-04 17:04:06 +02:00
parent 12a7a3d76a
commit 37b702f94a
32 changed files with 417 additions and 277 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 327 B

After

Width:  |  Height:  |  Size: 516 B

View File

@ -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

View File

@ -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 )

View File

@ -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)

View File

@ -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()

View File

@ -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))

View File

@ -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:

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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="."]

View File

@ -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]

View File

@ -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]

View File

@ -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

View File

@ -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 )

View File

@ -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]

View File

@ -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 )

View File

@ -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]

View File

@ -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 )

View File

@ -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 )]

View File

@ -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"]

View File

@ -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)

View File

@ -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)

View File

@ -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

View File

@ -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)

View File

@ -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"]

View File

@ -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

View File

@ -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="."]

View File

@ -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

View File

@ -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)