İlk commit: Stepstead Godot istemci (4.6 Mobile)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
commit
6a1706051d
346 changed files with 14415 additions and 0 deletions
159
scripts/hud.gd
Normal file
159
scripts/hud.gd
Normal file
|
|
@ -0,0 +1,159 @@
|
|||
extends CanvasLayer
|
||||
## HUD — üst bilgi çubuğu (karakter/altın/adım + ikincil ikonlar) ve
|
||||
## alt navigasyon çubuğu (Harita/Çanta/Üretim/Market/Karakter/Ayarlar).
|
||||
## Ana paneller kod ile kurulur; alt bar soldan kayarak girer.
|
||||
|
||||
@onready var char_label: Label = $TopBar/HBox/CharName
|
||||
@onready var level_label: Label = $TopBar/HBox/Level
|
||||
@onready var steps_label: Label = $TopBar/HBox/Steps
|
||||
@onready var logout_btn: Button = $TopBar/HBox/Logout
|
||||
@onready var add_steps_btn: Button = $TopBar/HBox/AddSteps
|
||||
@onready var inventory_btn: Button = $TopBar/HBox/InventoryBtn
|
||||
@onready var inventory_panel: PanelContainer = $InventoryPanel
|
||||
@onready var craft_btn: Button = $TopBar/HBox/CraftBtn
|
||||
@onready var craft_panel: PanelContainer = $CraftPanel
|
||||
|
||||
const NAV_HEIGHT := 96
|
||||
|
||||
var chat_panel: PanelContainer
|
||||
var market_panel: PanelContainer
|
||||
var daily_panel: PanelContainer
|
||||
var skills_panel: PanelContainer
|
||||
var leaderboard_panel: PanelContainer
|
||||
var settings_panel: PanelContainer
|
||||
var gold_label: Label
|
||||
var _nav_layer: CanvasLayer
|
||||
|
||||
func _ready() -> void:
|
||||
add_steps_btn.pressed.connect(_add_steps_debug)
|
||||
# Eski üst-bar nav butonları alt çubuğa taşındı — gizle (tscn'e dokunmadan)
|
||||
inventory_btn.visible = false
|
||||
craft_btn.visible = false
|
||||
logout_btn.visible = false
|
||||
|
||||
# Kod-ile-kurulan paneller
|
||||
chat_panel = preload("res://scripts/chat_panel.gd").new()
|
||||
add_child(chat_panel)
|
||||
market_panel = preload("res://scripts/market_panel.gd").new()
|
||||
add_child(market_panel)
|
||||
daily_panel = preload("res://scripts/daily_panel.gd").new()
|
||||
add_child(daily_panel)
|
||||
skills_panel = preload("res://scripts/skills_panel.gd").new()
|
||||
add_child(skills_panel)
|
||||
leaderboard_panel = preload("res://scripts/leaderboard_panel.gd").new()
|
||||
add_child(leaderboard_panel)
|
||||
settings_panel = preload("res://scripts/settings_panel.gd").new()
|
||||
add_child(settings_panel)
|
||||
settings_panel.logout_requested.connect(_logout)
|
||||
|
||||
# Üst bar: altın etiketi + ikincil ikonlar (sohbet/lider/günlük)
|
||||
var hbox: HBoxContainer = $TopBar/HBox
|
||||
gold_label = Label.new()
|
||||
gold_label.add_theme_color_override("font_color", Color(0.95, 0.8, 0.35))
|
||||
hbox.add_child(gold_label)
|
||||
hbox.move_child(gold_label, steps_label.get_index() + 1)
|
||||
_top_icon(hbox, "💬", _open_chat)
|
||||
_top_icon(hbox, "🏆", _open_leaderboard)
|
||||
_top_icon(hbox, "🎁", _open_daily)
|
||||
|
||||
_build_bottom_nav()
|
||||
_render()
|
||||
GameState.character_loaded.connect(func(_c): _render())
|
||||
|
||||
func _top_icon(hbox: HBoxContainer, txt: String, cb: Callable) -> void:
|
||||
var b := Button.new()
|
||||
b.text = txt
|
||||
hbox.add_child(b)
|
||||
b.pressed.connect(cb)
|
||||
|
||||
# --- Alt navigasyon çubuğu ---
|
||||
|
||||
func _build_bottom_nav() -> void:
|
||||
_nav_layer = CanvasLayer.new()
|
||||
_nav_layer.layer = 3
|
||||
add_child(_nav_layer)
|
||||
|
||||
var bar := PanelContainer.new()
|
||||
bar.set_anchors_preset(Control.PRESET_BOTTOM_WIDE)
|
||||
bar.offset_top = -NAV_HEIGHT
|
||||
bar.offset_bottom = 0
|
||||
var sb := StyleBoxFlat.new()
|
||||
sb.bg_color = Color(0.09, 0.10, 0.13, 0.98)
|
||||
sb.border_color = Color(0.2, 0.22, 0.28)
|
||||
sb.border_width_top = 2
|
||||
bar.add_theme_stylebox_override("panel", sb)
|
||||
_nav_layer.add_child(bar)
|
||||
|
||||
var hbox := HBoxContainer.new()
|
||||
hbox.add_theme_constant_override("separation", 0)
|
||||
bar.add_child(hbox)
|
||||
|
||||
_nav_btn(hbox, "🗺", "Harita", close_all_panels)
|
||||
_nav_btn(hbox, "🎒", "Çanta", func() -> void: _toggle(inventory_panel))
|
||||
_nav_btn(hbox, "🛠", "Üretim", func() -> void: _toggle(craft_panel))
|
||||
_nav_btn(hbox, "🏪", "Market", func() -> void: _toggle(market_panel))
|
||||
_nav_btn(hbox, "👤", "Karakter", func() -> void: _toggle(skills_panel))
|
||||
_nav_btn(hbox, "⚙", "Ayarlar", func() -> void: _toggle(settings_panel))
|
||||
|
||||
# Soldan kaydırarak gir
|
||||
_nav_layer.offset = Vector2(-720, 0)
|
||||
var tw := create_tween()
|
||||
tw.tween_property(_nav_layer, "offset", Vector2.ZERO, 0.35).set_trans(Tween.TRANS_CUBIC).set_ease(Tween.EASE_OUT)
|
||||
|
||||
func _nav_btn(hbox: HBoxContainer, icon: String, label: String, cb: Callable) -> void:
|
||||
var b := Button.new()
|
||||
b.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||||
b.custom_minimum_size = Vector2(0, NAV_HEIGHT)
|
||||
b.focus_mode = Control.FOCUS_NONE
|
||||
b.flat = true
|
||||
b.text = "%s\n%s" % [icon, label]
|
||||
b.add_theme_font_size_override("font_size", 13)
|
||||
b.autowrap_mode = TextServer.AUTOWRAP_OFF
|
||||
hbox.add_child(b)
|
||||
b.pressed.connect(cb)
|
||||
|
||||
func _all_panels() -> Array:
|
||||
return [inventory_panel, craft_panel, market_panel, skills_panel,
|
||||
daily_panel, leaderboard_panel, chat_panel, settings_panel]
|
||||
|
||||
func close_all_panels() -> void:
|
||||
for p in _all_panels():
|
||||
if p != null:
|
||||
p.visible = false
|
||||
|
||||
# Bir paneli aç/kapat; açarken diğerlerini kapat (tek panel görünür)
|
||||
func _toggle(panel: PanelContainer) -> void:
|
||||
if panel == null:
|
||||
return
|
||||
if panel.visible:
|
||||
panel.visible = false
|
||||
return
|
||||
close_all_panels()
|
||||
panel.open()
|
||||
|
||||
func _open_chat() -> void: _toggle(chat_panel)
|
||||
func _open_leaderboard() -> void: _toggle(leaderboard_panel)
|
||||
func _open_daily() -> void: _toggle(daily_panel)
|
||||
|
||||
func _add_steps_debug() -> void:
|
||||
# Gerçek pedometer yolunu test eder: simülasyon sayacına ekle + sunucuya sync
|
||||
Pedometer.sim_add(100)
|
||||
await Pedometer.sync_now()
|
||||
_render()
|
||||
|
||||
func _render() -> void:
|
||||
var c: Dictionary = GameState.character
|
||||
if c.is_empty():
|
||||
return
|
||||
char_label.text = str(c.get("name", ""))
|
||||
level_label.text = "Lv %d" % int(c.get("level", 1))
|
||||
steps_label.text = "👣 %d" % int(c.get("step_balance", 0))
|
||||
if gold_label != null:
|
||||
gold_label.text = "🪙 %d" % int(c.get("gold", 0))
|
||||
|
||||
func _logout() -> void:
|
||||
WsClient.stop()
|
||||
Auth.clear()
|
||||
GameState.character = {}
|
||||
GameState.skills = []
|
||||
get_tree().change_scene_to_file("res://scenes/login.tscn")
|
||||
Loading…
Add table
Add a link
Reference in a new issue