From cc0899a26423c7e59d5634012812be4cbebdc5ce 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: Sat, 28 Mar 2026 08:29:22 +0800 Subject: [PATCH] =?UTF-8?q?feat(=E6=88=98=E6=96=97=E7=B3=BB=E7=BB=9F):=20?= =?UTF-8?q?=E4=BC=98=E5=8C=96Kernyr=E8=A7=92=E8=89=B2=E7=9A=84=E6=94=BB?= =?UTF-8?q?=E5=87=BB=E9=80=BB=E8=BE=91=E5=92=8C=E7=A2=B0=E6=92=9E=E5=BD=A2?= =?UTF-8?q?=E7=8A=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 将Yangyi子弹的碰撞形状从矩形改为圆形 - 为EntityBase添加攻击互斥状态管理 - 调整Kernyr的攻击冷却时间和互斥规则 - 重写Kernyr的AI攻击逻辑和特殊攻击2的实现 --- components/Bullets/Yangyi.tscn | 6 +++--- scripts/Contents/Characters/Kernyr.gd | 31 ++++++++++++++++++++------- scripts/Statemachine/EntityBase.gd | 9 ++++++++ 3 files changed, 35 insertions(+), 11 deletions(-) diff --git a/components/Bullets/Yangyi.tscn b/components/Bullets/Yangyi.tscn index f172b56..c407208 100644 --- a/components/Bullets/Yangyi.tscn +++ b/components/Bullets/Yangyi.tscn @@ -53,8 +53,8 @@ _data = { &"loop": SubResource("Animation_c3irh") } -[sub_resource type="RectangleShape2D" id="RectangleShape2D_x2cof"] -size = Vector2(48, 48) +[sub_resource type="CircleShape2D" id="CircleShape2D_c3irh"] +radius = 43.011627 [sub_resource type="Curve" id="Curve_c3irh"] _data = [Vector2(0, 0.8), 0.0, 0.0, 0, 0, Vector2(1, 0), 0.0, 0.0, 0, 0] @@ -90,7 +90,7 @@ libraries = { } [node name="hitbox" parent="." index="1"] -shape = SubResource("RectangleShape2D_x2cof") +shape = SubResource("CircleShape2D_c3irh") [node name="trail" type="GPUParticles2D" parent="." index="2"] z_index = -1 diff --git a/scripts/Contents/Characters/Kernyr.gd b/scripts/Contents/Characters/Kernyr.gd index 41520ba..70c1e22 100644 --- a/scripts/Contents/Characters/Kernyr.gd +++ b/scripts/Contents/Characters/Kernyr.gd @@ -7,16 +7,17 @@ var attack0State = 0 func register(): fields[FieldStore.Entity.MAX_HEALTH] = 2000 fields[FieldStore.Entity.OFFSET_SHOOT] = 20 - attackCooldownMap[0] = 3000 + attackCooldownMap[0] = 2000 attackCooldownMap[1] = 100 - attackCooldownMap[2] = 1000 + attackCooldownMap[2] = 10000 + attackMutexes = [2] func ai(): - tryAttack(0) - tryAttack(1) - tryAttack(2) - # texture.position = Vector2.from_angle(deg_to_rad(timeLived() / 1000.0 * 360)) * 200 + for i in 3: + tryAttack(i) func attack(type: int): if type == 0: + for i in randi_range(7, 16): + BulletBase.generate(ComponentManager.getBullet("Diamond"), self , position + MathTool.sampleInCircle(20), rotation + deg_to_rad(randf_range(-90, 90))) var states = [ Vector2(-1, 1), Vector2(1, 1), @@ -35,5 +36,19 @@ func attack(type: int): ) attack1Angle += deg_to_rad(360.0 / 20) elif type == 2: - for i in randi_range(7, 16): - BulletBase.generate(ComponentManager.getBullet("Diamond"), self , position + MathTool.sampleInCircle(20), rotation + deg_to_rad(randf_range(-90, 90))) + var anchor = currentFocusedBoss.position + var radius = 600 + await sprintTo(anchor + Vector2(0, -radius), 0.1) + await TickTool.millseconds(2000) + var count = 10.0 + for i in count: + await sprintTo(anchor + Vector2.from_angle(deg_to_rad(i / count * 360.0 - 90)) * radius, 0.5) + for bullet in BulletBase.generate( + ComponentManager.getBullet("Yangyi"), + self , + position, + 0 + ): + if bullet is YangyiBullet: + bullet.look_at(anchor) + await TickTool.millseconds(3000) diff --git a/scripts/Statemachine/EntityBase.gd b/scripts/Statemachine/EntityBase.gd index 5047abe..82cb9b7 100644 --- a/scripts/Statemachine/EntityBase.gd +++ b/scripts/Statemachine/EntityBase.gd @@ -59,6 +59,8 @@ var attackCooldownMap = { var attackCooldowner = { 0: CooldownTimer.new() } +var attackMutexes: Array[int] = [] +var attackingStates: Array[int] = [] var inventory = { ItemStore.ItemType.BASEBALL: 200, ItemStore.ItemType.BASKETBALL: 200, @@ -340,12 +342,19 @@ func tryAttack(type: int, needChargeUp: bool = false): charginup = true await EffectController.create(ComponentManager.getEffect("AttackStar"), damageAnchor.global_position).shot() charginup = false + for attackingState in attackingStates: + if attackingState in attackMutexes: + return false if isPlayer() and !isSummon(): + attackingStates.append(type) if await weapon.tryAttack(self ): weapon.playSound("attack") + attackingStates.erase(type) else: + attackingStates.append(type) if await attack(type): playSound("attack" + str(type)) + attackingStates.erase(type) return state func trySprint(): trailing = true