From f52f7cda8eaabb3d9b30ab4c3816a36c223568f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=A8=E8=90=BD=E5=9F=BA=E5=9B=B4=E8=99=BE?= <3161880837@qq.com> Date: Fri, 29 Aug 2025 12:42:44 +0800 Subject: [PATCH] =?UTF-8?q?feat(=E5=AD=90=E5=BC=B9):=20=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E7=B4=AB=E8=89=B2=E6=B0=B4=E6=99=B6=E5=AD=90=E5=BC=B9=E7=9A=84?= =?UTF-8?q?=E7=88=86=E7=82=B8=E6=95=88=E6=9E=9C=E5=92=8C=E9=94=80=E6=AF=81?= =?UTF-8?q?=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit refactor(子弹基类): 重构销毁逻辑防止重复调用 fix(敌人): 调整小鸡boss的出现波次和激光音效 style(场景文件): 整理动画资源顺序 --- components/Abstracts/BulletBase.tscn | 10 ++--- components/Bullets/ChickLaser.tscn | 11 ++++- components/Bullets/FireScan.tscn | 1 + components/Characters/Chick.tscn | 5 ++- ...osion.tscn => PurpleCrystalExplosion.tscn} | 41 ++++++++++--------- scripts/Contents/Bullets/PurpleCrystal.gd | 2 + scripts/Contents/Wave.gd | 2 +- scripts/Statemachine/BulletBase.gd | 24 +++++++---- scripts/Statemachine/EffectController.gd | 9 ++++ 9 files changed, 68 insertions(+), 37 deletions(-) rename components/Effects/{Explosion.tscn => PurpleCrystalExplosion.tscn} (91%) diff --git a/components/Abstracts/BulletBase.tscn b/components/Abstracts/BulletBase.tscn index 872dcff..d8ce8ef 100644 --- a/components/Abstracts/BulletBase.tscn +++ b/components/Abstracts/BulletBase.tscn @@ -4,6 +4,11 @@ [sub_resource type="SpriteFrames" id="SpriteFrames_vypy3"] +[sub_resource type="Animation" id="Animation_oinqg"] +resource_name = "destroy" +length = 0.5 +step = 0.1 + [sub_resource type="Animation" id="Animation_ynxlt"] resource_name = "loop" loop_mode = 1 @@ -24,11 +29,6 @@ tracks/0/keys = { [sub_resource type="Animation" id="Animation_kmogx"] resource_name = "spawn" -[sub_resource type="Animation" id="Animation_oinqg"] -resource_name = "destroy" -length = 0.5 -step = 0.1 - [sub_resource type="AnimationLibrary" id="AnimationLibrary_dxweq"] _data = { "destroy": SubResource("Animation_oinqg"), diff --git a/components/Bullets/ChickLaser.tscn b/components/Bullets/ChickLaser.tscn index b8f627e..a0b7790 100644 --- a/components/Bullets/ChickLaser.tscn +++ b/components/Bullets/ChickLaser.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=15 format=3 uid="uid://bvri0nv1jrigf"] +[gd_scene load_steps=16 format=3 uid="uid://bvri0nv1jrigf"] [ext_resource type="PackedScene" uid="uid://8gjjfju6p3fh" path="res://components/Bullets/Common/LaserSummoner.tscn" id="1_eb54j"] [ext_resource type="Script" path="res://scripts/Contents/Bullets/ChickLaser.gd" id="2_7g0f0"] @@ -198,6 +198,10 @@ _data = { "spawn": SubResource("Animation_ep0ow") } +[sub_resource type="CapsuleShape2D" id="CapsuleShape2D_sg52j"] +radius = 20.0 +height = 500.0 + [node name="ChickLaser" instance=ExtResource("1_eb54j")] script = ExtResource("2_7g0f0") metadata/_edit_vertical_guides_ = [705.0] @@ -224,3 +228,8 @@ scale = Vector2(0.525, 0.525) libraries = { "": SubResource("AnimationLibrary_7qqtc") } + +[node name="hitbox" parent="." index="1"] +visible = true +position = Vector2(454, 0) +shape = SubResource("CapsuleShape2D_sg52j") diff --git a/components/Bullets/FireScan.tscn b/components/Bullets/FireScan.tscn index 5b754b5..5896e82 100644 --- a/components/Bullets/FireScan.tscn +++ b/components/Bullets/FireScan.tscn @@ -4,6 +4,7 @@ [ext_resource type="Script" path="res://scripts/Contents/Bullets/FireScan.gd" id="2_qprdp"] [sub_resource type="RectangleShape2D" id="RectangleShape2D_4qcsn"] +size = Vector2(50, 50) [node name="FireScan" instance=ExtResource("1_cqre5")] script = ExtResource("2_qprdp") diff --git a/components/Characters/Chick.tscn b/components/Characters/Chick.tscn index 7aedf8c..b423d73 100644 --- a/components/Characters/Chick.tscn +++ b/components/Characters/Chick.tscn @@ -5,7 +5,7 @@ [ext_resource type="Texture2D" uid="uid://7pkplcqqxvnp" path="res://resources/characters/chick/chick-a.svg" id="2_syddq"] [ext_resource type="Texture2D" uid="uid://dj5dvqb8gsedr" path="res://resources/characters/chick/chick-b.svg" id="3_064jv"] [ext_resource type="AudioStream" uid="uid://b7pxuov1id0ho" path="res://resources/sounds/effect/Pew.mp3" id="3_ik1xf"] -[ext_resource type="AudioStream" uid="uid://bx3n11awokuyd" path="res://resources/sounds/effect/Rip.wav" id="4_oyq2p"] +[ext_resource type="AudioStream" uid="uid://b10u6iir6uvqn" path="res://resources/sounds/effect/BigLaser.wav" id="4_mrsne"] [ext_resource type="PackedScene" uid="uid://dny25qkcvtaa2" path="res://components/Effects/FirePot.tscn" id="6_kvx3n"] [sub_resource type="SpriteFrames" id="SpriteFrames_xji3d"] @@ -42,7 +42,8 @@ appleCount = Vector2i(2, 4) stream = ExtResource("3_ik1xf") [node name="attack1" type="AudioStreamPlayer2D" parent="sounds" index="6"] -stream = ExtResource("4_oyq2p") +stream = ExtResource("4_mrsne") +volume_db = -10.0 [node name="texture" parent="." index="1"] position = Vector2(0, -37) diff --git a/components/Effects/Explosion.tscn b/components/Effects/PurpleCrystalExplosion.tscn similarity index 91% rename from components/Effects/Explosion.tscn rename to components/Effects/PurpleCrystalExplosion.tscn index e1d94fd..11cfcc8 100644 --- a/components/Effects/Explosion.tscn +++ b/components/Effects/PurpleCrystalExplosion.tscn @@ -1,6 +1,6 @@ [gd_scene load_steps=14 format=3 uid="uid://dn0iwwnq3n8e2"] -[ext_resource type="PackedScene" uid="uid://bcvuuy2m0pke0" path="res://components/Abstracts/EffectBase.tscn" id="1_1mab3"] +[ext_resource type="PackedScene" uid="uid://bcvuuy2m0pke0" path="res://components/Abstracts/EffectBase.tscn" id="1_sqdwd"] [sub_resource type="Curve" id="Curve_jf41v"] _data = [Vector2(0, 1), 0.0, 0.0, 0, 0, Vector2(1, 0), 0.0, 0.0, 0, 0] @@ -17,7 +17,7 @@ point_count = 2 curve = SubResource("Curve_cxxkf") [sub_resource type="Gradient" id="Gradient_v1v0w"] -colors = PackedColorArray(1, 0, 0, 1, 1, 0.796875, 0, 1) +colors = PackedColorArray(0.3125, 0, 1, 1, 1, 0, 0.867188, 1) [sub_resource type="GradientTexture1D" id="GradientTexture1D_7jhwh"] gradient = SubResource("Gradient_v1v0w") @@ -35,14 +35,28 @@ angle_max = 360.0 angle_curve = SubResource("CurveTexture_fp3qe") direction = Vector3(0, -1, 0) spread = 180.0 -initial_velocity_max = 200.0 -gravity = Vector3(0, 300, 0) +initial_velocity_max = 150.0 +gravity = Vector3(0, 0, 0) scale_min = 3.0 scale_max = 8.0 color_ramp = SubResource("GradientTexture1D_30y3h") color_initial_ramp = SubResource("GradientTexture1D_7jhwh") alpha_curve = SubResource("CurveTexture_8rfho") +[sub_resource type="Animation" id="Animation_rcc6g"] +length = 0.001 +tracks/0/type = "bezier" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath(".:material:shader_parameter/explosion_radius") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"handle_modes": PackedInt32Array(0), +"points": PackedFloat32Array(0, -0.25, 0, 0.25, 0), +"times": PackedFloat32Array(0) +} + [sub_resource type="Animation" id="Animation_pa4et"] resource_name = "explosion" length = 2.0 @@ -59,31 +73,18 @@ tracks/0/keys = { "times": PackedFloat32Array(0, 1, 2) } -[sub_resource type="Animation" id="Animation_rcc6g"] -length = 0.001 -tracks/0/type = "bezier" -tracks/0/imported = false -tracks/0/enabled = true -tracks/0/path = NodePath(".:material:shader_parameter/explosion_radius") -tracks/0/interp = 1 -tracks/0/loop_wrap = true -tracks/0/keys = { -"handle_modes": PackedInt32Array(0), -"points": PackedFloat32Array(0, -0.25, 0, 0.25, 0), -"times": PackedFloat32Array(0) -} - [sub_resource type="AnimationLibrary" id="AnimationLibrary_n7i5u"] _data = { "RESET": SubResource("Animation_rcc6g"), "explosion": SubResource("Animation_pa4et") } -[node name="Explosion" instance=ExtResource("1_1mab3")] +[node name="Explosion" instance=ExtResource("1_sqdwd")] [node name="particles" parent="." index="0"] -amount = 200 +amount = 20 process_material = SubResource("ParticleProcessMaterial_w52ko") +lifetime = 0.5 [node name="animator" parent="stage" index="0"] libraries = { diff --git a/scripts/Contents/Bullets/PurpleCrystal.gd b/scripts/Contents/Bullets/PurpleCrystal.gd index a2894a3..2f5176c 100644 --- a/scripts/Contents/Bullets/PurpleCrystal.gd +++ b/scripts/Contents/Bullets/PurpleCrystal.gd @@ -3,3 +3,5 @@ class_name PurpleCrystal func ai(): PresetsAI.forward(self, rotation) +func destroy(): + EffectController.create(preload("res://components/Effects/PurpleCrystalExplosion.tscn"), global_position).shot() diff --git a/scripts/Contents/Wave.gd b/scripts/Contents/Wave.gd index 5ba8341..045b592 100644 --- a/scripts/Contents/Wave.gd +++ b/scripts/Contents/Wave.gd @@ -12,7 +12,7 @@ static var current: int = 0 static var data: Array[Wave] = [ # entity, minCount, maxCount, isBoss, from, to, per create(preload("res://components/Characters/Hen.tscn"), 1, 5, false, 0, INF, 1), - create(preload("res://components/Characters/Chick.tscn"), 0, 0, true, 0, INF, 5), + create(preload("res://components/Characters/Chick.tscn"), 0, 0, true, 8, INF, 6), ] static func create( diff --git a/scripts/Statemachine/BulletBase.gd b/scripts/Statemachine/BulletBase.gd index 44390d7..f164a35 100644 --- a/scripts/Statemachine/BulletBase.gd +++ b/scripts/Statemachine/BulletBase.gd @@ -23,6 +23,7 @@ class_name BulletBase var launcher: EntityBase = null var spawnInWhen: float = 0 var spawnInWhere: Vector2 = Vector2.ZERO +var destroying: bool = false func _ready(): register() @@ -35,17 +36,19 @@ func _ready(): animator.play("spawn") await animator.animation_finished if freeAfterSpawn: - destroy() + tryDestroy() if autoLoopAnimation: animator.play("loop") func _process(_delta: float) -> void: + if destroying: return if lifeTime > 0: if WorldManager.getTime() - spawnInWhen >= lifeTime: - destroy() + tryDestroy() if lifeDistance > 0: if position.distance_to(spawnInWhere) >= lifeDistance: - destroy() + tryDestroy() func _physics_process(_delta: float) -> void: + if destroying: return if is_instance_valid(launcher) and (launcher.isPlayer() or is_instance_valid(launcher.currentFocusedBoss)): launcher.position -= Vector2.from_angle(rotation) * recoil ai() @@ -61,7 +64,7 @@ func hit(target: Node): if MathTool.rate(fullPenerate()): penerate -= entity.fields[FieldStore.Entity.PENARATION_RESISTANCE] else: - destroy() + tryDestroy() func forward(direction: Vector2): position += direction.normalized() * speed * GameRule.bulletSpeedMultiplier func fullPenerate(): @@ -71,15 +74,20 @@ func timeLived(): func dotLoop(): if await applyDot(): await dotLoop() +func tryDestroy(): + if destroying: return + destroying = true + await destroy() + if autoDestroyAnimation: + animator.play("destroy") + await animator.animation_finished + queue_free() # 抽象方法 func ai(): pass func destroy(): - if autoDestroyAnimation: - animator.play("destroy") - await animator.animation_finished - queue_free() + pass func spawn(): pass func applyDot(): diff --git a/scripts/Statemachine/EffectController.gd b/scripts/Statemachine/EffectController.gd index 9349864..f171683 100644 --- a/scripts/Statemachine/EffectController.gd +++ b/scripts/Statemachine/EffectController.gd @@ -15,3 +15,12 @@ func shot(): if oneShot: await cloned.finished cloned.queue_free() + +static func create(scene: PackedScene, spawnPosition: Vector2, parent: Node2D = null) -> EffectController: + var cloned = scene.instantiate() as EffectController + cloned.global_position = spawnPosition + if parent: + parent.add_child(cloned) + else: + WorldManager.rootNode.add_child(cloned) + return cloned