223 lines
8.1 KiB
GDScript
223 lines
8.1 KiB
GDScript
class_name TopBarView
|
|
extends RefCounted
|
|
|
|
const BitmapFontLabelScript := preload("res://scripts/core/bitmap_font_label.gd")
|
|
const NumberFormatterScript := preload("res://scripts/core/number_formatter.gd")
|
|
const StaminaRulesScript := preload("res://scripts/domain/rules/stamina_rules.gd")
|
|
const PowerFontTexturePath := "res://assets/egret/fonts/building_lv_font.png"
|
|
const PowerFontPath := "res://assets/egret/fonts/building_lv_font.json"
|
|
const TopShowTexture := preload("res://assets/egret/menu2/btn_top_show.png")
|
|
const TopHideTexture := preload("res://assets/egret/menu2/btn_top_hide.png")
|
|
const TOP_MENU_EXPANDED_Y := 1.0
|
|
const TOP_MENU_COLLAPSED_Y := -130.0
|
|
const DEFAULT_BAR_FILL_MAX_WIDTH := 223.0
|
|
|
|
var _owner: Control
|
|
var _top_layer: Control
|
|
var _top_button_group: Control
|
|
var _top_hide: TextureRect
|
|
var _label_name: Label
|
|
var _label_level: Label
|
|
var _label_gold: Label
|
|
var _label_diamond: Label
|
|
var _label_score: Label
|
|
var _label_exp: Label
|
|
var _label_stamina: Label
|
|
var _exp_fill: NinePatchRect
|
|
var _stamina_fill: NinePatchRect
|
|
var _avatar: TextureRect
|
|
var _game_config
|
|
var _style_label: Callable
|
|
var _style_menu_title: Callable
|
|
var _score_bitmap: BitmapFontLabel
|
|
var _exp_tween: Tween
|
|
var _stamina_tween: Tween
|
|
var _top_menu_tween: Tween
|
|
var _top_menu_expanded := true
|
|
var _initial_rendered := false
|
|
var _exp_fill_max_width := DEFAULT_BAR_FILL_MAX_WIDTH
|
|
var _stamina_fill_max_width := DEFAULT_BAR_FILL_MAX_WIDTH
|
|
|
|
|
|
func setup(bindings: Dictionary, style_label: Callable, style_menu_title: Callable) -> void:
|
|
_owner = bindings.get("owner") as Control
|
|
_top_layer = bindings.get("top_layer") as Control
|
|
_top_button_group = bindings.get("top_button_group") as Control
|
|
_top_hide = bindings.get("top_hide") as TextureRect
|
|
_label_name = bindings.get("label_name") as Label
|
|
_label_level = bindings.get("label_level") as Label
|
|
_label_gold = bindings.get("label_gold") as Label
|
|
_label_diamond = bindings.get("label_diamond") as Label
|
|
_label_score = bindings.get("label_score") as Label
|
|
_label_exp = bindings.get("label_exp") as Label
|
|
_label_stamina = bindings.get("label_stamina") as Label
|
|
_exp_fill = bindings.get("exp_fill") as NinePatchRect
|
|
_stamina_fill = bindings.get("stamina_fill") as NinePatchRect
|
|
if _exp_fill != null and _exp_fill.size.x > 0.0:
|
|
_exp_fill_max_width = _exp_fill.size.x
|
|
if _stamina_fill != null and _stamina_fill.size.x > 0.0:
|
|
_stamina_fill_max_width = _stamina_fill.size.x
|
|
_avatar = bindings.get("avatar") as TextureRect
|
|
_game_config = bindings.get("game_config")
|
|
_style_label = style_label
|
|
_style_menu_title = style_menu_title
|
|
_apply_label_theme()
|
|
_setup_power_bitmap_label()
|
|
_apply_top_menu_toggle_visual()
|
|
|
|
|
|
func toggle_top_button_group() -> bool:
|
|
if _top_button_group == null or _owner == null:
|
|
return _top_menu_expanded
|
|
if _top_menu_tween != null:
|
|
_top_menu_tween.kill()
|
|
|
|
_top_menu_expanded = not _top_menu_expanded
|
|
_apply_top_menu_toggle_visual()
|
|
_top_button_group.visible = true
|
|
|
|
var target_y := TOP_MENU_EXPANDED_Y if _top_menu_expanded else TOP_MENU_COLLAPSED_Y
|
|
_top_menu_tween = _owner.create_tween()
|
|
_top_menu_tween.tween_property(_top_button_group, "position:y", target_y, 0.25).set_trans(Tween.TRANS_QUAD).set_ease(Tween.EASE_OUT)
|
|
if not _top_menu_expanded:
|
|
_top_menu_tween.finished.connect(_finish_collapse_top_menu)
|
|
return _top_menu_expanded
|
|
|
|
|
|
func set_visitor_mode(enabled: bool) -> void:
|
|
if _top_button_group != null:
|
|
_top_button_group.visible = not enabled and _top_menu_expanded
|
|
if _top_hide != null:
|
|
_top_hide.visible = not enabled
|
|
|
|
|
|
func render(player_data: Dictionary, own_player_data: Dictionary = {}) -> void:
|
|
if _label_name == null:
|
|
return
|
|
var nickname := str(player_data.get("nickname", player_data.get("username", "")))
|
|
_label_name.text = nickname.left(10)
|
|
_label_level.text = "LV.%s" % int(player_data.get("level", 1))
|
|
_label_gold.text = NumberFormatterScript.compact(int(player_data.get("gold", 0)))
|
|
_label_diamond.text = NumberFormatterScript.compact(int(player_data.get("gem", 0)))
|
|
var score_text := NumberFormatterScript.compact(int(player_data.get("score", 0)))
|
|
_label_score.text = score_text
|
|
if _score_bitmap != null:
|
|
_score_bitmap.set_text(score_text)
|
|
|
|
var exp_value := int(player_data.get("exp", 0))
|
|
var exp_max := _get_level_exp_max(int(player_data.get("level", 1)))
|
|
_label_exp.text = "%s/%s" % [exp_value, exp_max]
|
|
var ratio := clampf(float(exp_value) / float(maxi(exp_max, 1)), 0.0, 1.0)
|
|
_set_exp_width(_exp_fill_max_width * ratio, _initial_rendered)
|
|
|
|
var stamina_source := own_player_data if not own_player_data.is_empty() else player_data
|
|
var stamina := StaminaRulesScript.snapshot(stamina_source)
|
|
var stamina_value := int(stamina.get("value", 20))
|
|
var stamina_max := maxi(int(stamina.get("max", 20)), 1)
|
|
if _label_stamina != null:
|
|
_label_stamina.text = "%s/%s" % [stamina_value, stamina_max]
|
|
var stamina_ratio := clampf(float(stamina_value) / float(stamina_max), 0.0, 1.0)
|
|
_set_stamina_width(_stamina_fill_max_width * stamina_ratio, _initial_rendered)
|
|
_initial_rendered = true
|
|
|
|
_apply_avatar(str(player_data.get("avatar", "1")))
|
|
|
|
|
|
func _apply_label_theme() -> void:
|
|
if not _style_label.is_valid():
|
|
return
|
|
_style_label.call(_label_name, 20, Color.html("#fffeef"), 1, Color.html("#7f5523"))
|
|
_style_label.call(_label_level, 20, Color.WHITE, 1, Color.html("#724f2e"))
|
|
_style_label.call(_label_gold, 18, Color.html("#fffbe5"), 1, Color.html("#724f2e"))
|
|
_style_label.call(_label_diamond, 18, Color.html("#fffbe5"), 1, Color.html("#724f2e"))
|
|
_style_label.call(_label_score, 24, Color.html("#fff05a"), 2, Color.html("#8a4b18"))
|
|
_style_label.call(_label_exp, 16, Color.html("#b0ff94"), 1, Color.html("#724f2e"))
|
|
_style_label.call(_label_stamina, 16, Color.html("#fff9d7"), 1, Color.html("#8a4b18"))
|
|
|
|
|
|
func _setup_power_bitmap_label() -> void:
|
|
if _top_layer == null or _label_score == null:
|
|
return
|
|
_label_score.visible = false
|
|
_score_bitmap = BitmapFontLabelScript.new()
|
|
_score_bitmap.name = "PowerBitmapLabel"
|
|
_score_bitmap.position = Vector2(244.0, 8.0)
|
|
_score_bitmap.letter_spacing = -3.0
|
|
_score_bitmap.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
|
_score_bitmap.setup(PowerFontTexturePath, PowerFontPath)
|
|
_top_layer.add_child(_score_bitmap)
|
|
|
|
|
|
func _set_exp_width(width: float, animated: bool) -> void:
|
|
if _exp_fill == null:
|
|
return
|
|
width = clampf(width, 0.0, _exp_fill_max_width)
|
|
if _exp_tween != null:
|
|
_exp_tween.kill()
|
|
if width <= 0.0:
|
|
_exp_fill.size.x = 0.0
|
|
_exp_fill.visible = false
|
|
return
|
|
if not animated:
|
|
_exp_fill.visible = true
|
|
_exp_fill.size.x = width
|
|
return
|
|
if _owner == null:
|
|
_exp_fill.visible = true
|
|
_exp_fill.size.x = width
|
|
return
|
|
_exp_fill.visible = true
|
|
_exp_tween = _owner.create_tween()
|
|
_exp_tween.tween_property(_exp_fill, "size:x", width, 0.24).set_trans(Tween.TRANS_QUAD).set_ease(Tween.EASE_OUT)
|
|
|
|
|
|
func _set_stamina_width(width: float, animated: bool) -> void:
|
|
if _stamina_fill == null:
|
|
return
|
|
width = clampf(width, 0.0, _stamina_fill_max_width)
|
|
if _stamina_tween != null:
|
|
_stamina_tween.kill()
|
|
if width <= 0.0:
|
|
_stamina_fill.size.x = 0.0
|
|
_stamina_fill.visible = false
|
|
return
|
|
if not animated:
|
|
_stamina_fill.visible = true
|
|
_stamina_fill.size.x = width
|
|
return
|
|
if _owner == null:
|
|
_stamina_fill.visible = true
|
|
_stamina_fill.size.x = width
|
|
return
|
|
_stamina_fill.visible = true
|
|
_stamina_tween = _owner.create_tween()
|
|
_stamina_tween.tween_property(_stamina_fill, "size:x", width, 0.24).set_trans(Tween.TRANS_QUAD).set_ease(Tween.EASE_OUT)
|
|
|
|
|
|
func _apply_top_menu_toggle_visual() -> void:
|
|
if _top_hide == null:
|
|
return
|
|
_top_hide.texture = TopShowTexture if _top_menu_expanded else TopHideTexture
|
|
|
|
|
|
func _finish_collapse_top_menu() -> void:
|
|
if _top_button_group != null and not _top_menu_expanded:
|
|
_top_button_group.visible = false
|
|
|
|
|
|
func _apply_avatar(avatar_id: String) -> void:
|
|
if _avatar == null:
|
|
return
|
|
if avatar_id.is_empty() or avatar_id.contains("http"):
|
|
avatar_id = "1"
|
|
var resource_path := "res://assets/egret/head/head%s.png" % avatar_id
|
|
if not ResourceLoader.exists(resource_path):
|
|
resource_path = "res://assets/egret/head/head1.png"
|
|
_avatar.texture = load(resource_path)
|
|
|
|
|
|
func _get_level_exp_max(level: int) -> int:
|
|
if _game_config != null and _game_config.has_method("get_player_exp_max"):
|
|
return int(_game_config.get_player_exp_max(level + 1))
|
|
return mini(level + 1, 60)
|