563 lines
21 KiB
TypeScript
563 lines
21 KiB
TypeScript
|
|
import AvatarPanel from "../AvatarPanel/AvatarPanel";
|
|
import CSMessage from "../Common/Message/CSMessage";
|
|
import { CoroutineV2 } from "../Engine/CatanEngine/CoroutineV2/CoroutineV2";
|
|
import HoldButton from "../Engine/Component/Button/HoldButton";
|
|
import LocalStorageData from "../Engine/Data/LocalStorageData";
|
|
import HistoryPanel from "../HistoryPanel/HistoryPanel";
|
|
import Lobby from "../Lobby/Lobby";
|
|
import ScoreBoard from "../ScoreBoard/ScoreBoard";
|
|
import VoicePanel from "../VoicePanel/VoicePanel";
|
|
import NodePackageManager from "../_BootLoader/Npm/NodePackageManager";
|
|
import ConfigManager from "./ConfigManager";
|
|
import { GameRecord, MemberData, ScoreResult } from "./MemberData";
|
|
import RecordManager from "./RecordManager";
|
|
import { URLSchemeHandler } from "./URLSchemeHandler";
|
|
|
|
const { ccclass, property } = cc._decorator;
|
|
|
|
@ccclass
|
|
export class Badminton extends cc.Component {
|
|
//#region property
|
|
|
|
@property({ type: cc.Prefab })
|
|
public toggleItem: cc.Prefab = null;
|
|
|
|
@property({ type: cc.Prefab })
|
|
public teamItem: cc.Prefab = null;
|
|
|
|
@property({ type: cc.EditBox })
|
|
public inputNameText: cc.EditBox = null;
|
|
|
|
@property({ type: cc.Label })
|
|
public storageText: cc.Label = null;
|
|
|
|
@property({ type: cc.Node })
|
|
public ToggleItemContent: cc.Node = null;
|
|
|
|
@property({ type: cc.Node })
|
|
public TeamItemContent: cc.Node = null;
|
|
|
|
@property({ type: ScoreBoard })
|
|
public ScoreBoard: ScoreBoard = null;
|
|
|
|
@property({ type: AvatarPanel })
|
|
public AvatarPanel: AvatarPanel = null;
|
|
|
|
@property({ type: HistoryPanel })
|
|
public HistoryPanel: HistoryPanel = null;
|
|
|
|
@property({ type: VoicePanel })
|
|
public VoicePanel: VoicePanel = null;
|
|
|
|
@property({ type: Lobby })
|
|
public Lobby: Lobby = null;
|
|
|
|
// @property({ type: AudioListSwitch })
|
|
// public GameBGM: AudioListSwitch = null;
|
|
|
|
// @property({ type: AudioListSwitch })
|
|
// public TextToSpeech: TextToSpeech { get; private set; }
|
|
|
|
//#endregion
|
|
|
|
//#region 實例
|
|
|
|
/** Badminton實例 */
|
|
private static _instance: Badminton = null;
|
|
public static get Instance(): Badminton { return this._instance; }
|
|
|
|
//#endregion
|
|
|
|
//#region public
|
|
|
|
public TeamMemberList: MemberData[] = [];
|
|
|
|
/** 目前所有可用玩家名單 */
|
|
public CurMemberList: string[] = [];
|
|
|
|
/** 預設球員(塞空格) */
|
|
public DefaultMember: MemberData = new MemberData("那個");
|
|
|
|
/** RecordManager */
|
|
public Record: RecordManager = new RecordManager(this);
|
|
|
|
/** ConfigManager */
|
|
public Config: ConfigManager = new ConfigManager(this);
|
|
|
|
//#endregion
|
|
|
|
//#region private
|
|
|
|
private _m_toggleList: cc.Toggle[] = [];
|
|
|
|
private _m_teamList: cc.Node[] = [];
|
|
|
|
/** 各玩家分數比賽次數記錄 */
|
|
private _m_results: Map<string, ScoreResult> = new Map<string, ScoreResult>();
|
|
|
|
/** 比賽歷史記錄(記錄每場次的參賽玩家組合與順序) [{time,team:[[name1,name2],[name3,name4]],type,score:[t1,t2] },] */
|
|
private _m_history: GameRecord[] = [];
|
|
|
|
private _isLoopStartDistribution: boolean = false;
|
|
|
|
//#endregion
|
|
|
|
//#region get set
|
|
|
|
public static get Today(): string { return NodePackageManager.Instance.Dayjs().format("YYYYMMDD"); }
|
|
|
|
public get TeamCount(): number { return this._m_teamList.length; }
|
|
|
|
/** 比賽歷史記錄(記錄每場次的參賽玩家組合與順序) [{time,team:[[name1,name2],[name3,name4]],type,score:[t1,t2] },] */
|
|
public get History(): GameRecord[] { return this._m_history; }
|
|
|
|
//#endregion
|
|
|
|
//#region 初始化
|
|
|
|
protected onLoad(): void {
|
|
Badminton._instance = this;
|
|
let self: this = this;
|
|
new NodePackageManager();
|
|
new LocalStorageData();
|
|
let AsyncFunction: () => IterableIterator<any> = function* (): IterableIterator<any> {
|
|
yield CoroutineV2.Parallel(
|
|
self.Config.Init(),
|
|
self.Record.Init(),
|
|
).Start();
|
|
CoroutineV2.Parallel(
|
|
self.Lobby.Show(),
|
|
self.ScoreBoard.Show(),
|
|
).Start();
|
|
if (self.HistoryPanel != null) {
|
|
self.HistoryPanel.LoadRecord();
|
|
self.HistoryPanel.Hide();
|
|
CoroutineV2.Single(self.HistoryPanel.Hide()).Start();
|
|
}
|
|
// textToSpeech = FindObjectOfType<TextToSpeech>();
|
|
self.HistoryPanel.Initial(self);
|
|
self.AvatarPanel.Initial(self);
|
|
CoroutineV2.Single(self.Show()).Start();
|
|
};
|
|
CoroutineV2.Single(AsyncFunction()).Start();
|
|
}
|
|
|
|
protected update(dt: number): void {
|
|
if (this._isLoopStartDistribution) {
|
|
this.OnClickStartDistribution();
|
|
}
|
|
}
|
|
|
|
public *Show(): IterableIterator<any> {
|
|
CoroutineV2.Single(this.ScoreBoard.Hide()).Start();
|
|
this._initUI();
|
|
this.LoadStatus();
|
|
// 跨日後計分清除
|
|
if (LocalStorageData.Instance.Date !== Badminton.Today) {
|
|
cc.warn("跨日後計分清除");
|
|
this.OnClickClearAllGameResult();
|
|
}
|
|
URLSchemeHandler.Init();
|
|
}
|
|
|
|
//#endregion
|
|
|
|
//#region Custom
|
|
|
|
private _initUI(): void {
|
|
let self: this = this;
|
|
this._updateCurSelMember();
|
|
// this.toggleItem.gameObject.SetActive(false);
|
|
// this.teamItem.gameObject.SetActive(false);
|
|
|
|
let parent: cc.Node = this.TeamItemContent;
|
|
// for (let i: number = parent.childrenCount - 1; i > 0; i--) {
|
|
// parent.children[i].destroy();
|
|
// }
|
|
parent.removeAllChildren();
|
|
this._m_teamList.Clear();
|
|
|
|
parent = this.ToggleItemContent;
|
|
// for (let i: number = parent.childrenCount - 1; i > 0; i--) {
|
|
// parent.children[i].destroy();
|
|
// }
|
|
parent.removeAllChildren();
|
|
this._m_toggleList.Clear();
|
|
|
|
for (let idx: number = 0; idx < this.TeamMemberList.length; idx++) {
|
|
let memberName: string = this.TeamMemberList[idx].Name;
|
|
let item: cc.Toggle = parent.ExAddChild(this.toggleItem).getComponent(cc.Toggle);
|
|
item.node.getChildByName("Name").getComponent(cc.Label).string = memberName;
|
|
item.node.active = true;
|
|
item.node.getChildByName("Btn_Del").on("click", () => { this.OnDelMember(idx); }, this);
|
|
let picObj: cc.Node = item.node.getChildByName("Avatar").getChildByName("Pic");
|
|
if (picObj != null) {
|
|
picObj.getComponent(cc.Sprite).spriteFrame = this.Config.GetAvatarPicById(this.TeamMemberList[idx].AvatarId);
|
|
picObj.parent.getComponent(HoldButton).OnInvoke.AddListener(() => { this.OnChangeAvatar(+idx); });
|
|
picObj.parent.on("click", () => {
|
|
item.isChecked = !item.isChecked;
|
|
self._onChangeSelMember(item);
|
|
}, this);
|
|
}
|
|
this._m_toggleList.push(item);
|
|
|
|
item.isChecked = this.CurMemberList.indexOf(memberName) !== -1;
|
|
item.node.on("toggle", this._onChangeSelMember, this);
|
|
}
|
|
}
|
|
|
|
public ReloadUI(): void {
|
|
let chkMemberList: string[] = this.GetMemberListFromTeamView();
|
|
this._initUI();
|
|
this._updateTeamShow(chkMemberList);
|
|
}
|
|
|
|
private _onChangeSelMember(toggle: cc.Toggle): void {
|
|
let val: boolean = toggle.isChecked;
|
|
this._updateCurSelMember();
|
|
let chkMemberList: string[] = this.GetMemberListFromTeamView();
|
|
let dName: string = this.GetDefaultMemberName();
|
|
let selName: string = null;
|
|
if (val) {
|
|
for (let i: number = 0; i < this.CurMemberList.length; i++) {
|
|
if (chkMemberList.indexOf(this.CurMemberList[i]) === -1) {
|
|
selName = this.CurMemberList[i];
|
|
break;
|
|
}
|
|
}
|
|
for (let i: number = 0; i < chkMemberList.length; i++) {
|
|
if (chkMemberList[i] === dName) {
|
|
chkMemberList[i] = selName;
|
|
this._updateTeamShow(chkMemberList);
|
|
return;
|
|
}
|
|
|
|
}
|
|
|
|
if (selName != null) {
|
|
chkMemberList.push(selName);
|
|
}
|
|
this._updateTeamShow(chkMemberList);
|
|
} else {
|
|
for (let i: number = 0; i < chkMemberList.length; i++) {
|
|
if (this.CurMemberList.indexOf(chkMemberList[i]) === -1) {
|
|
selName = chkMemberList[i];
|
|
if (i === chkMemberList.length - 1) {
|
|
chkMemberList.ExRemoveAt(chkMemberList.length - 1);
|
|
} else { chkMemberList[i] = this.GetDefaultMemberName(); }
|
|
|
|
this._updateTeamShow(chkMemberList);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private _updateCurSelMember(): void {
|
|
this.CurMemberList.Clear();
|
|
this._m_toggleList.forEach((member: cc.Toggle) => {
|
|
if (member.isChecked) {
|
|
this.CurMemberList.push(member.node.getChildByName("Name").getComponent(cc.Label).string);
|
|
}
|
|
});
|
|
if (this.TeamMemberList != null && this.TeamMemberList.length > 0) {
|
|
this.CurMemberList.push(this.GetDefaultMemberName());
|
|
}
|
|
}
|
|
|
|
public OnClickStartDistribution(): void {
|
|
this.CurMemberList.Clear();
|
|
let chkMemberList: string[] = [];
|
|
for (let member of this._m_toggleList) {
|
|
if (member.isChecked) {
|
|
chkMemberList.push(member.node.getChildByName("Name").getComponent(cc.Label).string);
|
|
}
|
|
}
|
|
chkMemberList = this.GetListRandomize(chkMemberList);
|
|
this._updateTeamShow(chkMemberList);
|
|
}
|
|
|
|
public OnClickLoopStartDistribution(): void {
|
|
this._isLoopStartDistribution = !this._isLoopStartDistribution;
|
|
}
|
|
|
|
public GetMemberListFromTeamView(): string[] {
|
|
let chkMemberList: string[] = [];
|
|
for (let i: number = 0; i < this._m_teamList.length; i++) {
|
|
let team: cc.Node = this._m_teamList[i];
|
|
if (!team.active) {
|
|
break;
|
|
}
|
|
for (let j: number = 0; j < 2; j++) {
|
|
let memberName: string = team.getChildByName("Member_" + (j + 1)).getChildByName("Name").getComponent(cc.Label).string;
|
|
chkMemberList.push(memberName);
|
|
}
|
|
}
|
|
|
|
return chkMemberList;
|
|
}
|
|
|
|
public GetDefaultMemberName(): string {
|
|
return "那個";
|
|
}
|
|
|
|
private _updateTeamShow(chkMemberList: string[]): void {
|
|
let teamCount: number = Math.floor(chkMemberList.length / 2);
|
|
let maxTeam: number = Math.ceil(chkMemberList.length / 2.0);
|
|
while (this._m_teamList.length > maxTeam) {
|
|
this._m_teamList[this._m_teamList.length - 1].destroy();
|
|
this._m_teamList.ExRemoveAt(this._m_teamList.length - 1);
|
|
}
|
|
if (maxTeam === 0 || (chkMemberList.length === 1 && chkMemberList[0] === this.GetDefaultMemberName())) {
|
|
return;
|
|
}
|
|
for (let i: number = 0; i < maxTeam; i++) {
|
|
let obj: cc.Node;
|
|
if (i >= this._m_teamList.length) {
|
|
obj = this.TeamItemContent.ExAddChild(this.teamItem);
|
|
this._m_teamList.push(obj);
|
|
} else {
|
|
obj = this._m_teamList[i];
|
|
}
|
|
obj.getChildByName("Member_1").getChildByName("Name").getComponent(cc.Label).string = "";
|
|
obj.getChildByName("Member_2").getChildByName("Name").getComponent(cc.Label).string = "";
|
|
obj.getChildByName("Member_1").getComponent(cc.Sprite).enabled = false;
|
|
obj.getChildByName("Member_2").getComponent(cc.Sprite).enabled = false;
|
|
obj.active = false;
|
|
}
|
|
|
|
let index: number = 0;
|
|
for (let idx: number = 0; idx < teamCount && idx < maxTeam; idx++) {
|
|
if (chkMemberList[0] === chkMemberList[1] && chkMemberList[0] === this.GetDefaultMemberName()) {
|
|
chkMemberList.splice(0, 2);
|
|
continue;
|
|
}
|
|
let team: cc.Node = this._m_teamList[index++];
|
|
team.getChildByName("No").getComponent(cc.Label).string = index.toString();
|
|
for (let j: number = 0; j < 2; j++) {
|
|
let name: string = chkMemberList[0];
|
|
if (j === 0 && name === this.GetDefaultMemberName()) {
|
|
name = chkMemberList[1];
|
|
chkMemberList.ExRemoveAt(1);
|
|
} else {
|
|
chkMemberList.ExRemoveAt(0);
|
|
}
|
|
|
|
team.getChildByName("Member_" + (j + 1)).getChildByName("Name").getComponent(cc.Label).string = name;
|
|
team.getChildByName("Member_" + (j + 1)).getComponent(cc.Sprite).enabled = name !== this.GetDefaultMemberName();
|
|
team.getChildByName("Member_" + (j + 1)).getComponent(cc.Sprite).spriteFrame = this.Config.GetAvatarPicByName(name);
|
|
team.active = true;
|
|
}
|
|
}
|
|
if (chkMemberList.length > 0 && teamCount < maxTeam) {
|
|
let name_1: string = chkMemberList[0];
|
|
let name_2: string = this.GetDefaultMemberName();
|
|
let team: cc.Node = this._m_teamList[teamCount];
|
|
team.getChildByName("Member_1").getChildByName("Name").getComponent(cc.Label).string = name_1;
|
|
team.getChildByName("Member_2").getChildByName("Name").getComponent(cc.Label).string = name_2;
|
|
team.getChildByName("Member_1").getComponent(cc.Sprite).enabled = true;
|
|
team.getChildByName("Member_1").getComponent(cc.Sprite).spriteFrame = this.Config.GetAvatarPicByName(name_1);
|
|
team.getChildByName("No").getComponent(cc.Label).string = (index + 1).toString();
|
|
team.active = true;
|
|
}
|
|
}
|
|
|
|
public OnClickCleanTeam(): void {
|
|
for (let obj of this._m_toggleList) {
|
|
obj.isChecked = false;
|
|
this._onChangeSelMember(obj);
|
|
}
|
|
}
|
|
|
|
public OnDelMember(index: number): void {
|
|
let viewTeamList: string[] = this.GetMemberListFromTeamView();
|
|
let player: MemberData = this.TeamMemberList[index];
|
|
let teamIndex: number = viewTeamList.indexOf(player.Name);
|
|
if (teamIndex !== -1) { viewTeamList[teamIndex] = this.GetDefaultMemberName(); }
|
|
this.TeamMemberList.ExRemoveAt(index);
|
|
this._initUI();
|
|
this._updateTeamShow(viewTeamList);
|
|
if (teamIndex !== -1) {
|
|
this._updateCurSelMember();
|
|
}
|
|
}
|
|
|
|
public GetListRandomize(list: any[]): any[] {
|
|
list.sort(function (): number {
|
|
return (0.5 - Math.random());
|
|
});
|
|
return list;
|
|
}
|
|
|
|
public OnClickAddMember(): void {
|
|
let newName: string = this.inputNameText.string;
|
|
if (String.IsNullOrWhiteSpace(newName)) {
|
|
return;
|
|
}
|
|
let members: string[] = this.TeamMemberList.map(m => m.Name);
|
|
if (members.includes(newName)) {
|
|
CSMessage.CreateYesMsg(newName + "已經在名單內");
|
|
return;
|
|
}
|
|
this.TeamMemberList.push(new MemberData(newName));
|
|
this.inputNameText.string = "";
|
|
let viewTeamList: string[] = this.GetMemberListFromTeamView();
|
|
this._initUI();
|
|
this._updateTeamShow(viewTeamList);
|
|
this._updateGameResult();
|
|
}
|
|
|
|
public OnChangeAvatar(index: number): void {
|
|
CoroutineV2.Single(this.AvatarPanel.Show(this.TeamMemberList[index])).Start();
|
|
}
|
|
|
|
public SaveStatus(): void {
|
|
// member
|
|
let member_list: string[] = this.GetMemberListFromTeamView();
|
|
LocalStorageData.Instance.Member = member_list;
|
|
|
|
let avatar_list: number[] = member_list.map(m => this.Config.GetAvatarDataByName(m).ID);
|
|
LocalStorageData.Instance.Avatar = avatar_list;
|
|
|
|
LocalStorageData.Instance.IsSingleMode = this.ScoreBoard.isSingleMode ? 1 : 0;
|
|
let selected_list: string[] = this.ScoreBoard.selectedList;
|
|
LocalStorageData.Instance.Selected = selected_list;
|
|
|
|
let firstTeam: number = this.ScoreBoard.firstTeam;
|
|
LocalStorageData.Instance.FirstTeam = firstTeam;
|
|
|
|
// TODO ScoreBoard
|
|
// let score_list = this.ScoreBoard.GetScoreWinList();
|
|
// LocalStorageData.Instance.Score = score_list;
|
|
|
|
let result_dict: Map<string, Object> = new Map<string, Object>();
|
|
this._m_results.forEach((item: ScoreResult, key: string, map: Map<string, ScoreResult>) => {
|
|
let obj: Object = {
|
|
win: item.Win,
|
|
total: item.Total,
|
|
};
|
|
result_dict.set(key, obj);
|
|
});
|
|
LocalStorageData.Instance.Results = result_dict;
|
|
// // 增加紀錄日期
|
|
LocalStorageData.Instance.Date = Badminton.Today;
|
|
|
|
if (this.HistoryPanel != null) {
|
|
// 增加隊伍歷史紀錄
|
|
// 格式 json: {"日期":[玩家1,玩家2,...],"日期":[玩家1,玩家2,...]}
|
|
let history_dict: Map<string, string[]> = this.HistoryPanel.History;
|
|
LocalStorageData.Instance.HistoryTeam = history_dict;
|
|
}
|
|
}
|
|
|
|
public LoadStatus(): void {
|
|
console.log("LoadStatus ======= ");
|
|
try {
|
|
let members: string[] = this.TeamMemberList.map(m => m.Name);
|
|
let member_list: string[] = LocalStorageData.Instance.Member;
|
|
let avatar_list: number[] = LocalStorageData.Instance.Avatar;
|
|
for (let i: number = 0; i < member_list.length; i++) {
|
|
let member: string = member_list[i];
|
|
if (!members.includes(member)) {
|
|
if (member !== this.GetDefaultMemberName()) {
|
|
this.TeamMemberList.push(new MemberData(member, avatar_list[i]));
|
|
}
|
|
} else {
|
|
this.TeamMemberList.find((m) => m.Name === member).AvatarId = avatar_list[i];
|
|
}
|
|
}
|
|
this.CurMemberList.Clear();
|
|
for (const members of this._m_toggleList) {
|
|
members.isChecked = false;
|
|
}
|
|
this.CurMemberList = member_list.Copy();
|
|
this._initUI();
|
|
|
|
for (let i: number = 0; i < member_list.length; i++) {
|
|
let member: string = member_list[i];
|
|
let index: number = members.indexOf(member);
|
|
if (index !== -1) {
|
|
this._m_toggleList[index].isChecked = true;
|
|
this._onChangeSelMember(this._m_toggleList[index]);
|
|
} else {
|
|
// 那個
|
|
}
|
|
}
|
|
this._updateTeamShow(member_list);
|
|
this._loadScoreResult();
|
|
// TODO voicePanel
|
|
// voicePanel.SetProps(MiniJSON.Json.Deserialize(PlayerPrefs.GetString("voice", "null")) as Dictionary<string, object>);
|
|
this._updateGameResult();
|
|
} catch (err: any) {
|
|
console.log(err);
|
|
}
|
|
}
|
|
|
|
private _loadScoreResult(): void {
|
|
let self: this = this;
|
|
this.ScoreBoard.isSingleMode = LocalStorageData.Instance.IsSingleMode === 1;
|
|
|
|
let selected_list: string[] = LocalStorageData.Instance.Selected;
|
|
|
|
if (selected_list.length > 0) {
|
|
// TODO ScoreBoard
|
|
// this.ScoreBoard.ResetScore();
|
|
// this.ScoreBoard.SetPlayerList(selected_list);
|
|
|
|
let firstTeam: number = LocalStorageData.Instance.FirstTeam;
|
|
this.ScoreBoard.firstTeam = firstTeam;
|
|
|
|
// TODO ScoreBoard
|
|
// if (firstTeam !== -1) {
|
|
// let score_list: number[] = LocalStorageData.Instance.Score;
|
|
// this.ScoreBoard.SetScoreWinList(score_list);
|
|
// }
|
|
}
|
|
this._m_results.clear();
|
|
let result_list: Map<string, Object> = LocalStorageData.Instance.Results;
|
|
if (result_list.size > 0) {
|
|
result_list.forEach((item: Object, key: string) => {
|
|
let val: Object = item;
|
|
let result: ScoreResult = new ScoreResult(+item["win"], +item["total"]);
|
|
self._m_results.set(key, result);
|
|
this.Config.GetMemberDataByName(key).Score = result;
|
|
});
|
|
}
|
|
}
|
|
|
|
private _updateGameResult(): void {
|
|
let self: this = this;
|
|
this._m_toggleList.forEach((member: cc.Toggle, index: number, array: cc.Toggle[]) => {
|
|
if (self._m_results.has(member.node.Find("Name").getComponent(cc.Label).string)) {
|
|
let result: ScoreResult = self._m_results.get(member.node.Find("Name").getComponent(cc.Label).string);
|
|
member.node.Find("Score").getComponent(cc.Label).string = "" + result.Total;
|
|
} else {
|
|
member.node.Find("Score").getComponent(cc.Label).string = "";
|
|
}
|
|
});
|
|
}
|
|
|
|
public OnClickClearAllGameResult(): void {
|
|
this._m_results.clear();
|
|
this._m_history.Clear();
|
|
this._updateGameResult();
|
|
// 清除計分後 寫入紀錄
|
|
this.SaveStatus();
|
|
}
|
|
|
|
public OnClickBtn_History(): void {
|
|
CoroutineV2.Single(this.HistoryPanel.Show()).Start();
|
|
}
|
|
|
|
public OnClickBtn_Sound(): void {
|
|
CoroutineV2.Single(this.VoicePanel.Show()).Start();
|
|
}
|
|
|
|
//#endregion
|
|
|
|
public Log(a: any, b: any): void {
|
|
console.log(b);
|
|
}
|
|
|
|
} |