From 338137be0994f20ccf6465653d9ab738b9283401 Mon Sep 17 00:00:00 2001 From: fredrikr79 Date: Sat, 4 Oct 2025 15:32:50 +0200 Subject: [PATCH] add: basic virus implementation --- growth/virus.gd | 56 ++++++++++++++++++++++++++++++++++++++--------- growth/virus.tscn | 12 +++++++++- 2 files changed, 57 insertions(+), 11 deletions(-) diff --git a/growth/virus.gd b/growth/virus.gd index 8e37cc9..a34fc1f 100644 --- a/growth/virus.gd +++ b/growth/virus.gd @@ -1,16 +1,52 @@ extends Node2D -@export var speed = 400 # How fast the player will move (pixels/sec). +@export var speed = 400 # How fast the virus will move (pixels/sec). +@export var attack_range = 200 # virus vision radius (pixels) + +# a virus is instantiated as Spawning and transitions (matures) into Spawned +# after a timer timeout, after which it is activated and ready to do its thing. +enum SpawningState {Spawning, Spawned} +# when idle, a virus Waits. if it has already performed some action, it may +# become Blocked for a while. otherwise it might be Running. like a process. +enum ActionState {Blocked, Waiting, Running} + +var spawning_state +var action_state + +var targets # who the virus will attack func _ready(): - # Initalize with random abilities from available abilities + self.spawning_state = SpawningState.Spawning + self.action_state = ActionState.Waiting func _process(delta): - # Grow in size - - # RayCast towards player (every N frames), moving towards it if close enough - # Or should we always move towards the player? - - # Use abilities if: - ## Raycast hit - ## Regular intervals (if close enough to player)? + if self.spawning_state != SpawningState.Spawned: + return # do nothing if not yet spawned + if len(self.targets) == 0: + return # do nothing if no set targets + + # --- determine nearest target + var nearest_target = self.targets[0] + var shortest_distance = 0 + for i in range(1, len(self.targets)): + var target = self.targets[i] + var distance = self.position.distance_to(target) + if distance < shortest_distance: + shortest_distance = distance + nearest_target = target + + # --- attack the nearest target, if within range + if self.action_state != ActionState.Blocked: + if shortest_distance < self.attack_range: + self.attack(nearest_target) + + # --- move towards nearest target + self.position += \ + self.position.direction_to(nearest_target) * self.speed * delta + +func attack(target): + # do attack, block until timer + self.action_state = ActionState.Blocked + +func _on_mature(): + spawning_state = SpawningState.Spawned diff --git a/growth/virus.tscn b/growth/virus.tscn index 8fa0901..d2d4f81 100644 --- a/growth/virus.tscn +++ b/growth/virus.tscn @@ -1,6 +1,9 @@ -[gd_scene format=3 uid="uid://bsv3h2lpv7h77"] +[gd_scene load_steps=2 format=3 uid="uid://bsv3h2lpv7h77"] + +[ext_resource type="Script" uid="uid://bwhxwf77egesx" path="res://virus.gd" id="1_5nuwd"] [node name="Virus" type="Node2D"] +script = ExtResource("1_5nuwd") [node name="AnimatedSprite2D" type="AnimatedSprite2D" parent="."] @@ -9,3 +12,10 @@ [node name="CollisionShape2D" type="CollisionShape2D" parent="Area2D"] [node name="RayCast2D" type="RayCast2D" parent="."] + +[node name="SpawningTime" type="Timer" parent="."] +editor_description = "How long to mature from Spawning to Spawned" +one_shot = true +autostart = true + +[connection signal="timeout" from="SpawningTime" to="." method="_on_mature"]