From 721d38e9d1befdf14d03ea68c5026d5d22a16d9c Mon Sep 17 00:00:00 2001 From: Ruslan Ignatov Date: Tue, 18 Nov 2025 00:31:10 +0300 Subject: [PATCH] Added MinelayerProjectile blast for near ships --- game/entities/weapons/blast_projectile.gd | 9 ++- .../weapons/minelayer/minelayer_projectile.gd | 74 +++++++++++++++++++ .../minelayer/minelayer_projectile.tscn | 27 +++++-- 3 files changed, 103 insertions(+), 7 deletions(-) diff --git a/game/entities/weapons/blast_projectile.gd b/game/entities/weapons/blast_projectile.gd index 0986a16..4a43080 100644 --- a/game/entities/weapons/blast_projectile.gd +++ b/game/entities/weapons/blast_projectile.gd @@ -6,15 +6,20 @@ extends AbstractProjectile func _on_body_entered(body: Node2D) -> void: + var damaged := _try_to_damage_by_blast() + if damaged: + _process_hit_for_projectile(body) + + +func _try_to_damage_by_blast() -> bool: var damaged := false var overlapping_bodies := blast.get_overlapping_bodies() for overlapping_body in overlapping_bodies: var damage := blast.get_damage_to(overlapping_body) if _try_to_damage(overlapping_body, damage): damaged = true + return damaged - if damaged: - _process_hit_for_projectile(body) func _apply_collision_mask() -> void: diff --git a/game/entities/weapons/minelayer/minelayer_projectile.gd b/game/entities/weapons/minelayer/minelayer_projectile.gd index f3055cb..b1ad676 100644 --- a/game/entities/weapons/minelayer/minelayer_projectile.gd +++ b/game/entities/weapons/minelayer/minelayer_projectile.gd @@ -5,7 +5,32 @@ extends BlastProjectile @export var deceleration : int +@onready var sprite_on := $Sprite2D_On +@onready var sprite_off := $Sprite2D_Off @onready var livetime_timer := $LivetimeTimer +@onready var sprite_on_timer := $SpriteOnTimer +@onready var sprite_off_timer := $SpriteOffTimer + + +const OFF_TIMES = [ + 1.0, 1.0, 0.5, 0.25, 0.05, 0.05, 0.05, 0.05, 0.05, +] +const ON_TIME = 0.05 + + +enum Sprite { + ON, + OFF, +} + + +var _bodies_inside: Array[Node2D] = [] +var current_off_time_index := 0 + + +func _ready() -> void: + _switch_sprite(Sprite.OFF) + super._ready() func _physics_process(delta: float) -> void: @@ -23,3 +48,52 @@ func _process_acceleration(delta: float) -> void: func _on_livetime_timer_timeout() -> void: queue_free() + + +func _on_blast_body_entered(body: Node2D) -> void: + _bodies_inside.append(body) + _switch_sprite(Sprite.ON) + if sprite_on_timer.is_stopped() and sprite_off_timer.is_stopped(): + sprite_on_timer.start(ON_TIME) + + +func _on_blast_body_exited(body: Node2D) -> void: + if not body in _bodies_inside: return + + _bodies_inside.erase(body) + + if _bodies_inside.size() == 0: + _reset() + + +func _on_sprite_on_timer_timeout() -> void: + current_off_time_index += 1 + + if current_off_time_index >= OFF_TIMES.size(): + _try_to_damage_by_blast() + _process_hit_for_projectile(null) + else: + _switch_sprite(Sprite.OFF) + sprite_off_timer.start(OFF_TIMES[current_off_time_index]) + + +func _on_sprite_off_timer_timeout() -> void: + _switch_sprite(Sprite.ON) + sprite_on_timer.start(ON_TIME) + + +func _reset() -> void: + _switch_sprite(Sprite.OFF) + sprite_on_timer.stop() + sprite_off_timer.stop() + current_off_time_index = 0 + + +func _switch_sprite(sprite: Sprite) -> void: + match sprite: + Sprite.ON: + sprite_on.show() + sprite_off.hide() + Sprite.OFF: + sprite_on.hide() + sprite_off.show() diff --git a/game/entities/weapons/minelayer/minelayer_projectile.tscn b/game/entities/weapons/minelayer/minelayer_projectile.tscn index 1b7b553..22e62c7 100644 --- a/game/entities/weapons/minelayer/minelayer_projectile.tscn +++ b/game/entities/weapons/minelayer/minelayer_projectile.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=9 format=3 uid="uid://4mkklqt1g14f"] +[gd_scene load_steps=10 format=3 uid="uid://4mkklqt1g14f"] [ext_resource type="PackedScene" uid="uid://betr5ry5tc75e" path="res://game/entities/weapons/blast_projectile.tscn" id="1_ufc4r"] [ext_resource type="Script" uid="uid://76swcukelnii" path="res://game/entities/weapons/minelayer/minelayer_projectile.gd" id="2_hwwfa"] @@ -9,6 +9,10 @@ atlas = ExtResource("4_px1i2") region = Rect2(0, 16, 16, 16) +[sub_resource type="AtlasTexture" id="AtlasTexture_px1i2"] +atlas = ExtResource("4_px1i2") +region = Rect2(16, 16, 16, 16) + [sub_resource type="CircleShape2D" id="CircleShape2D_ufc4r"] radius = 7.0 @@ -27,19 +31,32 @@ script = ExtResource("2_hwwfa") deceleration = 100 speed = 200 -[node name="Sprite2D" type="Sprite2D" parent="." index="0"] +[node name="Sprite2D_Off" type="Sprite2D" parent="." index="0"] texture = SubResource("AtlasTexture_ckqco") -[node name="CollisionShape2D" parent="." index="1"] +[node name="Sprite2D_On" type="Sprite2D" parent="." index="1"] +texture = SubResource("AtlasTexture_px1i2") + +[node name="CollisionShape2D" parent="." index="2"] shape = SubResource("CircleShape2D_ufc4r") -[node name="Blast" parent="." index="3"] +[node name="Blast" parent="." index="4"] damage = SubResource("Resource_ckqco") shape = SubResource("CircleShape2D_px1i2") -[node name="LivetimeTimer" type="Timer" parent="." index="4"] +[node name="LivetimeTimer" type="Timer" parent="." index="5"] wait_time = 60.0 one_shot = true autostart = true +[node name="SpriteOnTimer" type="Timer" parent="." index="6"] +one_shot = true + +[node name="SpriteOffTimer" type="Timer" parent="." index="7"] +one_shot = true + +[connection signal="body_entered" from="Blast" to="." method="_on_blast_body_entered"] +[connection signal="body_exited" from="Blast" to="." method="_on_blast_body_exited"] [connection signal="timeout" from="LivetimeTimer" to="." method="_on_livetime_timer_timeout"] +[connection signal="timeout" from="SpriteOnTimer" to="." method="_on_sprite_on_timer_timeout"] +[connection signal="timeout" from="SpriteOffTimer" to="." method="_on_sprite_off_timer_timeout"]