Nouvel autoload PlayerProgress qui gagne de l'XP sur: - cassage de blocs (gain variable selon le type: perle, épave, coral > sand) - collecte de perles (+25) - crafting (+10) - paliers de profondeur atteints (+20 à 10/25/50/75/100m) HUD: barre XP + label niveau en bas centre, bannière "NIVEAU X" au level-up (son bulle + fade). Popup 3D "+N XP" spawn au point d'action. Boucle court-terme dopamine: chaque action = feedback visuel immédiat. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
43 lines
1.1 KiB
GDScript
43 lines
1.1 KiB
GDScript
extends Node3D
|
|
|
|
var _label: Label3D = null
|
|
var _elapsed: float = 0.0
|
|
var _lifetime: float = 1.4
|
|
var _drift: float = 1.6
|
|
|
|
|
|
static func spawn(parent: Node, text: String, world_pos: Vector3, color: Color = Color(1.0, 0.9, 0.2)) -> void:
|
|
var popup := Node3D.new()
|
|
popup.set_script(load("res://scripts/progression/XpPopup.gd"))
|
|
parent.add_child(popup)
|
|
popup.global_position = world_pos
|
|
popup.configure(text, color)
|
|
|
|
|
|
func configure(text: String, color: Color) -> void:
|
|
_label = Label3D.new()
|
|
_label.text = text
|
|
_label.font_size = 54
|
|
_label.outline_size = 6
|
|
_label.modulate = color
|
|
_label.billboard = BaseMaterial3D.BILLBOARD_ENABLED
|
|
_label.no_depth_test = true
|
|
_label.render_priority = 4
|
|
_label.pixel_size = 0.008
|
|
add_child(_label)
|
|
|
|
|
|
func _process(delta: float) -> void:
|
|
_elapsed += delta
|
|
var t: float = _elapsed / _lifetime
|
|
position.y += _drift * delta
|
|
if _label != null:
|
|
var alpha: float = 1.0 - clampf(t, 0.0, 1.0)
|
|
var c: Color = _label.modulate
|
|
c.a = alpha
|
|
_label.modulate = c
|
|
var scale_factor: float = 1.0 + (1.0 - alpha) * 0.4
|
|
_label.scale = Vector3.ONE * scale_factor
|
|
if _elapsed >= _lifetime:
|
|
queue_free()
|