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

feat(战斗系统): 添加招架球子弹和循环计时器功能

实现新的招架球子弹类型(ParryBallBullet)及其相关行为
新增CycleTimer类用于管理子弹的周期性运动
在EntityBase中添加计时器管理功能,支持创建和应用周期计时器
添加招架球子弹的资源文件和相关配置
This commit is contained in:
2026-03-17 22:58:04 +08:00
parent c5cfe236da
commit ac643e426b
7 changed files with 120 additions and 2 deletions
+10
View File
@@ -10,3 +10,13 @@ func hitBullet(bullet: BulletBase):
eff.modulate = bullet.modulate.blend(bullet.texture.modulate)
eff.shot()
bullet.tryDestroy()
var cycler = launcher.getOrCreateCycleTimer("parry", 2000, 100)
if len(cycler.bullets) < 5:
for b in BulletBase.generate(
ComponentManager.getBullet("ParryBall"),
launcher,
position,
0
):
if b is ParryBallBullet:
pass
+11
View File
@@ -0,0 +1,11 @@
extends BulletBase
class_name ParryBallBullet
var cycler: CycleTimer
func spawn():
cycler = launcher.getOrCreateCycleTimer("parry")
cycler.host(self )
func ai():
PresetBulletAI.selfRotate(self , 5)
hitbox.disabled = !launcher.sprinting
@@ -0,0 +1 @@
uid://6to3ptrfe6dr
+23
View File
@@ -0,0 +1,23 @@
class_name CycleTimer
@export var period: float = 1
var startTime: float = 0
var running: bool = false
var distance: float = 200
var bullets: Array[BulletBase] = []
func start():
startTime = Time.get_ticks_msec()
running = true
func lifetime():
return Time.get_ticks_msec() - startTime
func periodPercent(count: int):
return lifetime() / period * deg_to_rad(360) - deg_to_rad(360.0 * count / len(bullets))
func apply():
bullets = bullets.filter(is_instance_valid)
for index in len(bullets):
var bullet = bullets[index]
bullet.position = bullet.launcher.position + Vector2.from_angle(periodPercent(index)) * distance
func host(bullet: BulletBase):
bullets.append(bullet)
+1
View File
@@ -0,0 +1 @@
uid://b3k5h2vs6uwi2
+14 -2
View File
@@ -112,6 +112,7 @@ var weaponBag: Array[String] = []
var canRunAi: bool = true
var currentStage: int = 0
var spawnTime: float = 0
var cycleTimers: Dictionary = {}
func _ready():
if useStatic:
@@ -199,8 +200,19 @@ func _physics_process(_delta: float) -> void:
move_and_slide()
storeEnergy(randf_range(0.01, 0.05 + fields.get(FieldStore.Entity.ENERGY_REGENERATION) - 1), true)
trailParticle.emitting = trailing
for cycler in cycleTimers.values():
if cycler is CycleTimer:
cycler.apply()
# 通用方法
func getOrCreateCycleTimer(timerName: String, period: float = 1000, distance: float = 200, start: bool = true) -> CycleTimer:
if !cycleTimers.has(timerName):
var newTimer = CycleTimer.new()
newTimer.period = period
newTimer.distance = distance
if start: newTimer.start()
cycleTimers[timerName] = newTimer
return cycleTimers[timerName]
func initHealth(maxHealth: float):
fields[FieldStore.Entity.MAX_HEALTH] = maxHealth
health = maxHealth
@@ -276,7 +288,7 @@ func bulletHit(bullet: BulletBase, crit: bool):
healthChanged.emit(health)
DamageLabel.create(damage, crit || perfectMiss, damageAnchor.global_position + MathTool.sampleInCircle(GameRule.damageLabelSpawnOffset))
if isBoss and bullet.launcher.isPlayer():
bullet.launcher.setBoss(self)
bullet.launcher.setBoss(self )
if health <= 0:
if isBoss:
bullet.launcher.storeEnergy(energy * 0.35)
@@ -324,7 +336,7 @@ func tryAttack(type: int, needChargeUp: bool = false):
await EffectController.create(ComponentManager.getEffect("AttackStar"), damageAnchor.global_position).shot()
charginup = false
if isPlayer() and !isSummon():
if await weapon.tryAttack(self):
if await weapon.tryAttack(self ):
weapon.playSound("attack")
else:
if await attack(type):