Merge remote-tracking branch 'refs/remotes/origin/stage/molecular' into stage/molecular

This commit is contained in:
2026-02-07 15:42:37 +01:00
8 changed files with 114 additions and 114 deletions

View File

@@ -114,7 +114,7 @@ script = ExtResource("4_mys4o")
[node name="PreyManager" type="Node" parent="." unique_id=1486332229]
script = ExtResource("5_cthuy")
scene = ExtResource("6_a5cls")
minCount = 10
minCount = 100
maxCount = 30
metadata/_custom_type_script = "uid://coetidfssb80w"

View File

@@ -8,6 +8,7 @@ var desired_rotation: float = self.rotation
@onready var sprite = $AnimatedSprite2D
@onready var fsm: StateMachine = $StateMachine
@onready var attack_cooldown_timer: Timer = $AttackCooldownTimer
@onready var wrapper: WrappingManager = $WrappingManager
@export var damage: int = 15
@export var attack_range = 20
@@ -71,6 +72,7 @@ func die() -> void:
func become_injured() -> void:
sprite.play("Hurt")
wrapper.play_sprite("Hurt")
func _on_sight_body_entered(body: Node2D) -> void:
if fsm.map(fsm.state) != fsm.States.HUNTING and body.is_in_group("prey") or (health < maxHealth and body.is_in_group("player")):

View File

@@ -7,7 +7,8 @@
[ext_resource type="Script" uid="uid://xbiqj7ubmj7d" path="res://molecular/prey/state_idle.gd" id="4_8a23j"]
[ext_resource type="Texture2D" uid="uid://jyuf4lgjo64" path="res://molecular/assets/predator/hammerheadRibozyme-hurt.png" id="4_shhro"]
[ext_resource type="Script" uid="uid://ubcu8fdfxxj1" path="res://molecular/prey/state_random_movement.gd" id="5_6rsu5"]
[ext_resource type="Script" path="res://molecular/predator/state_hunting.gd" id="8_7qt2q"]
[ext_resource type="Script" uid="uid://bc7apl71t0q04" path="res://molecular/predator/state_hunting.gd" id="8_7qt2q"]
[ext_resource type="Script" uid="uid://bvbc0n0pslq7p" path="res://shared/wrapping_manager.gd" id="9_shhro"]
[sub_resource type="AtlasTexture" id="AtlasTexture_8a23j"]
atlas = ExtResource("2_34kwa")
@@ -99,6 +100,11 @@ script = ExtResource("1_xp037")
maxHealth = 50
metadata/_custom_type_script = "uid://dgfimmq53whll"
[node name="WrappingManager" type="Node" parent="." unique_id=826586678 node_paths=PackedStringArray("sprite")]
script = ExtResource("9_shhro")
sprite = NodePath("../AnimatedSprite2D")
metadata/_custom_type_script = "uid://bvbc0n0pslq7p"
[node name="AnimatedSprite2D" type="AnimatedSprite2D" parent="." unique_id=410999609]
rotation = 4.712389
sprite_frames = SubResource("SpriteFrames_shhro")

View File

