361 lines
12 KiB
C#
361 lines
12 KiB
C#
using Assets.MyGame.Scripts.Net;
|
||
using Newtonsoft.Json;
|
||
using Spine.Unity;
|
||
using System;
|
||
using System.Collections;
|
||
using System.Collections.Generic;
|
||
using TMPro;
|
||
using UnityEngine;
|
||
using UnityEngine.UI;
|
||
using static Assets.MyGame.Scripts.Net.WebResponses.ChineseChess.ChineseChessGameClassList;
|
||
|
||
public class HintData
|
||
{
|
||
public ChessGameRoom roomData;
|
||
public int hintType; //1求和2认输
|
||
}
|
||
|
||
/// <summary>
|
||
/// GoldConfigRequired Socket 推送数据
|
||
/// </summary>
|
||
[Serializable]
|
||
public class GoldConfigRequiredData
|
||
{
|
||
public string targetUserId;
|
||
public ChessGameRoom room;
|
||
}
|
||
|
||
public enum CountdownType
|
||
{
|
||
WaitPlayer, // 等待玩家进入,超时 → 退出到选房
|
||
WaitHostStart, // 等待房主开始游戏,超时 → 退出到选房
|
||
WaitSetCoin, // 等待设置金额,超时 → 退出到选房
|
||
WaitOpponent, // 等待对手操作,超时 → 自动处理
|
||
}
|
||
|
||
public class ChineseChessMainPanel : GameMainPanel_Base
|
||
{
|
||
public Button btn_QiuHe;
|
||
public Button btn_RenShu;
|
||
public Button btn_HuiQi;
|
||
public Button btn_SheZhi;
|
||
public Button btn_GuiZe;
|
||
public Button btn_StartGame;
|
||
public Image img_DengDaiZhong;
|
||
public ChessGameRoom roomData;
|
||
public static Dictionary<string,ChessGameRoom> dic_RoomData=new Dictionary<string, ChessGameRoom>();
|
||
public Button btn_FanHuiDaTing;
|
||
[Header("Bottom")]
|
||
public TextMeshProUGUI tmp_Name_Bottom;
|
||
public TextMeshProUGUI tmp_CoinCount_Bottom;
|
||
public TextMeshProUGUI tmp_WaitTime_Bottom;
|
||
public Image img_Title_Bottom;
|
||
[Header("Top")]
|
||
public TextMeshProUGUI tmp_Name_Top;
|
||
public TextMeshProUGUI tmp_CoinCount_Top;
|
||
public TextMeshProUGUI tmp_WaitTime_Top;
|
||
public Image img_Title_Top;
|
||
|
||
private Coroutine waitCountdown;
|
||
|
||
public SkeletonGraphic skeletonGraphic;
|
||
public string skineName_JinXingZhong;
|
||
public string skineName_KaiShi;
|
||
public string skineName_PiPeiChengGong;
|
||
public string skineName_ZhengZaiPiPei;
|
||
|
||
public string animName_Close;
|
||
public string animName_Open;
|
||
public string animName_Loop;
|
||
|
||
/// <summary>
|
||
/// 加载头像精灵(优先使用缓存,否则异步下载)
|
||
/// </summary>
|
||
public static void LoadAvatar(Image target, string avatarUrl, System.Action<Sprite> onLoaded = null)
|
||
{
|
||
if (target == null) return;
|
||
var sprite = GameManager.Instance.GetAvatarSprite(avatarUrl);
|
||
if (sprite != null)
|
||
{
|
||
target.sprite = sprite;
|
||
onLoaded?.Invoke(sprite);
|
||
return;
|
||
}
|
||
// 缓存未命中,通过 DownSprite 协程异步加载
|
||
GameManager.Instance.StartCoroutine(LoadAvatarCoroutine(target, avatarUrl, onLoaded));
|
||
}
|
||
|
||
private static IEnumerator LoadAvatarCoroutine(Image target, string avatarUrl, System.Action<Sprite> onLoaded)
|
||
{
|
||
// 构造一个临时的 UserBaseInfo 对象来复用 DownSprite 逻辑
|
||
var tempInfo = new UserBaseInfo { avatarUrl = avatarUrl };
|
||
yield return tempInfo.DownSprite(sprite =>
|
||
{
|
||
if (sprite != null && target != null)
|
||
target.sprite = sprite;
|
||
onLoaded?.Invoke(sprite);
|
||
});
|
||
}
|
||
|
||
public static string FormatGold(long gold)
|
||
{
|
||
if (gold >= 100000000)
|
||
{
|
||
// 截取两位小数,不四舍五入
|
||
long yi = gold / 100000000;
|
||
long remainder = gold % 100000000;
|
||
long decimals = remainder * 100 / 100000000;
|
||
if (decimals > 0)
|
||
return $"{yi}.{decimals:D2}亿";
|
||
return $"{yi}亿";
|
||
}
|
||
if (gold >= 10000)
|
||
{
|
||
// 截取两位小数,不四舍五入
|
||
long wan = gold / 10000;
|
||
long remainder = gold % 10000;
|
||
long decimals = remainder * 100 / 10000; // 两位小数
|
||
if (decimals > 0)
|
||
return $"{wan}.{decimals:D2}万";
|
||
return $"{wan}万";
|
||
}
|
||
return gold.ToString();
|
||
}
|
||
|
||
public void StartGame(string msg)
|
||
{
|
||
var va = JsonConvert.DeserializeObject<WebSocketResponseBase<ChessGameRoom>>(msg.ToString());
|
||
ChessGameRoom chessGameRoom = va.arguments[0];
|
||
UpdateUserData(chessGameRoom);
|
||
|
||
switch (chessGameRoom.users.Count)
|
||
{
|
||
case 1:
|
||
{
|
||
tmp_Name_Top.text = "等待玩家进入";
|
||
tmp_CoinCount_Top.text = "";
|
||
img_Title_Top.gameObject.SetActive(false);
|
||
if (tmp_WaitTime_Bottom != null) tmp_WaitTime_Bottom.text = "等待玩家进入02:00";
|
||
if (tmp_WaitTime_Top != null) tmp_WaitTime_Top.text = "等待玩家进入02:00";
|
||
StartWaitCountdown(120, CountdownType.WaitPlayer, "等待玩家进入");
|
||
}
|
||
break;
|
||
case 2:
|
||
{
|
||
StopWaitCountdown();
|
||
img_Title_Top.gameObject.SetActive(true);
|
||
|
||
// 判断是否为房主
|
||
bool isRoomOwner = chessGameRoom.users.Count > 0
|
||
&& chessGameRoom.users[0].userId == GameManager.Instance.user.BaseInfo.number;
|
||
|
||
if (isRoomOwner)
|
||
{
|
||
btn_StartGame.gameObject.SetActive(true);
|
||
btn_StartGame.onClick.RemoveAllListeners();
|
||
btn_StartGame.onClick.AddListener(() =>
|
||
{
|
||
// 房主点击开始 → 发送 StartGame Socket 请求
|
||
btn_StartGame.gameObject.SetActive(false);
|
||
StopWaitCountdown();
|
||
WebSocketSendList.StartGameChineseChess(chessGameRoom.roomId, GameManager.Instance.user.BaseInfo.number);
|
||
});
|
||
}
|
||
else
|
||
{
|
||
btn_StartGame.gameObject.SetActive(false);
|
||
}
|
||
|
||
StartWaitCountdown(60, CountdownType.WaitHostStart, "等待房主开始游戏");
|
||
}
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 服务端推送 GoldConfigRequired → 显示金币设置面板(红方配置)
|
||
/// data: { targetUserId, room }
|
||
/// </summary>
|
||
public void OnGoldConfigRequired(string msg)
|
||
{
|
||
StopWaitCountdown();
|
||
var result = JsonConvert.DeserializeObject<WebSocketResponseBase<GoldConfigRequiredData>>(msg);
|
||
var data = result.arguments[0];
|
||
|
||
// 更新房间数据
|
||
if (data.room != null)
|
||
{
|
||
roomData = data.room;
|
||
UpdateUserData(data.room);
|
||
}
|
||
|
||
// 判断当前用户是否为红方(targetUserId)
|
||
bool isRedSide = data.targetUserId == GameManager.Instance.user.BaseInfo.number;
|
||
if (isRedSide)
|
||
{
|
||
// 红方显示金币设置面板
|
||
subUIManager.ShowAsync(UIPanel.ZGXQSelectCoin, roomData);
|
||
StartWaitCountdown(60, CountdownType.WaitSetCoin, "等待设置金额");
|
||
}
|
||
else
|
||
{
|
||
// 黑方等待红方设置金币
|
||
StartWaitCountdown(60, CountdownType.WaitSetCoin, "等待对方设置金额");
|
||
}
|
||
}
|
||
|
||
public void UpdateUserData(ChessGameRoom chessGameRoom)
|
||
{
|
||
foreach (var item in chessGameRoom.users)
|
||
{
|
||
if (item.userId == GameManager.Instance.user.BaseInfo.number)
|
||
{
|
||
tmp_Name_Bottom.text ="ID:" + item.userId;
|
||
tmp_CoinCount_Bottom.text = FormatGold(item.gold);
|
||
LoadAvatar(img_Title_Bottom, item.userAvatar);
|
||
}
|
||
else
|
||
{
|
||
tmp_Name_Top.text ="ID:" + item.userId;
|
||
tmp_CoinCount_Top.text = FormatGold(item.gold);
|
||
LoadAvatar(img_Title_Top, item.userAvatar);
|
||
}
|
||
}
|
||
}
|
||
|
||
public override void Awake()
|
||
{
|
||
base.Awake();
|
||
btn_FanHuiDaTing.onClick.AddListener(() =>
|
||
{
|
||
UIManager.Instance.Close(UIPanel.MainGamePanelZGXQ);
|
||
});
|
||
btn_GuiZe.onClick.AddListener(() =>
|
||
{
|
||
subUIManager.ShowAsync(UIPanel.ZGXQIntroduce);
|
||
});
|
||
}
|
||
protected override void OnShow(object args = null)
|
||
{
|
||
base.OnShow(args);
|
||
// 回到选房间界面时显示等待中(连带父对象)
|
||
SetDengDaiZhongActive(true);
|
||
subUIManager.ShowAsync(UIPanel.ZGXQDistrict, args);
|
||
}
|
||
/// <summary>
|
||
/// 显示/隐藏等待中(连带控制父对象链)
|
||
/// </summary>
|
||
public void SetDengDaiZhongActive(bool active)
|
||
{
|
||
if (img_DengDaiZhong != null)
|
||
{
|
||
img_DengDaiZhong.gameObject.SetActive(active);
|
||
}
|
||
}
|
||
public void IsShowHint(string id,int type)
|
||
{
|
||
if (GameManager.Instance.user.BaseInfo.number!=id)
|
||
{
|
||
subUIManager.ShowAsync(UIPanel.ZGXQHint, new HintData
|
||
{
|
||
roomData = roomData,
|
||
hintType = type
|
||
});
|
||
}
|
||
}
|
||
public void InitRoomData()
|
||
{
|
||
// 游戏已开始,停止所有倒计时
|
||
StopWaitCountdown();
|
||
|
||
|
||
btn_QiuHe.onClick.RemoveAllListeners();
|
||
btn_RenShu.onClick.RemoveAllListeners();
|
||
btn_QiuHe.onClick.AddListener(() =>
|
||
{
|
||
WebSocketSendList.GameOperationChineseChess(roomData.roomId,1,GameManager.Instance.user.BaseInfo.number);
|
||
|
||
});
|
||
btn_RenShu.onClick.AddListener(() =>
|
||
{
|
||
//WebSocketSendList.GameOperationChineseChess(roomData.roomId, 2, GameManager.Instance.user.BaseInfo.number);
|
||
|
||
subUIManager.ShowAsync(UIPanel.ZGXQHint, new HintData
|
||
{
|
||
roomData = roomData,
|
||
hintType = 2
|
||
});
|
||
});
|
||
}
|
||
|
||
public void Start()
|
||
{
|
||
|
||
}
|
||
|
||
/// <summary>
|
||
/// 开始等待倒计时
|
||
/// </summary>
|
||
/// <param name="seconds">总秒数</param>
|
||
/// <param name="type">倒计时类型</param>
|
||
/// <param name="waitMsg">等待时显示的文字,如"等待玩家进入"</param>
|
||
public void StartWaitCountdown(int seconds, CountdownType type = CountdownType.WaitPlayer, string waitMsg = null)
|
||
{
|
||
if (waitCountdown != null) StopCoroutine(waitCountdown);
|
||
waitCountdown = StartCoroutine(WaitCountdownRoutine(seconds, type, waitMsg));
|
||
}
|
||
|
||
/// <summary>
|
||
/// 停止等待倒计时
|
||
/// </summary>
|
||
public void StopWaitCountdown()
|
||
{
|
||
if (waitCountdown != null)
|
||
{
|
||
StopCoroutine(waitCountdown);
|
||
waitCountdown = null;
|
||
}
|
||
if (tmp_WaitTime_Bottom != null) tmp_WaitTime_Bottom.text = "";
|
||
if (tmp_WaitTime_Top != null) tmp_WaitTime_Top.text = "";
|
||
}
|
||
|
||
private IEnumerator WaitCountdownRoutine(int totalSeconds, CountdownType type, string waitMsg)
|
||
{
|
||
int remaining = totalSeconds;
|
||
while (remaining >= 0)
|
||
{
|
||
string timeStr = $"{remaining / 60:D2}:{remaining % 60:D2}";
|
||
switch (type)
|
||
{
|
||
default:
|
||
string displayText = string.IsNullOrEmpty(waitMsg) ? timeStr : $"{waitMsg}{timeStr}";
|
||
if (tmp_WaitTime_Bottom != null)
|
||
tmp_WaitTime_Bottom.text = displayText;
|
||
if (tmp_WaitTime_Top != null)
|
||
tmp_WaitTime_Top.text = displayText;
|
||
break;
|
||
}
|
||
|
||
yield return new WaitForSeconds(1f);
|
||
remaining--;
|
||
}
|
||
switch (type)
|
||
{
|
||
default:
|
||
// 超时:返回选房间界面
|
||
subUIManager.CloseAll();
|
||
WebSocketSendList.GetRoomListChineseChess(1);
|
||
break;
|
||
}
|
||
}
|
||
|
||
protected override void OnHide()
|
||
{
|
||
base.OnHide();
|
||
WebSocketManager.Instance.Close(SocketType.chess);
|
||
Screen.orientation = ScreenOrientation.LandscapeLeft;
|
||
}
|
||
}
|