From 171dbb1131bbdaaebe5d9606ee71f6cdbfb4ea4f 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: Fri, 29 Aug 2025 10:50:22 +0800 Subject: [PATCH] =?UTF-8?q?refactor(BulletBase/EntityBase):=20=E9=87=8D?= =?UTF-8?q?=E6=9E=84=E5=AD=90=E5=BC=B9=E5=92=8C=E5=AE=9E=E4=BD=93=E5=B1=9E?= =?UTF-8?q?=E6=80=A7=E7=B3=BB=E7=BB=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 将子弹的fields属性拆分为独立的speed、damage和penerate变量 为所有子弹和实体添加register方法用于初始化属性 统一攻击冷却时间管理为attackCooldownMap 移除FieldStore中不再使用的Bullet相关枚举和映射 --- components/Bullets/Diamond.tscn | 5 ----- scripts/Contents/Bullets/BigLaser.gd | 6 +++++- scripts/Contents/Bullets/Diamond.gd | 2 ++ scripts/Contents/Bullets/FireScan.gd | 7 +++---- scripts/Contents/Bullets/Pencil.gd | 3 +++ scripts/Contents/Bullets/Star.gd | 2 ++ scripts/Contents/Characters/Bear.gd | 15 -------------- scripts/Contents/Characters/Chick.gd | 8 +++++--- scripts/Contents/Characters/Hen.gd | 7 +++---- scripts/Contents/Characters/Rooster.gd | 5 +++-- scripts/Statemachine/BulletBase.gd | 21 ++++++++++--------- scripts/Statemachine/EntityBase.gd | 28 +++++++++++++++++--------- scripts/Tools/FieldStore.gd | 16 --------------- scripts/Tools/WorldManager.gd | 2 +- 14 files changed, 56 insertions(+), 71 deletions(-) diff --git a/components/Bullets/Diamond.tscn b/components/Bullets/Diamond.tscn index 68b8daf..83514b3 100644 --- a/components/Bullets/Diamond.tscn +++ b/components/Bullets/Diamond.tscn @@ -17,11 +17,6 @@ animations = [{ [node name="Diamond" instance=ExtResource("1_8udva")] script = ExtResource("2_yxtyj") -fields = { -0: 10, -1: 2, -2: 0 -} lifeTime = 5000.0 indisDamage = true diff --git a/scripts/Contents/Bullets/BigLaser.gd b/scripts/Contents/Bullets/BigLaser.gd index a9dd037..ca078c0 100644 --- a/scripts/Contents/Bullets/BigLaser.gd +++ b/scripts/Contents/Bullets/BigLaser.gd @@ -1,10 +1,14 @@ extends BulletBase class_name BigLaser # 这个子弹是玩家的超级武器,耗能高,dps也高 +func register(): + speed = 0 + damage = 35 + penerate = 1 func spawn(): CameraManager.shake(5000, 150) # 激光会运行5秒(5000毫秒),期间震屏超高强度 CameraManager.playAnimation("bigLaser") - fields[FieldStore.Bullet.DAMAGE] *= launcher.fields[FieldStore.Entity.ATTACK_SPEED] + damage *= launcher.fields[FieldStore.Entity.ATTACK_SPEED] func ai(): rotation = lerp_angle(rotation, ((get_global_mouse_position() - position).angle()), 0.1) position = launcher.texture.global_position diff --git a/scripts/Contents/Bullets/Diamond.gd b/scripts/Contents/Bullets/Diamond.gd index 10541ca..f3886ad 100644 --- a/scripts/Contents/Bullets/Diamond.gd +++ b/scripts/Contents/Bullets/Diamond.gd @@ -3,6 +3,8 @@ class_name Diamond const traceTime = 2000 +func register(): + damage = 2 func ai(): rotation = lerp_angle(rotation, position.angle_to_point(launcher.currentFocusedBoss.position), 0.1 * clamp((traceTime - timeLived()) / traceTime, 0, INF)) canDamageSelf = !(timeLived() >= traceTime) diff --git a/scripts/Contents/Bullets/FireScan.gd b/scripts/Contents/Bullets/FireScan.gd index a367895..6a1df4a 100644 --- a/scripts/Contents/Bullets/FireScan.gd +++ b/scripts/Contents/Bullets/FireScan.gd @@ -1,10 +1,9 @@ extends BulletBase class_name FireScan -func _ready(): - fields[FieldStore.Bullet.SPEED] = 5 - fields[FieldStore.Bullet.DAMAGE] = 20 - super._ready() +func register(): + speed = 5 + damage = 20 func ai(): forward(Vector2.from_angle(rotation)) diff --git a/scripts/Contents/Bullets/Pencil.gd b/scripts/Contents/Bullets/Pencil.gd index 0ee506f..ff5dc02 100644 --- a/scripts/Contents/Bullets/Pencil.gd +++ b/scripts/Contents/Bullets/Pencil.gd @@ -1,5 +1,8 @@ extends BulletBase +class_name Pencil +func register(): + damage = 20 func spawn(): await TickTool.millseconds(1000) hitbox.disabled = false diff --git a/scripts/Contents/Bullets/Star.gd b/scripts/Contents/Bullets/Star.gd index d78d93e..9bf8478 100644 --- a/scripts/Contents/Bullets/Star.gd +++ b/scripts/Contents/Bullets/Star.gd @@ -1,5 +1,7 @@ extends BulletBase class_name Star +func register(): + damage = 1 func ai(): forward(Vector2.from_angle(rotation)) diff --git a/scripts/Contents/Characters/Bear.gd b/scripts/Contents/Characters/Bear.gd index 8962555..4372dbf 100644 --- a/scripts/Contents/Characters/Bear.gd +++ b/scripts/Contents/Characters/Bear.gd @@ -1,17 +1,2 @@ extends EntityBase class_name Bear - -func ai(): - pass -func attack(type): - if type == 0: - var weaponPos = findWeaponAnchor("normal") - return BulletBase.generate(preload("res://components/Bullets/PurpleCrystal.tscn"), self, weaponPos, (get_global_mouse_position() - weaponPos).angle()) -func sprint(): - move(Vector2( - Input.get_axis("m_left", "m_right"), - Input.get_axis("m_up", "m_down") - ) * sprintMultiplier, true) -func heal(count: float): - health += count - DamageLabel.create(-count, false, damageAnchor.global_position + MathTool.randv2_range(GameRule.damageLabelSpawnOffset)) diff --git a/scripts/Contents/Characters/Chick.gd b/scripts/Contents/Characters/Chick.gd index d274870..f347ee4 100644 --- a/scripts/Contents/Characters/Chick.gd +++ b/scripts/Contents/Characters/Chick.gd @@ -5,10 +5,12 @@ class_name Chick const laserCount = 4 -func _ready(): +func register(): fields[FieldStore.Entity.MAX_HEALTH] = 2000 - fields[FieldStore.Entity.MOVEMENT_SPEED] = 0.1 - super._ready() + fields[FieldStore.Entity.MOVEMENT_SPEED] = 0.35 + attackCooldownMap[0] = 2000 + attackCooldownMap[1] = 3000 + attackCooldownMap[2] = 100 func ai(): move(currentFocusedBoss.position - position) diff --git a/scripts/Contents/Characters/Hen.gd b/scripts/Contents/Characters/Hen.gd index 2f72765..47f2ae6 100644 --- a/scripts/Contents/Characters/Hen.gd +++ b/scripts/Contents/Characters/Hen.gd @@ -1,14 +1,13 @@ extends EntityBase class_name Hen -func _ready(): +func register(): fields[FieldStore.Entity.MAX_HEALTH] = 75 - fields[FieldStore.Entity.MOVEMENT_SPEED] = 0.25 + fields[FieldStore.Entity.MOVEMENT_SPEED] = 0.15 fields[FieldStore.Entity.OFFSET_SHOOT] = 10 - super._ready() func ai(): - cooldownUnit = randi_range(1500, 4000) + attackCooldownMap[0] = randi_range(1500, 4000) move(currentFocusedBoss.position - position) tryAttack(0) func attack(type): diff --git a/scripts/Contents/Characters/Rooster.gd b/scripts/Contents/Characters/Rooster.gd index 5f39481..2bedd3d 100644 --- a/scripts/Contents/Characters/Rooster.gd +++ b/scripts/Contents/Characters/Rooster.gd @@ -1,6 +1,9 @@ extends EntityBase class_name Rooster +func register(): + attackCooldownMap[0] = 200 + attackCooldownMap[1] = 6000 func ai(): texture.play("walk") var direction = Vector2( @@ -11,10 +14,8 @@ func ai(): if direction.length() == 0: texture.play("idle") if Input.is_action_pressed("attack"): - cooldownUnit = 200 tryAttack(0) elif Input.is_action_pressed("attack2"): - cooldownUnit = 6000 tryAttack(1) if Input.is_action_just_pressed("sprint"): trySprint() diff --git a/scripts/Statemachine/BulletBase.gd b/scripts/Statemachine/BulletBase.gd index d2d18c1..c682ee8 100644 --- a/scripts/Statemachine/BulletBase.gd +++ b/scripts/Statemachine/BulletBase.gd @@ -1,11 +1,9 @@ extends Area2D class_name BulletBase -@export var fields = { - FieldStore.Bullet.SPEED: 10, - FieldStore.Bullet.DAMAGE: 10, - FieldStore.Bullet.PENERATE: 0 -} +@export var speed: float = 10.0 +@export var damage: float = 10.0 +@export var penerate: float = 0.0 @export var lifeDistance: float = -1 # -1表示无限距离 @export var lifeTime: float = -1 # -1表示无限时间 @export var indisDamage: bool = false # 是否无差别伤害(不区分敌我) @@ -26,6 +24,7 @@ var spawnInWhen: float = 0 var spawnInWhere: Vector2 = Vector2.ZERO func _ready(): + register() area_entered.connect(hit) spawnInWhen = WorldManager.getTime() spawnInWhere = position @@ -56,16 +55,16 @@ func hit(target: Node): if !canDamageSelf && entity == launcher: return if !indisDamage && !GameRule.allowFriendlyFire: if entity.isPlayer() == launcher.isPlayer(): return - var damage = entity.takeDamage(self, MathTool.rate(launcher.fields.get(FieldStore.Entity.CRIT_RATE) + GameRule.critRateInfluenceByLuckValue * launcher.fields[FieldStore.Entity.LUCK_VALUE])) - succeedToHit(damage) + var damages = entity.takeDamage(self, MathTool.rate(launcher.fields.get(FieldStore.Entity.CRIT_RATE) + GameRule.critRateInfluenceByLuckValue * launcher.fields[FieldStore.Entity.LUCK_VALUE])) + succeedToHit(damages) if MathTool.rate(fullPenerate()): - fields[FieldStore.Bullet.PENERATE] -= entity.fields[FieldStore.Entity.PENARATION_RESISTANCE] + penerate -= entity.fields[FieldStore.Entity.PENARATION_RESISTANCE] else: destroy() func forward(direction: Vector2): - position += direction.normalized() * fields.get(FieldStore.Bullet.SPEED) * GameRule.bulletSpeedMultiplier + position += direction.normalized() * speed * GameRule.bulletSpeedMultiplier func fullPenerate(): - return fields.get(FieldStore.Bullet.PENERATE) + launcher.fields.get(FieldStore.Entity.PENERATE) + GameRule.penerateRateInfluenceByLuckValue * launcher.fields[FieldStore.Entity.LUCK_VALUE] + return penerate + launcher.fields.get(FieldStore.Entity.PENERATE) + GameRule.penerateRateInfluenceByLuckValue * launcher.fields[FieldStore.Entity.LUCK_VALUE] func timeLived(): return WorldManager.getTime() - spawnInWhen func dotLoop(): @@ -82,6 +81,8 @@ func applyDot(): pass func succeedToHit(_dmg: float): pass +func register(): + pass static func generate( bullet: PackedScene, diff --git a/scripts/Statemachine/EntityBase.gd b/scripts/Statemachine/EntityBase.gd index f9e9fe3..c0bcc51 100644 --- a/scripts/Statemachine/EntityBase.gd +++ b/scripts/Statemachine/EntityBase.gd @@ -38,6 +38,9 @@ var fields = { FieldStore.Entity.SAVE_ENERGY: 1, FieldStore.Entity.ENERGY_REGENERATION: 1, } +var attackCooldownMap = { + 0: 100 +} var inventory = { ItemStore.ItemType.BASEBALL: 100, ItemStore.ItemType.BASKETBALL: 100, @@ -49,7 +52,7 @@ var inventoryMax = { ItemStore.ItemType.APPLE: 5, # 最多5个苹果 } -@export var cooldownUnit: float = 100 # 100毫秒每次攻击 +@export var defaultCooldownUnit: float = 100 @export var isBoss: bool = false @export var displayName: String = "未知实体" @export var sprintMultiplier: float = 4 @@ -57,6 +60,7 @@ var inventoryMax = { @export var dropCounts: Array[Vector2] = [] @export var appleCount: Vector2i = Vector2(0, 2) # 死亡后掉落的苹果数量 @export var level: int = 1 # 等级 +@export var sprintEnergy: float = 5 @onready var animatree: AnimationTree = $"%animatree" @onready var texture: AnimatedSprite2D = $"%texture" @@ -75,6 +79,7 @@ var lastAttack: int = 0 var currentFocusedBoss: EntityBase = null func _ready(): + register() var selfStatebar: EntityStateBar = $"%statebar" if isBoss: selfStatebar.hide() @@ -140,7 +145,7 @@ func move(direction: Vector2, isSprinting: bool = false): lastDirection = currentDirection func takeDamage(bullet: BulletBase, crit: bool): hurtAnimator.play("hurt") - var baseDamage: float = bullet.fields.get(FieldStore.Bullet.DAMAGE) * bullet.launcher.fields.get(FieldStore.Entity.DAMAGE_MULTIPILER) * randf_range(1 - GameRule.damageOffset, 1 + GameRule.damageOffset) + var baseDamage: float = bullet.damage * bullet.launcher.fields.get(FieldStore.Entity.DAMAGE_MULTIPILER) * randf_range(1 - GameRule.damageOffset, 1 + GameRule.damageOffset) var damage = baseDamage + baseDamage * int(crit) * fields.get(FieldStore.Entity.CRIT_DAMAGE) if sprinting: playSound("miss") @@ -175,23 +180,24 @@ func useEnergy(value: float): energy -= value energyChanged.emit(energy) return state -func isCooldowned(): - return WorldManager.getTime() - lastAttack >= cooldownUnit / fields.get(FieldStore.Entity.ATTACK_SPEED) -func startCooldown(): - var state = isCooldowned() +func isCooldowned(type: int): + return WorldManager.getTime() - lastAttack >= attackCooldownMap.get(type, defaultCooldownUnit) / fields.get(FieldStore.Entity.ATTACK_SPEED) +func startCooldown(type: int): + var state = isCooldowned(type) if state: lastAttack = WorldManager.getTime() return state func tryAttack(type: int): - var state = startCooldown() + var state = startCooldown(type) if state: if attack(type): playSound("attack" + str(type)) return state func trySprint(): - playSound("sprint") - sprint() - sprinting = true + if useEnergy(sprintEnergy): + playSound("sprint") + sprint() + sprinting = true func tryDie(by: BulletBase): for drop in range(min(len(drops), len(dropCounts))): var item = drops[drop] @@ -250,6 +256,8 @@ func sprint(): func heal(count: float): health += count return count +func register(): + pass static func generate( entity: PackedScene, diff --git a/scripts/Tools/FieldStore.gd b/scripts/Tools/FieldStore.gd index 7fbe2b6..5ce0ce1 100644 --- a/scripts/Tools/FieldStore.gd +++ b/scripts/Tools/FieldStore.gd @@ -101,20 +101,4 @@ static var entityViewCastMap = { Entity.EXTRA_APPLE_MAX: func(entity, _value): return entity.inventoryMax[ItemStore.ItemType.APPLE] , -} - -enum Bullet { - SPEED, - DAMAGE, - PENERATE -} -static var bulletMap = { - Bullet.SPEED: "速度", - Bullet.DAMAGE: "伤害", - Bullet.PENERATE: "穿透" -} -static var bulletMapType = { - Bullet.SPEED: DataType.VALUE, - Bullet.DAMAGE: DataType.VALUE, - Bullet.PENERATE: DataType.PERCENT } \ No newline at end of file diff --git a/scripts/Tools/WorldManager.gd b/scripts/Tools/WorldManager.gd index 482df67..9e85899 100644 --- a/scripts/Tools/WorldManager.gd +++ b/scripts/Tools/WorldManager.gd @@ -3,7 +3,7 @@ class_name WorldManager static var rootNode: Node2D static var tree: SceneTree -static var runningTime: float = 0 +static var runningTime: int = 0 func _ready(): tree = get_tree()