mirror of
https://github.com/Rundll86/Dog-Lynx-And-HCN.git
synced 2026-05-27 22:41:56 +08:00
feat(战斗系统): 添加小鸡冲刺攻击技能及相关特效
实现小鸡的冲刺攻击能力,包括: 1. 新增ChickSprint子弹类型及场景 2. 为EntityBase添加拖尾粒子效果 3. 添加攻击蓄力特效和音效 4. 调整小鸡的攻击冷却时间和冲刺倍率 5. 优化TickTool工具类添加until方法 6. 修改世界背景z-index避免遮挡 调整战斗平衡性: 1. 降低默认冲刺倍率 2. 修改测试波次配置 3. 增加新的攻击方式选项
This commit is contained in:
@@ -7,6 +7,11 @@
|
||||
[node name="EffectBase" type="Node2D"]
|
||||
script = ExtResource("1_pt2rk")
|
||||
|
||||
[node name="sounds" type="Node2D" parent="."]
|
||||
unique_name_in_owner = true
|
||||
|
||||
[node name="spawn" type="AudioStreamPlayer2D" parent="sounds"]
|
||||
|
||||
[node name="particles" type="GPUParticles2D" parent="."]
|
||||
unique_name_in_owner = true
|
||||
amount = 30
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
[gd_scene load_steps=18 format=3 uid="uid://cvogxi7mktumf"]
|
||||
[gd_scene load_steps=27 format=3 uid="uid://cvogxi7mktumf"]
|
||||
|
||||
[ext_resource type="Script" path="res://scripts/Statemachine/EntityBase.gd" id="1_mvol6"]
|
||||
[ext_resource type="Texture2D" uid="uid://dwwpkn4q07ja2" path="res://icon.svg" id="2_7lpu0"]
|
||||
@@ -169,6 +169,49 @@ _data = {
|
||||
"hurt": SubResource("Animation_wl2we")
|
||||
}
|
||||
|
||||
[sub_resource type="Curve" id="Curve_cs3iy"]
|
||||
_data = [Vector2(0, 1), 0.0, 0.0, 0, 0, Vector2(1, 0), 0.0, 0.0, 0, 0]
|
||||
point_count = 2
|
||||
|
||||
[sub_resource type="CurveTexture" id="CurveTexture_r5gvu"]
|
||||
curve = SubResource("Curve_cs3iy")
|
||||
|
||||
[sub_resource type="Curve" id="Curve_uf1fy"]
|
||||
_data = [Vector2(0, 1), 0.0, 0.0, 0, 0, Vector2(1, 0), 0.0, 0.0, 0, 0]
|
||||
point_count = 2
|
||||
|
||||
[sub_resource type="CurveTexture" id="CurveTexture_cofpe"]
|
||||
curve = SubResource("Curve_uf1fy")
|
||||
|
||||
[sub_resource type="Gradient" id="Gradient_nkkgg"]
|
||||
colors = PackedColorArray(1, 0, 0, 1, 1, 0.84375, 0, 1)
|
||||
|
||||
[sub_resource type="GradientTexture1D" id="GradientTexture1D_j74g5"]
|
||||
gradient = SubResource("Gradient_nkkgg")
|
||||
|
||||
[sub_resource type="Gradient" id="Gradient_m6h1v"]
|
||||
colors = PackedColorArray(1, 1, 1, 1, 0, 0, 0, 1)
|
||||
|
||||
[sub_resource type="GradientTexture1D" id="GradientTexture1D_j8vyx"]
|
||||
gradient = SubResource("Gradient_m6h1v")
|
||||
|
||||
[sub_resource type="ParticleProcessMaterial" id="ParticleProcessMaterial_kndb2"]
|
||||
particle_flag_disable_z = true
|
||||
emission_shape = 1
|
||||
emission_sphere_radius = 50.0
|
||||
angle_min = 1.07288e-05
|
||||
angle_max = 360.0
|
||||
angle_curve = SubResource("CurveTexture_cofpe")
|
||||
direction = Vector3(-1, 0, 0)
|
||||
spread = 15.0
|
||||
initial_velocity_max = 100.0
|
||||
gravity = Vector3(0, 0, 0)
|
||||
scale_min = 5.0
|
||||
scale_max = 15.0
|
||||
color_ramp = SubResource("GradientTexture1D_j8vyx")
|
||||
color_initial_ramp = SubResource("GradientTexture1D_j74g5")
|
||||
alpha_curve = SubResource("CurveTexture_r5gvu")
|
||||
|
||||
[sub_resource type="CircleShape2D" id="CircleShape2D_34h7q"]
|
||||
|
||||
[node name="EntityBase" type="CharacterBody2D"]
|
||||
@@ -225,6 +268,12 @@ libraries = {
|
||||
[node name="weapons" type="Node2D" parent="texture"]
|
||||
unique_name_in_owner = true
|
||||
|
||||
[node name="trailParticle" type="GPUParticles2D" parent="texture"]
|
||||
unique_name_in_owner = true
|
||||
z_index = -1
|
||||
amount = 300
|
||||
process_material = SubResource("ParticleProcessMaterial_kndb2")
|
||||
|
||||
[node name="statebar" parent="." instance=ExtResource("2_uje1g")]
|
||||
unique_name_in_owner = true
|
||||
position = Vector2(0, -100)
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
[gd_scene load_steps=4 format=3 uid="uid://dpww053pxchsb"]
|
||||
|
||||
[ext_resource type="PackedScene" uid="uid://crtdkysmnkith" path="res://components/Abstracts/BulletBase.tscn" id="1_hvhrf"]
|
||||
[ext_resource type="Script" path="res://scripts/Contents/Bullets/ChickSprint.gd" id="2_fecvj"]
|
||||
|
||||
[sub_resource type="CircleShape2D" id="CircleShape2D_rirs4"]
|
||||
radius = 63.1269
|
||||
|
||||
[node name="ChickSprint" instance=ExtResource("1_hvhrf")]
|
||||
script = ExtResource("2_fecvj")
|
||||
|
||||
[node name="hitbox" parent="." index="1"]
|
||||
shape = SubResource("CircleShape2D_rirs4")
|
||||
@@ -48,7 +48,6 @@ volume_db = -10.0
|
||||
[node name="texture" parent="." index="1"]
|
||||
position = Vector2(0, -37)
|
||||
sprite_frames = SubResource("SpriteFrames_xji3d")
|
||||
animation = &"walk"
|
||||
|
||||
[node name="normal" type="Node2D" parent="texture/weapons" index="0"]
|
||||
position = Vector2(30, -12)
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
[gd_scene load_steps=9 format=3 uid="uid://bkwy3rwkihf4m"]
|
||||
|
||||
[ext_resource type="PackedScene" uid="uid://bcvuuy2m0pke0" path="res://components/Abstracts/EffectBase.tscn" id="1_gbycc"]
|
||||
[ext_resource type="Texture2D" uid="uid://chqmaeivt84b5" path="res://components/UI/attackstar.svg" id="2_2ws80"]
|
||||
[ext_resource type="AudioStream" uid="uid://cn876dtp1ypqx" path="res://resources/sounds/effect/Collect.wav" id="2_nxkfo"]
|
||||
|
||||
[sub_resource type="Curve" id="Curve_2biku"]
|
||||
_data = [Vector2(0, 0), 0.0, 0.0, 0, 0, Vector2(0.2, 1), 0.0, 0.0, 0, 0, Vector2(0.8, 1), 0.0, 0.0, 0, 0, Vector2(1, 0), 0.0, 0.0, 0, 0]
|
||||
point_count = 4
|
||||
|
||||
[sub_resource type="CurveTexture" id="CurveTexture_77moo"]
|
||||
curve = SubResource("Curve_2biku")
|
||||
|
||||
[sub_resource type="Curve" id="Curve_e8ols"]
|
||||
_data = [Vector2(0, 0), 0.0, 0.0, 0, 0, Vector2(0.2, 1), 0.0, 0.0, 0, 0, Vector2(0.8, 1), 0.0, 0.0, 0, 0, Vector2(1, 0), 0.0, 0.0, 0, 0]
|
||||
point_count = 4
|
||||
|
||||
[sub_resource type="CurveTexture" id="CurveTexture_3oeed"]
|
||||
curve = SubResource("Curve_e8ols")
|
||||
|
||||
[sub_resource type="ParticleProcessMaterial" id="ParticleProcessMaterial_bt5eu"]
|
||||
particle_flag_disable_z = true
|
||||
direction = Vector3(0, -1, 0)
|
||||
initial_velocity_min = 10.0
|
||||
initial_velocity_max = 50.0
|
||||
gravity = Vector3(0, 0, 0)
|
||||
scale_curve = SubResource("CurveTexture_3oeed")
|
||||
alpha_curve = SubResource("CurveTexture_77moo")
|
||||
|
||||
[node name="AttackStar" instance=ExtResource("1_gbycc")]
|
||||
spawnSound = "spawn"
|
||||
|
||||
[node name="spawn" parent="sounds" index="0"]
|
||||
stream = ExtResource("2_nxkfo")
|
||||
volume_db = 10.0
|
||||
|
||||
[node name="particles" parent="." index="1"]
|
||||
amount = 1
|
||||
process_material = SubResource("ParticleProcessMaterial_bt5eu")
|
||||
texture = ExtResource("2_2ws80")
|
||||
@@ -85,7 +85,7 @@ libraries = {
|
||||
}
|
||||
|
||||
[node name="background" type="Sprite2D" parent="."]
|
||||
z_index = -1
|
||||
z_index = -100
|
||||
texture = ExtResource("6_p0nkj")
|
||||
|
||||
[node name="rooster" parent="." groups=["players"] instance=ExtResource("3_5ui6q")]
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="81.9" height="81.9" viewBox="0,0,81.9,81.9"><g transform="translate(-199.05,-139.05)"><g stroke="none" stroke-width="0" stroke-linecap="round" stroke-miterlimit="10"><g><g fill="#ffba47"><path d="M250.00785,180.01989h-20.03499l10.05558,-40.96989l9.9987,40.73811"/><path d="M250.02714,180.21189l-9.9987,40.73811l-10.05558,-40.96989h20.03499"/><path d="M239.98011,190.00785v-20.03499l40.96989,10.05558l-40.73811,9.9987"/><path d="M239.78811,190.02714l-40.73811,-9.9987l40.96989,-10.05558v20.03499"/></g><g fill="#fff06c"><path d="M247.09152,180.01409h-14.19672l7.12535,-29.03112l7.08504,28.86688"/><path d="M247.10519,180.15015l-7.08504,28.86688l-7.12535,-29.03112h14.19672"/><path d="M239.98591,187.09152v-14.19672l29.03112,7.12535l-28.86688,7.08504"/><path d="M239.84985,187.10519l-28.86688,-7.08504l29.03112,-7.12535v14.19672"/></g><g fill="#ffffff"><path d="M241.36303,180.00271h-2.7287l1.36954,-5.57996l1.36179,5.54839"/><path d="M241.36566,180.02886l-1.36179,5.54839l-1.36954,-5.57996h2.7287"/><path d="M239.99729,181.36303v-2.7287l5.57996,1.36954l-5.54839,1.36179"/><path d="M239.97114,181.36566l-5.54839,-1.36179l5.57996,-1.36954v2.7287"/></g></g></g></g></svg><!--rotationCenter:40.950000000000074:40.94999999999999-->
|
||||
|
After Width: | Height: | Size: 1.3 KiB |
@@ -0,0 +1,37 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://chqmaeivt84b5"
|
||||
path="res://.godot/imported/attackstar.svg-b1221cbc7b9ccfacea37ada0859e9b08.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://components/UI/attackstar.svg"
|
||||
dest_files=["res://.godot/imported/attackstar.svg-b1221cbc7b9ccfacea37ada0859e9b08.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
svg/scale=1.0
|
||||
editor/scale_with_editor_scale=false
|
||||
editor/convert_colors_with_editor_theme=false
|
||||
@@ -0,0 +1,11 @@
|
||||
extends BulletBase
|
||||
class_name ChickSprint
|
||||
|
||||
func register():
|
||||
speed = 0
|
||||
damage = 30
|
||||
penerate = 1
|
||||
func ai():
|
||||
PresetsAI.lockLauncher(self, launcher, true)
|
||||
if !launcher.sprinting:
|
||||
tryDestroy()
|
||||
@@ -8,9 +8,11 @@ const laserCount = 4
|
||||
func register():
|
||||
fields[FieldStore.Entity.MAX_HEALTH] = 2000
|
||||
fields[FieldStore.Entity.MOVEMENT_SPEED] = 0.35
|
||||
attackCooldownMap[0] = 2000
|
||||
attackCooldownMap[0] = 500
|
||||
attackCooldownMap[1] = 6000
|
||||
attackCooldownMap[2] = 100
|
||||
attackCooldownMap[3] = 500
|
||||
sprintMultiplier = 60
|
||||
func spawn():
|
||||
texture.play("walk")
|
||||
|
||||
@@ -21,7 +23,8 @@ func ai():
|
||||
elif currentFocusedBoss.position.distance_to(position) < 700:
|
||||
tryAttack(1)
|
||||
else:
|
||||
tryAttack(0)
|
||||
var method = MathTool.randc_from([0, 3])
|
||||
tryAttack(method, method == 3)
|
||||
func attack(type):
|
||||
if type == 0:
|
||||
var weaponPos = findWeaponAnchor("normal")
|
||||
@@ -36,4 +39,11 @@ func attack(type):
|
||||
firepot.global_rotation = target
|
||||
firepot.shot()
|
||||
BulletBase.generate(preload("res://components/Bullets/FireScan.tscn"), self, weaponPos, target)
|
||||
elif type == 3:
|
||||
trailing = true
|
||||
BulletBase.generate(preload("res://components/Bullets/ChickSprint.tscn"), self, position, 0)
|
||||
await trySprint()
|
||||
trailing = false
|
||||
return true
|
||||
func sprint():
|
||||
move((currentFocusedBoss.position - position).normalized() * sprintMultiplier, true)
|
||||
|
||||
@@ -11,8 +11,9 @@ var per: int = 0
|
||||
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, 8, INF, 6),
|
||||
# create(preload("res://components/Characters/Hen.tscn"), 1, 5, false, 0, INF, 1),
|
||||
# create(preload("res://components/Characters/Chick.tscn"), 0, 0, true, 8, INF, 6),
|
||||
create(preload("res://components/Characters/Chick.tscn"), 1, 1, true, 0, INF, 1),
|
||||
]
|
||||
|
||||
static func create(
|
||||
|
||||
@@ -2,12 +2,17 @@ extends Node2D
|
||||
class_name EffectController
|
||||
|
||||
@export var oneShot: bool = true
|
||||
@export var spawnSound: String = ""
|
||||
|
||||
@onready var particles: GPUParticles2D = $"%particles"
|
||||
@onready var sounds = $"%sounds"
|
||||
|
||||
func _ready():
|
||||
particles.emitting = false
|
||||
particles.one_shot = oneShot
|
||||
var sound = sounds.get_node_or_null(spawnSound)
|
||||
if sound and sound.stream:
|
||||
sound.play()
|
||||
func shot():
|
||||
var cloned = particles.duplicate() as GPUParticles2D
|
||||
cloned.emitting = true
|
||||
|
||||
@@ -55,7 +55,7 @@ var inventoryMax = {
|
||||
@export var defaultCooldownUnit: float = 100
|
||||
@export var isBoss: bool = false
|
||||
@export var displayName: String = "未知实体"
|
||||
@export var sprintMultiplier: float = 4
|
||||
@export var sprintMultiplier: float = 3
|
||||
@export var drops: Array[ItemStore.ItemType] = []
|
||||
@export var dropCounts: Array[Vector2] = []
|
||||
@export var appleCount: Vector2i = Vector2(0, 2) # 死亡后掉落的苹果数量
|
||||
@@ -67,15 +67,18 @@ var inventoryMax = {
|
||||
@onready var sounds: Node2D = $"%sounds"
|
||||
@onready var hurtAnimator: AnimationPlayer = $"%hurtAnimator"
|
||||
@onready var damageAnchor: Node2D = $"%damageAnchor"
|
||||
@onready var trailParticle: GPUParticles2D = $"%trailParticle"
|
||||
var statebar: EntityStateBar
|
||||
|
||||
var health: float = 0
|
||||
var energy: float = 0
|
||||
var sprinting: bool = false
|
||||
var trailing: bool = false
|
||||
|
||||
var lastDirection: int = 1
|
||||
var lastAttack: int = 0
|
||||
var currentFocusedBoss: EntityBase = null
|
||||
var charginup: bool = false
|
||||
|
||||
func _ready():
|
||||
register()
|
||||
@@ -127,10 +130,11 @@ func _physics_process(_delta: float) -> void:
|
||||
sprinting = false
|
||||
else:
|
||||
velocity = Vector2.ZERO
|
||||
if isPlayer() or is_instance_valid(currentFocusedBoss):
|
||||
if (isPlayer() or is_instance_valid(currentFocusedBoss)) and not charginup:
|
||||
ai()
|
||||
move_and_slide()
|
||||
storeEnergy(0.01 * fields.get(FieldStore.Entity.ENERGY_REGENERATION))
|
||||
trailParticle.emitting = trailing
|
||||
|
||||
# 通用方法
|
||||
func applyLevel():
|
||||
@@ -187,16 +191,22 @@ func startCooldown(type: int):
|
||||
if state:
|
||||
lastAttack = WorldManager.getTime()
|
||||
return state
|
||||
func tryAttack(type: int):
|
||||
func tryAttack(type: int, needChargeUp: bool = false):
|
||||
var state = startCooldown(type)
|
||||
if state:
|
||||
if attack(type):
|
||||
if needChargeUp:
|
||||
charginup = true
|
||||
await EffectController.create(preload("res://components/Effects/AttackStar.tscn"), damageAnchor.global_position).shot()
|
||||
charginup = false
|
||||
else:
|
||||
playSound("attack" + str(type))
|
||||
attack(type)
|
||||
return state
|
||||
func trySprint():
|
||||
playSound("sprint")
|
||||
sprint()
|
||||
sprinting = true
|
||||
await TickTool.until(func(): return !sprinting)
|
||||
func tryDie(by: BulletBase):
|
||||
for drop in range(min(len(drops), len(dropCounts))):
|
||||
var item = drops[drop]
|
||||
|
||||
@@ -5,3 +5,6 @@ static func millseconds(ms: int):
|
||||
static func frame(count: int = 1):
|
||||
for i in range(count):
|
||||
await WorldManager.tree.physics_frame
|
||||
static func until(predicate: Callable):
|
||||
while not predicate.call():
|
||||
await frame()
|
||||
|
||||
Reference in New Issue
Block a user