diff --git a/characters/pests/Slug.gd b/characters/pests/Slug.gd index ce94f68..90df861 100644 --- a/characters/pests/Slug.gd +++ b/characters/pests/Slug.gd @@ -29,6 +29,7 @@ func _find_target() -> void: var tree_distsq := self.global_position.distance_squared_to(tree.global_position) var tree_dist := sqrt(tree_distsq) var tree_food = tree.calculate_food(tree_dist / SPEED) + #print("est food ", tree_food) if tree_food < 0.1: continue var tree_juiciness = tree_food / tree_dist @@ -45,25 +46,48 @@ func _find_target() -> void: func _at_target() -> void: if target.is_in_group("olive_trees"): _eating() - pass + if target.name == "Player": + _explode() + +var busy_eating = false func _eating() -> void: + if busy_eating: + return + busy_eating = true var tree = target while true: var just_eaten = tree.eat_food() - print("ate ", just_eaten) + #print("ate ", just_eaten) eaten_olives += just_eaten hp += just_eaten _on_eaten_olives_updated() # TODO sfx # TODO vfx - - yield(get_tree().create_timer(2.0, false), "timeout") + $EatingTimer.start(2.0); yield($EatingTimer, "timeout") if just_eaten <= 0.1: _find_target() + busy_eating = false return + + busy_eating = false + +func _explode() -> void: + var tree = get_tree() + target = null + $RenavigateTimer.stop() + var tween = tree.create_tween() + $ExplodeSfx.pitch_scale = rand_range(0.7, 1.2) + $ExplodeSfx.play() + tween.tween_property($AnimatedSprite, "scale", Vector2(2.5, 2.5), 0.5).set_ease(Tween.EASE_OUT).set_trans(Tween.TRANS_BACK) + tween.tween_property(self, "modulate:a", 0.5, 0.5).set_ease(Tween.EASE_OUT).set_trans(Tween.TRANS_BOUNCE) + tween.tween_callback(self, "queue_free") + var hud = find_parent("Level*").get_node("Hud") + # TODO sfx + tween.tween_callback(hud, "remove_hp") + func _physics_process(delta: float) -> void: if target == null: @@ -94,12 +118,15 @@ func _physics_process(delta: float) -> void: func _process(delta: float) -> void: hp = min(eaten_olives, hp + eaten_olives * HEAL_RATE_PER_OLIVE * delta) _on_hp_updated() + if target != null and target.name == "Player": + if target.global_position.distance_squared_to(self.global_position) < 1024: + self._explode() func _on_hp_updated() -> void: if hp == eaten_olives: self.modulate.a = 1.0 else: - self.modulate.a = clamp(sqrt(hp / eaten_olives), 0.0, 1.0) + self.modulate.a = clamp(sqrt(hp / max(eaten_olives, 0.1)), 0.0, 1.0) func _on_eaten_olives_updated() -> void: self.scale = Vector2(1, 1) * (1.0 + eaten_olives * 0.1) @@ -114,6 +141,7 @@ func interact(_player: Node2D) -> bool: $SlimyWalkSfx.stop() target = null # TODO sfx + $RenavigateTimer.stop() self.queue_free() else: self._on_hp_updated() @@ -131,3 +159,5 @@ func _on_NavigationAgent2D_target_reached() -> void: func _on_RenavigateTimer_timeout() -> void: if target != null: _agent.set_target_location(target.global_position) + else: + _find_target() diff --git a/characters/pests/Slug.tscn b/characters/pests/Slug.tscn index d6bb0b4..a09da98 100644 --- a/characters/pests/Slug.tscn +++ b/characters/pests/Slug.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=11 format=2] +[gd_scene load_steps=12 format=2] [ext_resource path="res://characters/pests/slug_frame0005.png" type="Texture" id=1] [ext_resource path="res://characters/pests/slug_frame0004.png" type="Texture" id=2] @@ -8,6 +8,7 @@ [ext_resource path="res://characters/pests/slug_frame0001.png" type="Texture" id=6] [ext_resource path="res://characters/pests/Slug.gd" type="Script" id=7] [ext_resource path="res://sfx/slimy_walk.wav" type="AudioStream" id=8] +[ext_resource path="res://sfx/slugsplode.wav" type="AudioStream" id=9] [sub_resource type="SpriteFrames" id=1] animations = [ { @@ -53,5 +54,11 @@ stream = ExtResource( 8 ) [node name="RenavigateTimer" type="Timer" parent="."] autostart = true +[node name="ExplodeSfx" type="AudioStreamPlayer2D" parent="."] +stream = ExtResource( 9 ) + +[node name="EatingTimer" type="Timer" parent="."] +one_shot = true + [connection signal="target_reached" from="NavigationAgent2D" to="." method="_on_NavigationAgent2D_target_reached"] [connection signal="timeout" from="RenavigateTimer" to="." method="_on_RenavigateTimer_timeout"] diff --git a/characters/player/PlayerAttachmentManager.gd b/characters/player/PlayerAttachmentManager.gd index 1a43c7c..dfecd7c 100644 --- a/characters/player/PlayerAttachmentManager.gd +++ b/characters/player/PlayerAttachmentManager.gd @@ -33,4 +33,4 @@ func _physics_process(_delta): return var velocity = (-anchor_relative_to_us.normalized()) * min(MAX_SPEED, SPEED_PER_DISTANCE * distance) - attached.move_and_slide(velocity) + var _lv = attached.move_and_slide(velocity) diff --git a/levels/Level0A.tscn b/levels/Level0A.tscn index 8597d44..6ff0154 100644 --- a/levels/Level0A.tscn +++ b/levels/Level0A.tscn @@ -83,6 +83,9 @@ position = Vector2( 486, 154 ) [node name="Node2D" parent="World/YSort" instance=ExtResource( 3 )] position = Vector2( 1134, 649 ) +[node name="Node2D4" parent="World/YSort" instance=ExtResource( 3 )] +position = Vector2( 1114, 493 ) + [node name="Node2D2" parent="World/YSort" instance=ExtResource( 3 )] position = Vector2( 574, 653 ) @@ -92,6 +95,15 @@ position = Vector2( 542, 475 ) [node name="Slug" parent="World/YSort" instance=ExtResource( 7 )] position = Vector2( 184, 679 ) +[node name="Slug4" parent="World/YSort" instance=ExtResource( 7 )] +position = Vector2( 61, 628 ) + +[node name="Slug2" parent="World/YSort" instance=ExtResource( 7 )] +position = Vector2( 184, 660 ) + +[node name="Slug3" parent="World/YSort" instance=ExtResource( 7 )] +position = Vector2( 172, 689 ) + [node name="MarkerRoadPoint" type="Node2D" parent="World"] position = Vector2( 328, 770 ) diff --git a/sfx/slugsplode.wav b/sfx/slugsplode.wav new file mode 100644 index 0000000..42ac191 --- /dev/null +++ b/sfx/slugsplode.wav @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b77851a97255d9195fce8f695b40b7d18ee1fd637bd32a308854de1ac541e7f5 +size 22033 diff --git a/sfx/slugsplode.wav.import b/sfx/slugsplode.wav.import new file mode 100644 index 0000000..fbf4669 --- /dev/null +++ b/sfx/slugsplode.wav.import @@ -0,0 +1,23 @@ +[remap] + +importer="wav" +type="AudioStreamSample" +path="res://.import/slugsplode.wav-419a9dd79535d0778834c99c725fc959.sample" + +[deps] + +source_file="res://sfx/slugsplode.wav" +dest_files=[ "res://.import/slugsplode.wav-419a9dd79535d0778834c99c725fc959.sample" ] + +[params] + +force/8_bit=false +force/mono=false +force/max_rate=false +force/max_rate_hz=44100 +edit/trim=false +edit/normalize=false +edit/loop_mode=0 +edit/loop_begin=0 +edit/loop_end=-1 +compress/mode=0 diff --git a/ui/Hud.gd b/ui/Hud.gd index 733f392..41ceab3 100644 --- a/ui/Hud.gd +++ b/ui/Hud.gd @@ -6,12 +6,40 @@ export var postie_times = [0.5] # Anything above 10 can't be rendered (for now?) export var num_days = 5 +export var next_level = "" + func add_coin(amount: int): coin += amount $HudInner/Panel/LabelCoin.text = str(coin) +var hp: int = 3 + +func _lose(): + get_tree().paused = true + $HudInner/GameOverDialogue.visible = true + return + +func _win(): + var _r = get_tree().change_scene("res://levels/" + next_level + ".tscn") + +func remove_hp(): + if hp == 0: + # Lose game + self._lose() + return + + hp -= 1 + var hp_indicator = $HudInner/Panel/HpBar.get_child(hp) + hp_indicator.modulate.r = 0 func _ready(): + # get a fresh seed for the PRNG + randomize() + $HudInner/GameOverDialogue.visible = false + + if next_level == "": + printerr("No next level configured!") + var sch = $HudInner/Panel/Scheduler sch.postie_times = postie_times sch.days_on_this_level = num_days @@ -19,3 +47,9 @@ func _ready(): var w2d: World2D = get_world_2d() # random place to put it, but needed to get our navigation working: Navigation2DServer.map_set_edge_connection_margin(w2d.navigation_map, 10.0) + + +func _on_TryAgainButton_pressed() -> void: + # restart the level + print("reload ", get_tree().reload_current_scene()) + get_tree().paused = false diff --git a/ui/Hud.tscn b/ui/Hud.tscn index af69edc..3d7281d 100644 --- a/ui/Hud.tscn +++ b/ui/Hud.tscn @@ -1,9 +1,10 @@ -[gd_scene load_steps=5 format=2] +[gd_scene load_steps=6 format=2] [ext_resource path="res://ui/normal_font.tres" type="DynamicFont" id=1] [ext_resource path="res://ui/coin.png" type="Texture" id=2] [ext_resource path="res://ui/Hud.gd" type="Script" id=3] [ext_resource path="res://ui/Scheduler.tscn" type="PackedScene" id=4] +[ext_resource path="res://ui/hp.png" type="Texture" id=5] [node name="Hud" type="Node2D"] z_index = 50 @@ -39,3 +40,42 @@ margin_left = 120.0 margin_top = 8.0 margin_right = -8.0 margin_bottom = -88.0 + +[node name="HpBar" type="Node2D" parent="HudInner/Panel"] +position = Vector2( 31, 69 ) + +[node name="Sprite" type="Sprite" parent="HudInner/Panel/HpBar"] +texture = ExtResource( 5 ) + +[node name="Sprite2" type="Sprite" parent="HudInner/Panel/HpBar"] +position = Vector2( 22, 0 ) +texture = ExtResource( 5 ) + +[node name="Sprite3" type="Sprite" parent="HudInner/Panel/HpBar"] +position = Vector2( 44, 0 ) +texture = ExtResource( 5 ) + +[node name="GameOverDialogue" type="Panel" parent="HudInner"] +pause_mode = 2 +margin_left = 544.0 +margin_top = 360.0 +margin_right = 901.0 +margin_bottom = 480.0 + +[node name="SlugSorrowLabel" type="Label" parent="HudInner/GameOverDialogue"] +margin_left = 8.0 +margin_top = 8.0 +margin_right = 349.0 +margin_bottom = 84.0 +text = "Those pesky slugs may have gotten the better of you. + +Try again?" + +[node name="TryAgainButton" type="Button" parent="HudInner/GameOverDialogue"] +margin_left = 136.0 +margin_top = 96.0 +margin_right = 204.0 +margin_bottom = 116.0 +text = "Try again" + +[connection signal="pressed" from="HudInner/GameOverDialogue/TryAgainButton" to="." method="_on_TryAgainButton_pressed"] diff --git a/ui/Scheduler.gd b/ui/Scheduler.gd index 699d13e..a5afeb2 100644 --- a/ui/Scheduler.gd +++ b/ui/Scheduler.gd @@ -35,17 +35,22 @@ var time_of_day = 0.0 func _start_schedule(): # schedule all events for the day... - for day in range(days_on_this_level): + for _day in range(days_on_this_level): var parent = find_parent("Level*").get_node("World/YSort") for postie_time in postie_times: # 5s early so the postie has time to drive there. _postie_in(parent, (postie_time / DAY_PER_SEC) - 5.0, postie_length / DAY_PER_SEC) - yield(get_tree().create_timer(1 / DAY_PER_SEC, false), "timeout") + $Timer.start(1 / DAY_PER_SEC) + yield($Timer, "timeout") func _postie_in(parent: Node2D, time: float, idling_time: float): - yield(get_tree().create_timer(time, false), "timeout") + var timer = Timer.new() + timer.one_shot = true + $Timer.add_child(timer) + timer.start(time); yield(timer, "timeout") + $Timer.remove_child(timer) var new_postie = preload("res://vehicles/Postie.tscn").instance() new_postie.position = Vector2(-500, 0) new_postie.idling_time = idling_time @@ -53,7 +58,5 @@ func _postie_in(parent: Node2D, time: float, idling_time: float): func _process(delta): - var old_time = time_of_day time_of_day += delta * DAY_PER_SEC - $Clock/ClockHand.rotation = 2 * PI * fmod(time_of_day, 1.0) diff --git a/ui/Scheduler.tscn b/ui/Scheduler.tscn index a64b151..7a1152f 100644 --- a/ui/Scheduler.tscn +++ b/ui/Scheduler.tscn @@ -118,3 +118,4 @@ text = "Clock" align = 1 [node name="Timer" type="Timer" parent="."] +one_shot = true diff --git a/ui/hp.kra b/ui/hp.kra new file mode 100644 index 0000000..291e78d --- /dev/null +++ b/ui/hp.kra @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:88f4cbccd7b90484bd82fb6cf6382720f8caad914e9552484347119cdcb9bfa8 +size 70264 diff --git a/ui/hp.png b/ui/hp.png new file mode 100644 index 0000000..3d91c8c --- /dev/null +++ b/ui/hp.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fb846502f00d3293dde3002d90e5f94228cc510df8b2b6e990a5b99aef1a883f +size 1229 diff --git a/ui/hp.png.import b/ui/hp.png.import new file mode 100644 index 0000000..918838f --- /dev/null +++ b/ui/hp.png.import @@ -0,0 +1,35 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/hp.png-d487826fe303417660d08af683ed719a.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://ui/hp.png" +dest_files=[ "res://.import/hp.png-d487826fe303417660d08af683ed719a.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=true +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=2 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +process/normal_map_invert_y=false +stream=false +size_limit=0 +detect_3d=true +svg/scale=1.0