@tool extends RigidBody2D signal hit_ball signal hit_boundary @export_enum("1", "2", "3", "4", "5", "6", "7") var id := "1": set(value): id = value if Engine.is_editor_hint() and is_node_ready(): _set_up_texture() @export var is_shooter := false: set(value): is_shooter = value @export var enable := true: set(value): enable = value if is_node_ready(): $CollisionShape2D.set_deferred("disabled", !value) @onready var collision_shape = $CollisionShape2D as CollisionShape2D @onready var sprite2d = $Sprite2D as Sprite2D @onready var shadow = $Shadow as Sprite2D const texture_dict = { "1": preload("res://asset/art/little_game/弹珠/球1.png"), "2": preload("res://asset/art/little_game/弹珠/球2.png"), "3": preload("res://asset/art/little_game/弹珠/球3.png"), "4": preload("res://asset/art/little_game/弹珠/球4.png"), "5": preload("res://asset/art/little_game/弹珠/球5.png"), "6": preload("res://asset/art/little_game/弹珠/球6.png"), "7": preload("res://asset/art/little_game/弹珠/球7.png"), } func _ready() -> void: if is_shooter: linear_damp = 0 contact_monitor = true max_contacts_reported = 1 _set_up_texture() body_entered.connect(_on_body_entered) func dispatch(origin_pos: Vector2): visible = true modulate.a = 0.3 var target_pos = position position = origin_pos collision_shape.disabled = true var tween = create_tween() tween.tween_property(self, "modulate:a", 1.0, 0.4) tween.parallel().tween_property(self, "rotation", 4.0, 0.8).set_ease(Tween.EASE_IN_OUT) tween.parallel().tween_property(self, "position", target_pos, 0.8).set_ease(Tween.EASE_IN_OUT) tween.tween_callback(func(): collision_shape.disabled = false) func hide_away(): visible = false collision_shape.disabled = true func rand_id(): # 随机 id var rand = randi() % 3 + 1 id = str(rand) _set_up_texture() func _set_up_texture(): sprite2d.texture = texture_dict[id] var recycling = false func _on_body_entered(node: Node): if GlobalConfig.DEBUG: print("[debug] hit node", node.get_path()) if recycling or not is_shooter: return recycling = true var tween = create_tween() if node is StaticBody2D: tween.tween_property(sprite2d, "modulate:a", 0.0, 1.0) tween.tween_callback(hit_boundary.emit) tween.tween_callback(queue_free) return tween.tween_property(sprite2d, "modulate:a", 0.0, 1.5) tween.parallel().tween_property(node.sprite2d, "modulate:a", 0.0, 1.5) tween.tween_callback(hit_ball.emit) tween.tween_callback(node.queue_free) tween.tween_callback(queue_free) func _process(_delta: float) -> void: if Engine.is_editor_hint(): return # 根据 y 坐标缩放 var ball_scale = 1.0 + (global_position.y / 400.0) sprite2d.scale = Vector2(ball_scale, ball_scale) * 0.4 shadow.scale = Vector2(ball_scale, ball_scale) shadow.rotation = -rotation shadow.position = Vector2(0, 6.0 * ball_scale).rotated(-rotation) collision_shape.scale = Vector2(ball_scale, ball_scale)