extends RigidBody3D class_name PT @export var follow_speed_curve: Curve @export var color_hp: Color = Color.WHITE @export var color_mp: Color = Color.WHITE var type: Enum.EPtType var value: int = 1 var velocity_min: Vector2 = Vector2.RIGHT *1 var velocity_max: Vector2 = Vector2.ONE *4 var born_time: float = 0.5 #生成时间,无法收集 var alive_time: float = 10.0 #存活时间 var is_born: bool = false var is_init: bool = false var is_collect: bool = false var collect_range: float = 2.0 var follow_dist_max: float = 5.0 @onready var sprite3D: Sprite3D = %Sprite3D as Sprite3D @onready var collision_shape: CollisionShape3D = %CollisionShape3D as CollisionShape3D var frame_rate: float = 0.1 var frame_time: float = 0 func _ready(): var dir: Vector2 = Util.angle_dir(randf_range(0, 360)) * randf_range(velocity_min.x, velocity_max.x) var velocity: Vector3 = Vector3(dir.x, randf_range(velocity_min.y, velocity_max.y), dir.y) set_linear_velocity(velocity) func _process(delta: float) -> void: if not is_init: var scale: Vector3 = Vector3.ONE * sqrt(sqrt(value)) sprite3D.scale = scale collision_shape.scale = scale var color: Color = Color.WHITE match type: Enum.EPtType.HP: color = color_hp Enum.EPtType.MP: color = color_mp _: pass #随机色移 color.r += randf_range(0, 0.3) color.g += randf_range(0, 0.3) color.b += randf_range(0, 0.3) color.clamp() sprite3D.modulate = color sprite3D.rotation.z = randf_range(0, 360) is_init = true var velocity: Vector3 = get_linear_velocity() if velocity.y > 0.01: var frame_count: int = sprite3D.hframes * sprite3D.vframes var frame_time_all: float = frame_rate * frame_count frame_time += delta sprite3D.frame = int(frame_time / frame_rate) % frame_count frame_time = fmod(frame_time, frame_time_all) #生成 if not is_born: if born_time <= 0: is_born = true else: born_time -= delta return #收集激活 if not is_collect: var target: Character = Global.character_mgr.get_player() if not target: return var dir: Vector3 = target.view_pos() - global_position var dist: float = dir.length() if dist < collect_range: is_collect = true #存活时间 if not is_collect: if alive_time <= 0: queue_free() return else: alive_time -= delta #收集 if is_collect: var target: Character = Global.character_mgr.get_player() if not target: return var dir: Vector3 = target.view_pos() - global_position var dist: float = dir.length() if dist > 0.1: var dist_rate = clamp(dist / follow_dist_max, 0, 1) var speed: float = follow_speed_curve.sample(dist_rate) set_linear_velocity(dir.normalized() * speed) else: collect() func collect() -> void: var target: Character = Global.character_mgr.get_player() if not target: return match type: Enum.EPtType.HP: target.add_hp(value) Enum.EPtType.MP: target.add_mp_sub(value, true) _: pass target.cast_particle(ResourceManager.particle_pt_collect, true) queue_free()