xiandie/scene/little_game/弹珠游戏/ball.gd

107 lines
2.9 KiB
GDScript3
Raw Normal View History

2025-04-21 13:31:12 +00:00
@tool
extends RigidBody2D
signal hit_ball
signal hit_boundary
2025-06-05 07:17:51 +00:00
@export_enum("1", "2", "3", "4", "5", "6", "7") var id := "1":
2025-04-21 13:31:12 +00:00
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
2025-04-21 13:31:12 +00:00
@onready var sprite2d = $Sprite2D as Sprite2D
@onready var shadow = $Shadow as Sprite2D
2025-04-21 13:31:12 +00:00
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"),
2025-04-21 13:31:12 +00:00
}
func _ready() -> void:
2025-06-05 07:17:51 +00:00
if is_shooter:
linear_damp = 0
2025-04-21 13:31:12 +00:00
contact_monitor = true
max_contacts_reported = 1
_set_up_texture()
body_entered.connect(_on_body_entered)
2025-06-05 07:17:51 +00:00
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
2025-04-21 13:31:12 +00:00
func rand_id():
# 随机 id
var rand = randi() % 3 + 1
id = str(rand)
_set_up_texture()
2025-04-21 13:31:12 +00:00
func _set_up_texture():
sprite2d.texture = texture_dict[id]
var recycling = false
2025-04-21 13:31:12 +00:00
func _on_body_entered(node: Node):
2025-06-05 07:17:51 +00:00
if GlobalConfig.DEBUG:
print("[debug] hit node", node.get_path())
2025-04-21 13:31:12 +00:00
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)
2025-04-21 13:31:12 +00:00
tween.tween_callback(hit_ball.emit)
tween.tween_callback(node.queue_free)
tween.tween_callback(queue_free)
2025-04-21 13:31:12 +00:00
func _process(_delta: float) -> void:
if Engine.is_editor_hint():
return
2025-04-21 13:31:12 +00:00
# 根据 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)