1
1
mirror of https://github.com/Rundll86/Dog-Lynx-And-HCN.git synced 2026-05-30 07:51:54 +08:00

feat(子弹): 添加紫色水晶子弹的爆炸效果和销毁逻辑

refactor(子弹基类): 重构销毁逻辑防止重复调用
fix(敌人): 调整小鸡boss的出现波次和激光音效
style(场景文件): 整理动画资源顺序
This commit is contained in:
2025-08-29 12:42:44 +08:00
parent 2a8ea238ad
commit f52f7cda8e
9 changed files with 68 additions and 37 deletions
+5 -5
View File
@@ -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"),
+10 -1
View File
@@ -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")
+1
View File
@@ -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")
+3 -2
View File
@@ -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)
@@ -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 = {
@@ -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()
+1 -1
View File
@@ -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(
+16 -8
View File
@@ -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():
+9
View File
@@ -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