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.0 KiB
GDScript
111 lines
3.0 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:
|
|
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()
|