challenge-editor/scene/card_state_machine/arrow.gd
2024-09-25 11:52:36 +08:00

86 lines
2.5 KiB
GDScript

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
##用来检测目标的
@onready var area: Area2D = $Area2D
##是否开启
@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 set_select_queue(q:int):
match q:
0:
area.set_collision_layer(1)
area.set_collision_mask(1)
1:
area.set_collision_layer(2)
area.set_collision_mask(2)
pass
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_global_mouse_position()-self.global_position)
area.global_position=get_global_mouse_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()
area.monitoring=true
area.monitorable=true
is_start=true
func stop():
for i in texture_array:
i.hide()
area.position=Vector2.ZERO
is_start=false
area.monitoring=false
area.monitorable=false