Let slugs eat and gear up for a fight

This commit is contained in:
Olivier 'reivilibre' 2023-01-09 03:29:53 +00:00
parent b6b38133db
commit 412a151d45
5 changed files with 79 additions and 9 deletions

View File

@ -1,6 +1,7 @@
extends KinematicBody2D extends KinematicBody2D
const SPEED := 50 const SPEED := 50
const HEAL_RATE_PER_OLIVE := 1.0
var _velocity := Vector2.ZERO var _velocity := Vector2.ZERO
@ -8,7 +9,7 @@ onready var _agent: NavigationAgent2D = $NavigationAgent2D
var target: Node2D = null var target: Node2D = null
var eaten_olives: int = 0 var eaten_olives: float = 0
var hp: float = 0 var hp: float = 0
@ -25,9 +26,12 @@ func _find_target() -> void:
var best_tree = null var best_tree = null
var best_tree_juiciness = -1 var best_tree_juiciness = -1
for tree in trees: for tree in trees:
var tree_distsq = self.global_position.distance_squared_to(tree.global_position) var tree_distsq := self.global_position.distance_squared_to(tree.global_position)
var tree_food = tree.calculate_food(sqrt(tree_distsq) / SPEED) var tree_dist := sqrt(tree_distsq)
var tree_juiciness = tree_food / tree_distsq var tree_food = tree.calculate_food(tree_dist / SPEED)
if tree_food < 0.1:
continue
var tree_juiciness = tree_food / tree_dist
if tree_juiciness > best_tree_juiciness: if tree_juiciness > best_tree_juiciness:
best_tree = tree best_tree = tree
@ -39,8 +43,27 @@ func _find_target() -> void:
_agent.set_target_location(target.global_position) _agent.set_target_location(target.global_position)
func _at_target() -> void: func _at_target() -> void:
print("at target") if target.is_in_group("olive_trees"):
_eating()
pass pass
func _eating() -> void:
var tree = target
while true:
var just_eaten = tree.eat_food()
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")
if just_eaten <= 0.1:
_find_target()
return
func _physics_process(delta: float) -> void: func _physics_process(delta: float) -> void:
if target == null: if target == null:
@ -68,6 +91,10 @@ func _physics_process(delta: float) -> void:
#print(_velocity) #print(_velocity)
var _vel := move_and_slide(_velocity) var _vel := move_and_slide(_velocity)
func _process(delta: float) -> void:
hp = min(eaten_olives, hp + eaten_olives * HEAL_RATE_PER_OLIVE * delta)
_on_hp_updated()
func _on_hp_updated() -> void: func _on_hp_updated() -> void:
if hp == eaten_olives: if hp == eaten_olives:
self.modulate.a = 1.0 self.modulate.a = 1.0
@ -81,7 +108,7 @@ func _on_eaten_olives_updated() -> void:
self.modulate.b = non_red self.modulate.b = non_red
func interact(_player: Node2D) -> bool: func interact(_player: Node2D) -> bool:
self.hp -= 1 self.hp -= 1.0
if self.hp < 0: if self.hp < 0:
# the slug is dead! # the slug is dead!
$SlimyWalkSfx.stop() $SlimyWalkSfx.stop()
@ -92,3 +119,10 @@ func interact(_player: Node2D) -> bool:
self._on_hp_updated() self._on_hp_updated()
return true return true
func _on_NavigationAgent2D_target_reached() -> void:
var dsq := self.global_position.distance_squared_to(target.global_position)
print("reached distsq = ", dsq)
if dsq < 256:
self._at_target()

View File

@ -26,7 +26,7 @@ animations = [ {
radius = 6.0 radius = 6.0
height = 40.0 height = 40.0
[node name="Slug" type="KinematicBody2D"] [node name="Slug" type="KinematicBody2D" groups=["interactable"]]
collision_layer = 2 collision_layer = 2
collision_mask = 0 collision_mask = 0
script = ExtResource( 7 ) script = ExtResource( 7 )
@ -49,3 +49,5 @@ path_max_distance = 64.0
[node name="SlimyWalkSfx" type="AudioStreamPlayer2D" parent="."] [node name="SlimyWalkSfx" type="AudioStreamPlayer2D" parent="."]
stream = ExtResource( 8 ) stream = ExtResource( 8 )
[connection signal="target_reached" from="NavigationAgent2D" to="." method="_on_NavigationAgent2D_target_reached"]

View File

@ -81,10 +81,10 @@ position = Vector2( 247, 412 )
position = Vector2( 486, 154 ) position = Vector2( 486, 154 )
[node name="Node2D" parent="World/YSort" instance=ExtResource( 3 )] [node name="Node2D" parent="World/YSort" instance=ExtResource( 3 )]
position = Vector2( 701, 189 ) position = Vector2( 1134, 649 )
[node name="Node2D2" parent="World/YSort" instance=ExtResource( 3 )] [node name="Node2D2" parent="World/YSort" instance=ExtResource( 3 )]
position = Vector2( 135, 190 ) position = Vector2( 574, 653 )
[node name="Node2D3" parent="World/YSort" instance=ExtResource( 4 )] [node name="Node2D3" parent="World/YSort" instance=ExtResource( 4 )]
position = Vector2( 542, 475 ) position = Vector2( 542, 475 )

View File

@ -34,3 +34,28 @@ func calculate_food(in_time: float) -> float:
food += child.calculate_food_on_bud(in_time) food += child.calculate_food_on_bud(in_time)
return food return food
func eat_food() -> float:
if not has_been_munched:
# TODO sfx
# TODO show munched sprite... colour will do for now
$Sprite.modulate = Color(0.6, 0.4, 0.4)
has_been_munched = true
for child in self.get_children():
# curse all buds
# TODO they will recover when next harvested, so this isn't as bad
# as it sounds..
if child.has_method("drop_olive"):
child.grow_rate *= 0.5
return 2.0
var limit = 1.0
var eaten = 0
for child in self.get_children():
if child.has_method("drop_olive"):
eaten += child.eat_food_from_bud(limit - eaten)
if limit - eaten < 0.01:
break
return eaten

View File

@ -61,3 +61,12 @@ func drop_olive():
func calculate_food_on_bud(in_time: float) -> float: func calculate_food_on_bud(in_time: float) -> float:
return clamp(progress + in_time * grow_rate, 0.0, 1.0) return clamp(progress + in_time * grow_rate, 0.0, 1.0)
func eat_food_from_bud(limit: float) -> float:
if limit >= progress:
var eaten = max(0.0, progress)
self.reset()
return eaten
else:
set_progress(progress - limit)
return limit