@@ -1,34 +1,16 @@
extends AbstractPrey2D
@onready var sprite = $AnimatedSprite2D
@onready var fsm = $StateMachine
@onready var wrapper: WrappingManager = $WrappingManager
@onready var sprite: AnimatedSprite2D = $AnimatedSprite2D
@onready var fsm: StateMachine = $StateMachine
@export var speed = 0.5
var desired_rotation: float = self.rotation
# Mirrored sprites for periodic boundary
var mirrorSprite1: Node2D
var mirrorSprite2: Node2D
var mirrorSprite3: Node2D
# Called when the node enters the scene tree for the first time.
func _ready() -> void:
health = maxHealth
sprite.play("Healthy")
mirrorSprite1 = sprite.duplicate()
sprite.play("Healthy")
mirrorSprite2 = sprite.duplicate()
sprite.play("Healthy")
mirrorSprite3 = sprite.duplicate()
sprite.play("Healthy")
add_child(mirrorSprite1)
add_child(mirrorSprite2)
add_child(mirrorSprite3)
# Called every frame. 'delta' is the elapsed time since the previous frame.
@@ -36,9 +18,6 @@ func _process(delta: float) -> void:
# smoothly rotate
if self.rotation != self.desired_rotation:
self.rotation = lerp_angle(self.rotation, self.desired_rotation, clampf(4 * delta, 0, 1))
# Boundary mirroring
_handle_wrapping()
func _physics_process(delta: float) -> void:
pass
@@ -60,94 +39,13 @@ func handle_damage(dmg: int, src: Node) -> void:
func die() -> void:
sprite.play("Dying")
mirrorSprite1.play("Dying")
mirrorSprite2.play("Dying")
mirrorSprite3.play("Dying")
wrapper.play_sprite("Dying")
super.die()
func become_injured() -> void:
sprite.play("Injured")
mirrorSprite1.play("Injured")
mirrorSprite2.play("Injured")
mirrorSprite3.play("Injured")
wrapper.play_sprite("Injured")
func _on_sight_body_entered(body: Node2D) -> void:
if body.is_in_group("predator") or (health < maxHealth and body.is_in_group("player")):
fsm.transition_to_next_state(fsm.States.FLEEING, {"threat": body})
# Mirroring table:
# |---|---|---|---|
# | 4 | 3 | 4 | 3 |
# |---|===|===|---|
# | 1 ǁ 2 | 1 ǁ 2 |
# |---ǁ---|---ǁ---|
# | 4 ǁ 3 | 4 ǁ 3 |
# |---|===|===|---|
# | 1 | 2 | 1 | 2 |
# |---|---|---|---|
# If less than viewport size away from an edge, mirror over that edge (for seamless boundary)
# NOTE: For this to look correctly the camera size should be smaller than half the screen port (in
# any one dimension. Ideally, the difference between camera size and half the screen port is
# at least the size of the prey sprite)
func _handle_wrapping():
mirrorSprite1.visible = false
mirrorSprite2.visible = false
mirrorSprite3.visible = false
# TODO: Assume viewport size << screen size and only draw according to GameManager.viewport_size
# Find corresponding section of the screen
if position.x < GameManager.screen_size.x/2 and position.y < GameManager.screen_size.y/2:
# 2
mirrorSprite1.visible = true
mirrorSprite2.visible = true
mirrorSprite3.visible = true
# Right
mirrorSprite1.global_position = global_position + Vector2(GameManager.screen_size.x, 0)
# Diag
mirrorSprite3.global_position = global_position + Vector2(GameManager.screen_size.x, GameManager.screen_size.y)
# Bottom
mirrorSprite2.global_position = global_position + Vector2(0, GameManager.screen_size.y)
elif position.x < GameManager.screen_size.x/2:
# 3
mirrorSprite1.visible = true
mirrorSprite2.visible = true
mirrorSprite3.visible = true
# Top
mirrorSprite1.global_position = global_position + Vector2(0, - GameManager.screen_size.y)
# Diag
mirrorSprite2.global_position = global_position + Vector2(GameManager.screen_size.x, - GameManager.screen_size.y)
# Right
mirrorSprite3.global_position = global_position + Vector2(GameManager.screen_size.x, 0)
elif position.y < GameManager.screen_size.y/2:
# 1
mirrorSprite1.visible = true
mirrorSprite2.visible = true
mirrorSprite3.visible = true
# Left
mirrorSprite1.global_position = global_position + Vector2(- GameManager.screen_size.x, 0)
# Bottom
mirrorSprite2.global_position = global_position + Vector2(0, GameManager.screen_size.y)
# Diag
mirrorSprite3.global_position = global_position + Vector2(- GameManager.screen_size.x, GameManager.screen_size.y)
else:
# 4
mirrorSprite1.visible = true
mirrorSprite2.visible = true
mirrorSprite3.visible = true
# Left
mirrorSprite1.global_position = global_position + Vector2(- GameManager.screen_size.x, 0)
# Diag
mirrorSprite2.global_position = global_position + Vector2(- GameManager.screen_size.x, - GameManager.screen_size.y)
# Top
mirrorSprite3.global_position = global_position + Vector2(0, - GameManager.screen_size.y)

View File

@@ -3,6 +3,7 @@
[ext_resource type="PackedScene" uid="uid://bvsdg1v3ksixy" path="res://shared/npc/prey2D.tscn" id="1_qvulj"]
[ext_resource type="Script" uid="uid://bgossk6xo31gi" path="res://molecular/prey/nucleotide_prey.gd" id="2_0227s"]
[ext_resource type="Texture2D" uid="uid://bhcb5g7g7um8" path="res://molecular/assets/prey/prey-dying-frame0.png" id="2_lkj7f"]
[ext_resource type="Script" uid="uid://bvbc0n0pslq7p" path="res://shared/wrapping_manager.gd" id="3_lecx4"]
[ext_resource type="Texture2D" uid="uid://bxn11avw7dykl" path="res://molecular/assets/prey/prey-dying-frame1.png" id="3_svqyr"]
[ext_resource type="Texture2D" uid="uid://ctkehsavw6ghx" path="res://molecular/assets/prey/prey-healthy-frame0.png" id="4_ee1gb"]
[ext_resource type="Texture2D" uid="uid://uy28y3mkk6nt" path="res://molecular/assets/prey/prey-healthy-frame1.png" id="5_ae5nf"]
@@ -57,20 +58,24 @@ script = ExtResource("2_0227s")
speed = 0.5
maxHealth = 20
[node name="AnimatedSprite2D" type="AnimatedSprite2D" parent="." index="0" unique_id=788182944]
[node name="WrappingManager" type="Node" parent="." index="0" unique_id=407460873 node_paths=PackedStringArray("sprite")]
script = ExtResource("3_lecx4")
sprite = NodePath("../AnimatedSprite2D")
metadata/_custom_type_script = "uid://bvbc0n0pslq7p"
[node name="AnimatedSprite2D" type="AnimatedSprite2D" parent="." index="1" unique_id=788182944]
rotation = 1.5707964
scale = Vector2(0.1, 0.1)
sprite_frames = SubResource("SpriteFrames_66x8p")
animation = &"Healthy"
[node name="CollisionPolygon2D" parent="." index="1"]
[node name="CollisionPolygon2D" parent="." index="2"]
light_mask = 2
visibility_layer = 2
position = Vector2(6.929083, 3.0664783)
rotation = 0.474154
polygon = PackedVector2Array(-8.831272, -2.3390446, -5.7760534, -2.3993049, -4.0230684, 0.41277456, -5.8890305, 2.9948444, -8.862037, 2.9326901, -10.268076, 0.28495264)
[node name="StateMachine" type="Node" parent="." index="2" unique_id=445822474 node_paths=PackedStringArray("initial_state")]
[node name="StateMachine" type="Node" parent="." index="3" unique_id=445822474 node_paths=PackedStringArray("initial_state")]
script = ExtResource("9_xxtgy")
initial_state = NodePath("Idle")
@@ -89,7 +94,7 @@ script = ExtResource("12_ubfhk")
[node name="Timer" type="Timer" parent="StateMachine/Idle" index="0" unique_id=1050348256]
one_shot = true
[node name="Sight" type="Area2D" parent="." index="3" unique_id=1773478588]
[node name="Sight" type="Area2D" parent="." index="4" unique_id=1773478588]
collision_layer = 0
collision_mask = 7

