107 lines
2.9 KiB
GDScript
107 lines
2.9 KiB
GDScript
@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)
|