68 lines
1.7 KiB
GDScript
68 lines
1.7 KiB
GDScript
class_name BeachBottlePresentation
|
|
extends Node3D
|
|
|
|
const VISIBLE_BASE_TUCK_PIXELS: float = 1.0
|
|
const AUTHORED_VISIBLE_BOTTOM_PIXEL: float = 48.0
|
|
|
|
@onready var _sprite: Sprite3D = %BottleSprite
|
|
|
|
var message_id: StringName
|
|
var _collecting: bool = false
|
|
|
|
|
|
func _ready() -> void:
|
|
_anchor_sprite_visible_bottom()
|
|
|
|
|
|
func configure(
|
|
reserved_message_id: StringName,
|
|
world_position: Vector3,
|
|
phase: float = 0.0,
|
|
) -> void:
|
|
message_id = reserved_message_id
|
|
global_position = world_position
|
|
rotation.y = phase
|
|
|
|
|
|
func _anchor_sprite_visible_bottom() -> void:
|
|
if _sprite == null or _sprite.texture == null:
|
|
return
|
|
var texture_height: float = float(_sprite.texture.get_height())
|
|
if texture_height <= 0.0:
|
|
return
|
|
var texture_center_pixel: float = texture_height * 0.5
|
|
# VRAM-compressed textures do not expose reliable alpha bounds at runtime.
|
|
# The authored 64px sand sprite ends at pixel 48; sink that visible baseline
|
|
# one source pixel into the sampled terrain so it cannot visibly hover.
|
|
_sprite.position.y = maxf(
|
|
(
|
|
AUTHORED_VISIBLE_BOTTOM_PIXEL
|
|
- texture_center_pixel
|
|
- VISIBLE_BASE_TUCK_PIXELS
|
|
) * _sprite.pixel_size,
|
|
0.0,
|
|
)
|
|
|
|
|
|
func get_collect_position() -> Vector3:
|
|
return global_position
|
|
|
|
|
|
func play_collected() -> void:
|
|
if _collecting:
|
|
return
|
|
_collecting = true
|
|
var tween := create_tween()
|
|
tween.set_parallel(true)
|
|
tween.set_trans(Tween.TRANS_QUAD)
|
|
tween.set_ease(Tween.EASE_IN)
|
|
tween.tween_property(self, "scale", Vector3(0.35, 0.35, 0.35), 0.22)
|
|
tween.tween_property(self, "position:y", position.y + 0.35, 0.22)
|
|
if _sprite != null:
|
|
tween.tween_property(
|
|
_sprite,
|
|
"modulate",
|
|
Color(1.0, 1.0, 1.0, 0.0),
|
|
0.22,
|
|
)
|
|
tween.chain().tween_callback(queue_free)
|