343 lines
12 KiB
GDScript
343 lines
12 KiB
GDScript
extends Panel
|
||
# 这是宠物商店面板,用来展示各种宠物
|
||
|
||
# 宠物商店格子容器
|
||
@onready var store_grid: GridContainer = $ScrollContainer/Store_Grid
|
||
@onready var quit_button: Button = $QuitButton
|
||
@onready var refresh_button: Button = $RefreshButton
|
||
@onready var scroll_container = $ScrollContainer
|
||
|
||
# 预添加常用的面板
|
||
@onready var main_game = get_node("/root/main")
|
||
|
||
@onready var lucky_draw_panel: LuckyDrawPanel = $'../LuckyDrawPanel'
|
||
@onready var daily_check_in_panel: DailyCheckInPanel = $'../DailyCheckInPanel'
|
||
@onready var tcp_network_manager_panel: Panel = $'../TCPNetworkManagerPanel'
|
||
@onready var item_bag_panel: Panel = $'../ItemBagPanel'
|
||
@onready var pet_bag_panel: Panel = $'../PetBagPanel'
|
||
@onready var player_bag_panel: Panel = $'../PlayerBagPanel'
|
||
@onready var crop_warehouse_panel: Panel = $'../CropWarehousePanel'
|
||
@onready var crop_store_panel: Panel = $'../CropStorePanel'
|
||
@onready var player_ranking_panel: Panel = $'../PlayerRankingPanel'
|
||
@onready var login_panel: PanelContainer = $'../LoginPanel'
|
||
@onready var batch_buy_popup: PanelContainer = $'../../DiaLog/BatchBuyPopup'
|
||
|
||
# 宠物配置数据
|
||
var pet_config: Dictionary = {}
|
||
# 请求状态标志,防止重复请求
|
||
var is_requesting_config: bool = false
|
||
|
||
# 准备函数
|
||
func _ready():
|
||
# 连接关闭按钮信号
|
||
quit_button.pressed.connect(self._on_quit_button_pressed)
|
||
refresh_button.pressed.connect(self._on_refresh_button_pressed)
|
||
# 连接可见性改变信号
|
||
visibility_changed.connect(_on_visibility_changed)
|
||
|
||
# 隐藏面板(初始默认隐藏)
|
||
self.hide()
|
||
|
||
|
||
# 初始化宠物商店
|
||
func init_pet_store():
|
||
# 从主游戏脚本获取宠物配置数据
|
||
_load_pet_config_from_main()
|
||
update_pet_store_ui()
|
||
|
||
# 更新宠物商店UI
|
||
func update_pet_store_ui():
|
||
if scroll_container:
|
||
scroll_container.clip_contents = false
|
||
|
||
# 设置GridContainer也不裁剪内容
|
||
if store_grid:
|
||
store_grid.clip_contents = false
|
||
|
||
# 清空宠物商店格子
|
||
for child in store_grid.get_children():
|
||
child.queue_free()
|
||
|
||
print("更新宠物商店UI,宠物种类:", pet_config.size())
|
||
|
||
# 为每个宠物配置创建按钮
|
||
for pet_name in pet_config.keys():
|
||
var pet_info = pet_config[pet_name]
|
||
#print("处理宠物:", pet_name, ",数据:", pet_info)
|
||
|
||
# 适配扁平化数据格式
|
||
var can_buy = pet_info.get("can_purchase", false)
|
||
|
||
# 只显示可购买的宠物
|
||
if not can_buy:
|
||
print("宠物 ", pet_name, " 不可购买,跳过")
|
||
continue
|
||
|
||
var pet_cost = pet_info.get("cost", 0)
|
||
var pet_desc = pet_info.get("description", "可爱的宠物伙伴")
|
||
|
||
# 检查玩家是否已购买该宠物
|
||
var is_owned = _check_pet_owned(pet_name)
|
||
|
||
# 创建宠物按钮
|
||
var button = _create_pet_button(pet_name, pet_cost, pet_desc, is_owned)
|
||
|
||
# 更新按钮文本显示价格和状态
|
||
if is_owned:
|
||
button.text = str(pet_name + "\n(已购买)")
|
||
button.disabled = true
|
||
else:
|
||
button.text = str(pet_name + "\n价格:" + str(pet_cost) + "元")
|
||
# 连接购买点击事件
|
||
button.pressed.connect(func(): _on_store_pet_selected(pet_name, pet_cost, pet_desc))
|
||
|
||
store_grid.add_child(button)
|
||
#print("已添加宠物按钮:", pet_name)
|
||
|
||
# 检查玩家是否已拥有某种宠物
|
||
func _check_pet_owned(pet_name: String) -> bool:
|
||
if not main_game.pet_bag:
|
||
return false
|
||
|
||
for pet_data in main_game.pet_bag:
|
||
var pet_type = pet_data.get("pet_type", "")
|
||
if pet_type == pet_name:
|
||
return true
|
||
return false
|
||
|
||
# 创建宠物按钮
|
||
func _create_pet_button(pet_name: String, pet_cost: int, pet_desc: String, is_owned: bool = false) -> Button:
|
||
# 使用按钮作为宠物商店按钮的样式
|
||
var button = main_game.item_button.duplicate()
|
||
|
||
# 确保按钮可见并可点击
|
||
button.visible = true
|
||
button.disabled = false
|
||
button.focus_mode = Control.FOCUS_ALL
|
||
|
||
# 关闭按钮的内容裁剪,允许图片超出按钮边界
|
||
button.clip_contents = false
|
||
|
||
# 设置按钮文本
|
||
button.text = pet_name
|
||
|
||
# 添加工具提示
|
||
button.tooltip_text = str(
|
||
"宠物: " + pet_name + "\n" +
|
||
"价格: " + str(pet_cost) + "元\n" +
|
||
"描述: " + pet_desc + "\n" +
|
||
"点击购买宠物"
|
||
)
|
||
|
||
# 如果按钮有标题标签,设置标题
|
||
if button.has_node("Title"):
|
||
if is_owned:
|
||
button.get_node("Title").text = "已购买"
|
||
button.get_node("Title").modulate = Color.GRAY # 已购买使用灰色
|
||
else:
|
||
button.get_node("Title").text = "宠物商店"
|
||
button.get_node("Title").modulate = Color.PINK # 宠物商店标题使用粉色
|
||
|
||
# 更新按钮的宠物图片
|
||
_update_button_pet_image(button, pet_name)
|
||
|
||
return button
|
||
|
||
# 更新按钮的宠物图片
|
||
func _update_button_pet_image(button: Button, pet_name: String):
|
||
# 检查按钮是否有CropImage节点
|
||
var pet_image = button.get_node_or_null("CropImage")
|
||
if not pet_image:
|
||
print("按钮没有CropImage节点,跳过图片设置")
|
||
return
|
||
|
||
# 从宠物配置获取场景路径
|
||
var texture = null
|
||
if pet_config.has(pet_name):
|
||
var pet_info = pet_config[pet_name]
|
||
var scene_path = pet_info.get("pet_image", "")
|
||
#print("宠物 ", pet_name, " 的图片路径:", scene_path)
|
||
|
||
if scene_path != "" and ResourceLoader.exists(scene_path):
|
||
#print("开始加载宠物场景:", scene_path)
|
||
# 加载宠物场景并获取PetImage的纹理
|
||
var pet_scene = load(scene_path)
|
||
if pet_scene:
|
||
var pet_instance = pet_scene.instantiate()
|
||
# 场景的根节点就是PetImage,直接使用
|
||
var pet_image_node = pet_instance
|
||
if pet_image_node and pet_image_node.sprite_frames:
|
||
# 获取默认动画的第一帧
|
||
var animation_names = pet_image_node.sprite_frames.get_animation_names()
|
||
if animation_names.size() > 0:
|
||
var default_animation = animation_names[0]
|
||
var frame_count = pet_image_node.sprite_frames.get_frame_count(default_animation)
|
||
if frame_count > 0:
|
||
texture = pet_image_node.sprite_frames.get_frame_texture(default_animation, 0)
|
||
#print("成功获取宠物纹理:", pet_name)
|
||
else:
|
||
print("宠物场景没有动画:", pet_name)
|
||
else:
|
||
print("宠物场景没有PetImage节点或sprite_frames:", pet_name)
|
||
pet_instance.queue_free()
|
||
else:
|
||
print("无法加载宠物场景:", scene_path)
|
||
else:
|
||
print("宠物图片路径无效或文件不存在:", scene_path)
|
||
else:
|
||
print("宠物配置中没有找到:", pet_name)
|
||
|
||
# 设置图片
|
||
if texture:
|
||
pet_image.texture = texture
|
||
pet_image.visible = true
|
||
pet_image.scale = Vector2(10, 10)
|
||
# 确保图片居中显示
|
||
pet_image.centered = true
|
||
#print("成功设置宠物图片:", pet_name)
|
||
else:
|
||
# 如果无法获取图片,隐藏图片节点但保留按钮
|
||
pet_image.visible = false
|
||
print("无法获取宠物图片,隐藏图片节点:", pet_name)
|
||
|
||
# 从服务器获取MongoDB中的宠物配置数据
|
||
func _load_pet_config_from_main():
|
||
# 如果正在请求中,避免重复发送
|
||
if is_requesting_config:
|
||
print("宠物商店:正在请求配置数据中,跳过重复请求")
|
||
return
|
||
|
||
# 发送请求到服务器获取宠物配置
|
||
if tcp_network_manager_panel and tcp_network_manager_panel.has_method("sendGetPetConfig"):
|
||
is_requesting_config = true
|
||
if tcp_network_manager_panel.sendGetPetConfig():
|
||
print("宠物商店:已发送获取宠物配置请求")
|
||
# 等待服务器响应,配置数据将通过网络回调更新
|
||
else:
|
||
print("宠物商店:发送获取宠物配置请求失败")
|
||
pet_config = {}
|
||
is_requesting_config = false
|
||
else:
|
||
print("宠物商店:网络管理器不可用,无法获取宠物配置")
|
||
pet_config = {}
|
||
is_requesting_config = false
|
||
|
||
# 处理服务器返回的宠物配置数据
|
||
func _on_pet_config_received(response_data: Dictionary):
|
||
"""处理从服务器接收到的宠物配置数据"""
|
||
# 重置请求状态
|
||
is_requesting_config = false
|
||
|
||
var success = response_data.get("success", false)
|
||
if success:
|
||
pet_config = response_data.get("pet_config", {})
|
||
print("宠物商店:成功接收宠物配置数据,宠物种类:", pet_config.size())
|
||
# 只更新UI,不重新发送请求
|
||
update_pet_store_ui()
|
||
else:
|
||
var error_message = response_data.get("message", "获取宠物配置失败")
|
||
print("宠物商店:获取宠物配置失败:", error_message)
|
||
pet_config = {}
|
||
# 显示错误提示
|
||
Toast.show(error_message, Color.RED, 3.0, 1.0)
|
||
|
||
# 商店宠物点击处理 - 购买宠物
|
||
func _on_store_pet_selected(pet_name: String, pet_cost: int, pet_desc: String):
|
||
# 检查玩家金钱是否足够
|
||
if main_game.money < pet_cost:
|
||
Toast.show("金钱不足!需要 " + str(pet_cost) + " 元,当前只有 " + str(main_game.money) + " 元", Color.RED, 3.0, 1.0)
|
||
return
|
||
|
||
# 显示购买确认对话框(宠物只能购买1只,不需要批量购买)
|
||
_show_buy_confirmation_dialog(pet_name, pet_cost, pet_desc)
|
||
|
||
# 显示购买确认对话框
|
||
func _show_buy_confirmation_dialog(pet_name: String, pet_cost: int, pet_desc: String):
|
||
# 创建确认对话框
|
||
var confirm_dialog = AcceptDialog.new()
|
||
confirm_dialog.dialog_text = str(
|
||
"确认购买宠物?\n\n" +
|
||
"宠物名称: " + pet_name + "\n" +
|
||
"购买价格: " + str(pet_cost) + " 元\n" +
|
||
"宠物描述: " + pet_desc + "\n\n" +
|
||
"当前金钱: " + str(main_game.money) + " 元\n" +
|
||
"购买后余额: " + str(main_game.money - pet_cost) + " 元\n\n" +
|
||
"注意:每种宠物只能购买一只!"
|
||
)
|
||
confirm_dialog.title = "购买宠物确认"
|
||
confirm_dialog.ok_button_text = "确认购买"
|
||
confirm_dialog.add_cancel_button("取消")
|
||
|
||
# 添加到场景
|
||
add_child(confirm_dialog)
|
||
|
||
# 连接信号
|
||
confirm_dialog.confirmed.connect(_on_confirm_buy_pet.bind(pet_name, pet_cost, confirm_dialog))
|
||
confirm_dialog.canceled.connect(_on_cancel_buy_pet.bind(confirm_dialog))
|
||
|
||
# 显示对话框
|
||
confirm_dialog.popup_centered()
|
||
|
||
# 确认购买宠物
|
||
func _on_confirm_buy_pet(pet_name: String, pet_cost: int, dialog: AcceptDialog):
|
||
# 再次检查金钱是否足够
|
||
if main_game.money < pet_cost:
|
||
Toast.show("金钱不足!需要 " + str(pet_cost) + " 元,当前只有 " + str(main_game.money) + " 元", Color.RED, 3.0, 1.0)
|
||
dialog.queue_free()
|
||
return
|
||
|
||
# 发送购买请求到服务器
|
||
_send_buy_pet_request(pet_name, pet_cost)
|
||
init_pet_store()
|
||
dialog.queue_free()
|
||
|
||
# 取消购买宠物
|
||
func _on_cancel_buy_pet(dialog: AcceptDialog):
|
||
print("取消购买宠物")
|
||
dialog.queue_free()
|
||
|
||
# 发送购买宠物请求
|
||
func _send_buy_pet_request(pet_name: String, pet_cost: int):
|
||
# 发送购买请求到服务器
|
||
if tcp_network_manager_panel and tcp_network_manager_panel.has_method("sendBuyPet"):
|
||
if tcp_network_manager_panel.sendBuyPet(pet_name, pet_cost):
|
||
# 服务器会处理购买逻辑,客户端等待响应
|
||
print("已发送购买宠物请求:", pet_name)
|
||
else:
|
||
Toast.show("购买请求发送失败", Color.RED, 2.0, 1.0)
|
||
else:
|
||
Toast.show("网络管理器不可用", Color.RED, 2.0, 1.0)
|
||
|
||
#=========================面板通用处理=========================
|
||
# 手动刷新宠物商店面板
|
||
#刷新按钮点击
|
||
func _on_refresh_button_pressed() -> void:
|
||
# 清空现有配置和请求状态,强制重新获取
|
||
pet_config = {}
|
||
is_requesting_config = false
|
||
# 重新初始化宠物商店
|
||
init_pet_store()
|
||
#Toast.show("宠物商店已刷新", Color.GREEN, 2.0, 1.0)
|
||
|
||
# 关闭宠物商店面板
|
||
func _on_quit_button_pressed() -> void:
|
||
# 打开面板后暂时禁用相机功能
|
||
GlobalVariables.isZoomDisabled = false
|
||
self.hide()
|
||
|
||
#面板显示与隐藏切换处理
|
||
func _on_visibility_changed():
|
||
if visible:
|
||
GlobalVariables.isZoomDisabled = true
|
||
# 面板显示时只在没有配置数据时才请求
|
||
if pet_config.is_empty():
|
||
init_pet_store()
|
||
else:
|
||
# 如果已有配置数据,直接更新UI
|
||
update_pet_store_ui()
|
||
pass
|
||
else:
|
||
GlobalVariables.isZoomDisabled = false
|
||
pass
|
||
#=========================面板通用处理=========================
|