You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

111 lines
3.1 KiB
GDScript

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(0, 3)
var velocity_max: Vector2 = Vector2(3, 6)
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 velocity_xz: Vector2 = Util.angle_dir(randf_range(0, 360)) * randf_range(velocity_min.x, velocity_max.x)
var velocity: Vector3 = Vector3(velocity_xz.x, randf_range(velocity_min.y, velocity_max.y), velocity_xz.y)
set_linear_velocity(velocity)
func _process(delta: float) -> void:
if not is_init:
var pt_scale: Vector3 = Vector3.ONE * sqrt(sqrt(sqrt(value)))
sprite3D.scale = pt_scale
collision_shape.scale = pt_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.1)
color.g += randf_range(0, 0.1)
color.b += randf_range(0, 0.1)
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:
Global.item_mgr.destroy_pt(self)
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)
Global.item_mgr.destroy_pt(self)