63 lines
2.0 KiB
GDScript3
63 lines
2.0 KiB
GDScript3
|
extends Control
|
||
|
class_name card_arrow
|
||
|
##用于贝塞尔曲线选择目标的线图片
|
||
|
@export var texture_circle:Texture2D
|
||
|
##用于贝塞尔曲线选择目标的箭头图片
|
||
|
@export var texture_arrow:Texture2D
|
||
|
##贝塞尔曲线选择目标的线密度
|
||
|
@export var texture_num:int=5
|
||
|
##贝塞尔箭头初始旋转因子(弧度制度)
|
||
|
@export var arrowImageRotate:float=PI/2
|
||
|
##箭头图片容器场景
|
||
|
@export var arrowImageScene:PackedScene
|
||
|
##是否开启
|
||
|
@export var is_start:bool=false
|
||
|
@export_group("缩放")
|
||
|
##用来决定arrow节点缩放曲线的curve
|
||
|
@export var curve:Curve
|
||
|
##缩放最大系数
|
||
|
@export var max_scale:float=2
|
||
|
##图片节点队列
|
||
|
var texture_array:Array[arrowImage]=[]
|
||
|
func _ready():
|
||
|
curve.bake()
|
||
|
for i in range(texture_num):
|
||
|
var new_texture=arrowImageScene.instantiate()
|
||
|
self.add_child(new_texture)
|
||
|
texture_array.append(new_texture)
|
||
|
new_texture.set_image(texture_circle,2)
|
||
|
new_texture.hide()
|
||
|
texture_array[texture_num-1].set_image(texture_arrow,2)
|
||
|
func replace_texture():
|
||
|
var mouse_pos=(get_viewport().get_mouse_position()-self.global_position)
|
||
|
texture_array[0].rotation=texture_array[1].rotation
|
||
|
for i in range(1,texture_array.size()):
|
||
|
var t=logWithBase(float(i)/(texture_array.size()-1)+1,2)
|
||
|
var res=get_bezier_position(self.position,mouse_pos,t)
|
||
|
texture_array[i].position=res[0]-self.position
|
||
|
texture_array[i].rotation=res[1]-self.rotation+arrowImageRotate
|
||
|
var scal=curve.sample(float(i+1)/texture_array.size())*max_scale
|
||
|
texture_array[i].scale=Vector2(scal,scal)
|
||
|
func _process(delta):
|
||
|
if is_start:
|
||
|
replace_texture()
|
||
|
|
||
|
|
||
|
##贝塞尔曲线
|
||
|
func get_bezier_position(p:Vector2,q:Vector2,scale:float):
|
||
|
var p1=p+(q-p)*Vector2(-0.3,0.8)
|
||
|
var p2=p+(q-p)*Vector2(0.1,1.4)
|
||
|
return [(1-scale)**3*p+3*(1-scale)**2*scale*p1+3*(1-scale)*scale**2*p2+scale**3*q,
|
||
|
((3*q-9*p2+9*p1-3*p)*scale**2+(6*p2-12*p1+6*p)*scale+3*p1-3*p).angle()]
|
||
|
pass
|
||
|
func logWithBase(value, base)->float:
|
||
|
return log(value) / log(base)
|
||
|
func start():
|
||
|
for i in texture_array:
|
||
|
i.show()
|
||
|
is_start=true
|
||
|
func stop():
|
||
|
for i in texture_array:
|
||
|
i.hide()
|
||
|
is_start=false
|