mirror of
https://github.com/Rundll86/Dog-Lynx-And-HCN.git
synced 2026-05-28 06:51:54 +08:00
feat(武器系统): 重构武器攻击逻辑并添加音效支持
- 将武器攻击逻辑移至Weapon类中,添加tryAttack方法统一处理冷却和能量消耗 - 为武器添加音效支持,包括攻击音效的播放和管理 - 移除子弹生成时的能量消耗检查,改由武器统一处理 - 调整部分武器的属性和配置,如伤害值和冷却时间 - 修复紫水晶子弹的分裂和折射逻辑错误
This commit is contained in:
@@ -29,6 +29,11 @@ theme_override_styles/panel = SubResource("StyleBoxFlat_n2ewr")
|
|||||||
script = ExtResource("1_g802t")
|
script = ExtResource("1_g802t")
|
||||||
metadata/_edit_lock_ = true
|
metadata/_edit_lock_ = true
|
||||||
|
|
||||||
|
[node name="sounds" type="Node2D" parent="."]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
|
||||||
|
[node name="attack" type="AudioStreamPlayer2D" parent="sounds"]
|
||||||
|
|
||||||
[node name="container" type="VBoxContainer" parent="."]
|
[node name="container" type="VBoxContainer" parent="."]
|
||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
theme_override_constants/separation = 10
|
theme_override_constants/separation = 10
|
||||||
|
|||||||
@@ -47,7 +47,6 @@ process_mode = 4
|
|||||||
[node name="PurpleCrystal" parent="weaponStore" index="0" instance=ExtResource("3_ms5sq")]
|
[node name="PurpleCrystal" parent="weaponStore" index="0" instance=ExtResource("3_ms5sq")]
|
||||||
|
|
||||||
[node name="LGBT" parent="weaponStore" index="1" instance=ExtResource("4_pb8qn")]
|
[node name="LGBT" parent="weaponStore" index="1" instance=ExtResource("4_pb8qn")]
|
||||||
debugRebuild = false
|
|
||||||
|
|
||||||
[node name="sprint" parent="sounds" index="0"]
|
[node name="sprint" parent="sounds" index="0"]
|
||||||
stream = ExtResource("4_66s6c")
|
stream = ExtResource("4_66s6c")
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
[gd_scene load_steps=4 format=3 uid="uid://cxabqjo7skxev"]
|
[gd_scene load_steps=5 format=3 uid="uid://cxabqjo7skxev"]
|
||||||
|
|
||||||
[ext_resource type="PackedScene" uid="uid://ckq2cq6m23hq3" path="res://components/Abstracts/WeaponCardBase.tscn" id="1_wrvv5"]
|
[ext_resource type="PackedScene" uid="uid://ckq2cq6m23hq3" path="res://components/Abstracts/WeaponCardBase.tscn" id="1_wrvv5"]
|
||||||
[ext_resource type="Script" path="res://scripts/Contents/Weapons/BigLaser.gd" id="2_gmch0"]
|
[ext_resource type="Script" path="res://scripts/Contents/Weapons/BigLaser.gd" id="2_gmch0"]
|
||||||
[ext_resource type="Texture2D" uid="uid://dy4op6n6vxef3" path="res://resources/bullets/laser-circle/circle.svg" id="2_qe8gb"]
|
[ext_resource type="Texture2D" uid="uid://dy4op6n6vxef3" path="res://resources/bullets/laser-circle/circle.svg" id="2_qe8gb"]
|
||||||
|
[ext_resource type="AudioStream" uid="uid://b10u6iir6uvqn" path="res://resources/sounds/effect/BigLaser.wav" id="4_cb5nh"]
|
||||||
|
|
||||||
[node name="BigLaser" instance=ExtResource("1_wrvv5")]
|
[node name="BigLaser" instance=ExtResource("1_wrvv5")]
|
||||||
script = ExtResource("2_gmch0")
|
script = ExtResource("2_gmch0")
|
||||||
@@ -16,10 +17,14 @@ store = {
|
|||||||
"atk": 35,
|
"atk": 35,
|
||||||
"time": 0.1
|
"time": 0.1
|
||||||
}
|
}
|
||||||
|
storeType = Array[int]([0, 0])
|
||||||
descriptionTemplate = "每$time秒造成$atk点伤害。"
|
descriptionTemplate = "每$time秒造成$atk点伤害。"
|
||||||
needEnergy = 100.0
|
needEnergy = 100.0
|
||||||
cooldown = 6000.0
|
cooldown = 6000.0
|
||||||
|
|
||||||
|
[node name="attack" parent="sounds" index="0"]
|
||||||
|
stream = ExtResource("4_cb5nh")
|
||||||
|
|
||||||
[node name="avatar" parent="container/info" index="0"]
|
[node name="avatar" parent="container/info" index="0"]
|
||||||
texture = ExtResource("2_qe8gb")
|
texture = ExtResource("2_qe8gb")
|
||||||
|
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ store = {
|
|||||||
storeType = Array[int]([2, 0, 0, 1, 0])
|
storeType = Array[int]([2, 0, 0, 1, 0])
|
||||||
descriptionTemplate = "发射$count条,每条间分隔$angle,可追踪$trace秒,效率为$power的带状彩虹,每条造成$atk点伤害。"
|
descriptionTemplate = "发射$count条,每条间分隔$angle,可追踪$trace秒,效率为$power的带状彩虹,每条造成$atk点伤害。"
|
||||||
needEnergy = 150.0
|
needEnergy = 150.0
|
||||||
|
cooldown = 2000.0
|
||||||
|
|
||||||
[node name="avatar" parent="container/info" index="0"]
|
[node name="avatar" parent="container/info" index="0"]
|
||||||
texture = ExtResource("2_ou6jo")
|
texture = ExtResource("2_ou6jo")
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
[gd_scene load_steps=4 format=3 uid="uid://c0n3igy4hucrg"]
|
[gd_scene load_steps=5 format=3 uid="uid://c0n3igy4hucrg"]
|
||||||
|
|
||||||
[ext_resource type="PackedScene" uid="uid://ckq2cq6m23hq3" path="res://components/Abstracts/WeaponCardBase.tscn" id="1_hyubh"]
|
[ext_resource type="PackedScene" uid="uid://ckq2cq6m23hq3" path="res://components/Abstracts/WeaponCardBase.tscn" id="1_hyubh"]
|
||||||
[ext_resource type="Script" path="res://scripts/Contents/Weapons/PurpleCrystal.gd" id="2_0xgcv"]
|
[ext_resource type="Script" path="res://scripts/Contents/Weapons/PurpleCrystal.gd" id="2_0xgcv"]
|
||||||
[ext_resource type="Texture2D" uid="uid://16yhngg3jpun" path="res://resources/weapons/purple-crystal.svg" id="2_wgtcw"]
|
[ext_resource type="Texture2D" uid="uid://16yhngg3jpun" path="res://resources/weapons/purple-crystal.svg" id="2_wgtcw"]
|
||||||
|
[ext_resource type="AudioStream" uid="uid://dclinyhu256xi" path="res://resources/sounds/effect/Low Whoosh.mp3" id="4_16daa"]
|
||||||
|
|
||||||
[node name="PurpleCrystal" instance=ExtResource("1_hyubh")]
|
[node name="PurpleCrystal" instance=ExtResource("1_hyubh")]
|
||||||
offset_right = 208.0
|
offset_bottom = 302.0
|
||||||
offset_bottom = 282.0
|
|
||||||
script = ExtResource("2_0xgcv")
|
script = ExtResource("2_0xgcv")
|
||||||
avatarTexture = ExtResource("2_wgtcw")
|
avatarTexture = ExtResource("2_wgtcw")
|
||||||
displayName = "紫水晶簇"
|
displayName = "紫水晶簇"
|
||||||
@@ -15,6 +15,9 @@ costCounts = Array[int]([50, 10])
|
|||||||
descriptionTemplate = "撞击造成$atk点伤害。"
|
descriptionTemplate = "撞击造成$atk点伤害。"
|
||||||
cooldown = 200.0
|
cooldown = 200.0
|
||||||
|
|
||||||
|
[node name="attack" parent="sounds" index="0"]
|
||||||
|
stream = ExtResource("4_16daa")
|
||||||
|
|
||||||
[node name="avatar" parent="container/info" index="0"]
|
[node name="avatar" parent="container/info" index="0"]
|
||||||
texture = ExtResource("2_wgtcw")
|
texture = ExtResource("2_wgtcw")
|
||||||
|
|
||||||
@@ -22,4 +25,4 @@ texture = ExtResource("2_wgtcw")
|
|||||||
displayName = "紫水晶簇"
|
displayName = "紫水晶簇"
|
||||||
|
|
||||||
[node name="description" parent="container" index="2"]
|
[node name="description" parent="container" index="2"]
|
||||||
text = "撞击造成[color=cyan]10.0[/color]点伤害。"
|
text = "[center]撞击造成[color=cyan]10.0[/color]点伤害。[/center]"
|
||||||
|
|||||||
@@ -11,7 +11,8 @@ func split(index, total, _last):
|
|||||||
launcher,
|
launcher,
|
||||||
position,
|
position,
|
||||||
deg_to_rad(360 / total * index),
|
deg_to_rad(360 / total * index),
|
||||||
true
|
true,
|
||||||
|
isChildRefract
|
||||||
)
|
)
|
||||||
func refract(entity, _index, _total, _last):
|
func refract(entity, _index, _total, _last):
|
||||||
BulletBase.generate(
|
BulletBase.generate(
|
||||||
@@ -19,6 +20,6 @@ func refract(entity, _index, _total, _last):
|
|||||||
launcher,
|
launcher,
|
||||||
position,
|
position,
|
||||||
position.angle_to_point(entity.position) if is_instance_valid(entity) else randf_range(0, deg_to_rad(360)),
|
position.angle_to_point(entity.position) if is_instance_valid(entity) else randf_range(0, deg_to_rad(360)),
|
||||||
false,
|
isChildSplit,
|
||||||
true
|
true
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -2,6 +2,6 @@ extends BulletBase
|
|||||||
class_name Star
|
class_name Star
|
||||||
|
|
||||||
func register():
|
func register():
|
||||||
damage = 1
|
damage = 5
|
||||||
func ai():
|
func ai():
|
||||||
PresetAIs.forward(self, rotation)
|
PresetAIs.forward(self, rotation)
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ class_name BulletBase
|
|||||||
@export var lifeTime: float = -1 # -1表示无限时间
|
@export var lifeTime: float = -1 # -1表示无限时间
|
||||||
@export var indisDamage: bool = false # 是否无差别伤害(不区分敌我)
|
@export var indisDamage: bool = false # 是否无差别伤害(不区分敌我)
|
||||||
@export var canDamageSelf: bool = false # 是否可以伤害发射者
|
@export var canDamageSelf: bool = false # 是否可以伤害发射者
|
||||||
@export var needEnergy: float = 0.0 # 发射时需要消耗的能量
|
|
||||||
@export var autoSpawnAnimation: bool = false
|
@export var autoSpawnAnimation: bool = false
|
||||||
@export var autoLoopAnimation: bool = false
|
@export var autoLoopAnimation: bool = false
|
||||||
@export var autoDestroyAnimation: bool = false
|
@export var autoDestroyAnimation: bool = false
|
||||||
@@ -139,13 +138,12 @@ static func generate(
|
|||||||
var instances = []
|
var instances = []
|
||||||
for i in range(count):
|
for i in range(count):
|
||||||
var instance: BulletBase = bullet.instantiate()
|
var instance: BulletBase = bullet.instantiate()
|
||||||
if launchBy.useEnergy(instance.needEnergy):
|
instance.isChildSplit = asChildSplit
|
||||||
instance.isChildSplit = asChildSplit
|
instance.isChildRefract = asChildRefract
|
||||||
instance.isChildRefract = asChildRefract
|
instance.launcher = launchBy
|
||||||
instance.launcher = launchBy
|
instance.position = spawnPosition
|
||||||
instance.position = spawnPosition
|
instance.rotation = spawnRotation + deg_to_rad(randf_range(-launchBy.fields.get(FieldStore.Entity.OFFSET_SHOOT), launchBy.fields.get(FieldStore.Entity.OFFSET_SHOOT)))
|
||||||
instance.rotation = spawnRotation + deg_to_rad(randf_range(-launchBy.fields.get(FieldStore.Entity.OFFSET_SHOOT), launchBy.fields.get(FieldStore.Entity.OFFSET_SHOOT)))
|
if addToWorld:
|
||||||
if addToWorld:
|
WorldManager.rootNode.call_deferred("add_child", instance)
|
||||||
WorldManager.rootNode.call_deferred("add_child", instance)
|
instances.append(instance)
|
||||||
instances.append(instance)
|
|
||||||
return len(instances)
|
return len(instances)
|
||||||
|
|||||||
@@ -199,7 +199,7 @@ func tryAttack(type: int, needChargeUp: bool = false):
|
|||||||
weapon = weapons[type]
|
weapon = weapons[type]
|
||||||
var state
|
var state
|
||||||
if isPlayer():
|
if isPlayer():
|
||||||
state = weapon.cooldownTimer.start()
|
state = true
|
||||||
else:
|
else:
|
||||||
cooldownTimer.cooldown = attackCooldownMap.get(type, defaultCooldownUnit)
|
cooldownTimer.cooldown = attackCooldownMap.get(type, defaultCooldownUnit)
|
||||||
state = cooldownTimer.start()
|
state = cooldownTimer.start()
|
||||||
@@ -208,13 +208,12 @@ func tryAttack(type: int, needChargeUp: bool = false):
|
|||||||
charginup = true
|
charginup = true
|
||||||
await EffectController.create(preload("res://components/Effects/AttackStar.tscn"), damageAnchor.global_position).shot()
|
await EffectController.create(preload("res://components/Effects/AttackStar.tscn"), damageAnchor.global_position).shot()
|
||||||
charginup = false
|
charginup = false
|
||||||
var done
|
|
||||||
if isPlayer():
|
if isPlayer():
|
||||||
done = weapon.attack(self)
|
if weapon.tryAttack(self):
|
||||||
|
weapon.playSound("attack")
|
||||||
else:
|
else:
|
||||||
done = attack(type)
|
if attack(type):
|
||||||
if done:
|
playSound("attack" + str(type))
|
||||||
playSound("attack" + str(type))
|
|
||||||
return state
|
return state
|
||||||
func trySprint():
|
func trySprint():
|
||||||
trailing = true
|
trailing = true
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ signal selected(applied: bool)
|
|||||||
@onready var descriptionLabel: RichTextLabel = $"%description"
|
@onready var descriptionLabel: RichTextLabel = $"%description"
|
||||||
@onready var costsBox: GridContainer = $"%costs"
|
@onready var costsBox: GridContainer = $"%costs"
|
||||||
@onready var updateButton: Button = $"%updateBtn"
|
@onready var updateButton: Button = $"%updateBtn"
|
||||||
|
@onready var sounds: Node2D = $"%sounds"
|
||||||
|
|
||||||
var cooldownTimer = CooldownTimer.new()
|
var cooldownTimer = CooldownTimer.new()
|
||||||
|
|
||||||
@@ -36,6 +37,8 @@ func _ready():
|
|||||||
apply(UIState.player)
|
apply(UIState.player)
|
||||||
)
|
)
|
||||||
cooldownTimer.cooldown = cooldown
|
cooldownTimer.cooldown = cooldown
|
||||||
|
for i in sounds.get_children():
|
||||||
|
i.process_mode = ProcessMode.PROCESS_MODE_ALWAYS
|
||||||
rebuildInfo()
|
rebuildInfo()
|
||||||
debugRebuild = false # 只能在编辑器里打开
|
debugRebuild = false # 只能在编辑器里打开
|
||||||
func _physics_process(_delta):
|
func _physics_process(_delta):
|
||||||
@@ -99,6 +102,18 @@ func buildDescription():
|
|||||||
return "[center]%s[/center]" % result
|
return "[center]%s[/center]" % result
|
||||||
func readStore(key: String, default: Variant = null):
|
func readStore(key: String, default: Variant = null):
|
||||||
return store.get(key, default)
|
return store.get(key, default)
|
||||||
|
func playSound(sound: String):
|
||||||
|
var body = sounds.get_node_or_null(sound)
|
||||||
|
if body is AudioStreamPlayer2D:
|
||||||
|
var cloned = body.duplicate() as AudioStreamPlayer2D
|
||||||
|
add_child(cloned)
|
||||||
|
cloned.play()
|
||||||
|
await cloned.finished
|
||||||
|
cloned.queue_free()
|
||||||
|
func tryAttack(entity: EntityBase):
|
||||||
|
if cooldownTimer.start():
|
||||||
|
if entity.useEnergy(needEnergy):
|
||||||
|
attack(entity)
|
||||||
|
|
||||||
# 抽象
|
# 抽象
|
||||||
func update(_to: int, _origin: Dictionary, _entity: EntityBase):
|
func update(_to: int, _origin: Dictionary, _entity: EntityBase):
|
||||||
|
|||||||
Reference in New Issue
Block a user