@tool extends Node2D @export var flower_area := Vector2(400, 50): set(val): flower_area = val queue_redraw() @export var gizmo_outline_color := Color(0.4, 0.4, 0.2, 0.8): set(val): gizmo_outline_color = val queue_redraw() @export var debug_setup_and_scatter := false: set(val): debug_setup_and_scatter = false if Engine.is_editor_hint(): _debug_setup_flowers() @export var auto_fade_distance := 50.0 @export var focus_node: Node2D # 花朵总数 @export var total_num := 300 # 1-10 号花数量权重; 2,6,8,9 靠前偏低; 4,5,10 靠后偏高; @export var weights :PackedFloat64Array= [10, 7, 10, 12, 14, 6, 10, 7, 8, 12] var origin_flowers := 10 var flowers = [] as Array[AnimatedSprite2D] # var faded_flowers = [] as Array[String] # Called when the node enters the scene tree for the first time. func _ready() -> void: if Engine.is_editor_hint(): queue_redraw() flowers.clear() for f in get_children(): if f is not AnimatedSprite2D: continue flowers.append(f) if f.global_position.y > 98: #98 玩家 f.z_index = 7 elif f.global_position.y > 88: # 背景小孩 f.z_index = 1 func _debug_setup_flowers(): var count = 0 for c in get_children(): count += 1 if count > origin_flowers: remove_child(c) c.owner = null c.queue_free() # 按照 origin_flowers 复制到 total_num 份 flowers.clear() for i in range(origin_flowers): var f = get_child(i) if f is AnimatedSprite2D: flowers.append(f) # duplicate flowers from [0, origin_flowers) var weights_sum = 0.0 for w in weights: weights_sum += w for id in range(weights.size()): var w = weights[id] # 减去本身就有的一个 var num = ceil(w / weights_sum * total_num - 1 ) print(id,"号花数量=",num) while num > 0.0: num -= 1.0 var f = flowers[id].duplicate() as AnimatedSprite2D f.y_sort_enabled = true add_child(f) f.name = "flower11" f.owner = self flowers.append(f) _sactter_flowers() func _sactter_flowers() -> void: flowers.clear() for f in get_children(): if f is AnimatedSprite2D: flowers.append(f) f.light_mask = 3 # scatter var rand = RandomNumberGenerator.new() rand.randomize() # flowers.shuffle() for i in range(flowers.size()): var f = flowers[i] # clamp to action area # 此时 pos 的 y 范围为 [0, 1)x var pos = Vector2(rand.randf_range(0, flower_area.x), rand.randf()) # 2,6,8,9 靠前 if f.animation in ["2","6","8","9"]: pos.y = (smoothstep(-1., 1., pos.y) - .5) * 2. # pos.y = smoothstep(.0, 10., pos.y * 10.) # pos.y *= 2. # 4,5,10 靠后 elif f.animation in ["4","5","10"]: pos.y = smoothstep(0., 2., pos.y) * 2. # pos.y *= .6 # pos.y = clampf(pos.y, 0., 1.) # 将 pos 的 y 投射到 [0., flower_area.y) pos.y *= flower_area.y f.position = pos # if ( # not Engine.is_editor_hint() # and ArchiveManager.archive.global_data_dict.has("faded_flowers") # ): # faded_flowers = ArchiveManager.archive.global_data_dict["faded_flowers"] # for f in flowers: # if faded_flowers.has(f.name): # var animation_name = fade_animation_dict.get(f.animation, "") # if animation_name: # f.play(animation_name) func _draw() -> void: if Engine.is_editor_hint(): # draw gizmo var area_rect = Rect2(Vector2.ZERO, flower_area) # fill var fill_color = gizmo_outline_color fill_color.a = 0.4 draw_rect(area_rect, fill_color) # outline draw_rect(area_rect, gizmo_outline_color, false, 1.0) func _process(_delta: float) -> void: if Engine.is_editor_hint(): return if not focus_node or not focus_node.is_visible_in_tree(): return var focus_pos_x = focus_node.global_position.x # var faded := false for f in flowers: if f.animation.begins_with("_"): continue var f_pos_x = f.global_position.x var distance = abs(focus_pos_x - f_pos_x) if distance < auto_fade_distance: # print("fading:", f.animation) f.play("_" + f.animation) # faded_flowers.append(f.name) # faded = true # if faded and not Engine.is_editor_hint(): # ArchiveManager.archive.global_data_dict["faded_flowers"] = faded_flowers # 重置所有花,恢复开放状态 func reset_all_blooming(): for f in flowers: if f.animation.begins_with("_"): f.play(f.animation.substr(1)) # faded_flowers.clear() # if not Engine.is_editor_hint(): # ArchiveManager.archive.global_data_dict["faded_flowers"] = faded_flowers