View File

@@ -0,0 +1,6 @@
[gd_scene format=3 uid="uid://dbgqratyxesm6"]
[ext_resource type="Script" uid="uid://bvbc0n0pslq7p" path="res://shared/wrapping_manager.gd" id="1_n7cdp"]
[node name="WrappingManager" type="Node" unique_id=492173693]
script = ExtResource("1_n7cdp")

View File

@@ -0,0 +1,82 @@
class_name WrappingManager extends Node
@export var sprite: AnimatedSprite2D
# Mirrored sprites for periodic boundary
var mirrorSprite1: Node2D
var mirrorSprite2: Node2D
var mirrorSprite3: Node2D
# Called when the node enters the scene tree for the first time.
func _ready() -> void:
await owner.ready
mirrorSprite1 = sprite.duplicate()
mirrorSprite2 = sprite.duplicate()
mirrorSprite3 = sprite.duplicate()
owner.add_child(mirrorSprite1)
owner.add_child(mirrorSprite2)
owner.add_child(mirrorSprite3)
_handle_wrapping()
func play_sprite(anim: String) -> void:
mirrorSprite1.play(anim)
mirrorSprite2.play(anim)
mirrorSprite3.play(anim)
func _process(delta: float) -> void:
_handle_wrapping()
# Mirroring table:
# |---|---|---|---|
# | 4 | 3 | 4 | 3 |
# |---|===|===|---|
# | 1 ǁ 2 | 1 ǁ 2 |
# |---ǁ---|---ǁ---|
# | 4 ǁ 3 | 4 ǁ 3 |
# |---|===|===|---|
# | 1 | 2 | 1 | 2 |
# |---|---|---|---|
# If less than viewport size away from an edge, mirror over that edge (for seamless boundary)
# NOTE: For this to look correctly the camera size should be smaller than half the screen port (in
# any one dimension. Ideally, the difference between camera size and half the screen port is
# at least the size of the prey sprite)
func _handle_wrapping():
# TODO: Assume viewport size << screen size and only draw according to GameManager.viewport_size
# Find corresponding section of the screen
if owner.position.x < GameManager.screen_size.x/2 and owner.position.y < GameManager.screen_size.y/2:
# Right
mirrorSprite1.global_position = owner.global_position + Vector2(GameManager.screen_size.x, 0)
# Diag
mirrorSprite3.global_position = owner.global_position + Vector2(GameManager.screen_size.x, GameManager.screen_size.y)
# Bottom
mirrorSprite2.global_position = owner.global_position + Vector2(0, GameManager.screen_size.y)
elif owner.position.x < GameManager.screen_size.x/2:
# Top
mirrorSprite1.global_position = owner.global_position + Vector2(0, - GameManager.screen_size.y)
# Diag
mirrorSprite2.global_position = owner.global_position + Vector2(GameManager.screen_size.x, - GameManager.screen_size.y)
# Right
mirrorSprite3.global_position = owner.global_position + Vector2(GameManager.screen_size.x, 0)
elif owner.position.y < GameManager.screen_size.y/2:
# Left
mirrorSprite1.global_position = owner.global_position + Vector2(- GameManager.screen_size.x, 0)
# Bottom
mirrorSprite2.global_position = owner.global_position + Vector2(0, GameManager.screen_size.y)
# Diag
mirrorSprite3.global_position = owner.global_position + Vector2(- GameManager.screen_size.x, GameManager.screen_size.y)
else:
# Left
mirrorSprite1.global_position = owner.global_position + Vector2(- GameManager.screen_size.x, 0)
# Diag
mirrorSprite2.global_position = owner.global_position + Vector2(- GameManager.screen_size.x, - GameManager.screen_size.y)
# Top
mirrorSprite3.global_position = owner.global_position + Vector2(0, - GameManager.screen_size.y)

View File

@@ -0,0 +1 @@
uid://bvbc0n0pslq7p