Badminton-Scoreboard/assets/Script/Badminton/Badminton.ts

563 lines
21 KiB
TypeScript
Raw Normal View History

2022-05-02 13:04:23 +00:00
import AvatarPanel from "../AvatarPanel/AvatarPanel";
2022-05-08 12:36:56 +00:00
import CSMessage from "../Common/Message/CSMessage";
2022-05-02 13:04:23 +00:00
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";
2022-05-15 06:34:42 +00:00
import { URLSchemeHandler } from "./URLSchemeHandler";
2022-05-02 13:04:23 +00:00
const { ccclass, property } = cc._decorator;
2022-05-08 12:36:56 +00:00
2022-05-02 13:04:23 +00:00
@ccclass
export class Badminton extends cc.Component {
//#region property
@property({ type: cc.Prefab })
2022-05-15 06:34:42 +00:00
public toggleItem: cc.Prefab = null;
2022-05-02 13:04:23 +00:00
@property({ type: cc.Prefab })
2022-05-15 06:34:42 +00:00
public teamItem: cc.Prefab = null;
2022-05-02 13:04:23 +00:00
@property({ type: cc.EditBox })
2022-05-15 06:34:42 +00:00
public inputNameText: cc.EditBox = null;
2022-05-02 13:04:23 +00:00
@property({ type: cc.Label })
2022-05-15 06:34:42 +00:00
public storageText: cc.Label = null;
2022-05-02 13:04:23 +00:00
@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[] = [];
/** 預設球員(塞空格) */
2022-05-08 12:36:56 +00:00
public DefaultMember: MemberData = new MemberData("那個");
2022-05-02 13:04:23 +00:00
/** RecordManager */
2022-05-08 12:36:56 +00:00
public Record: RecordManager = new RecordManager(this);
2022-05-02 13:04:23 +00:00
/** ConfigManager */
2022-05-08 12:36:56 +00:00
public Config: ConfigManager = new ConfigManager(this);
2022-05-02 13:04:23 +00:00
//#endregion
//#region private
private _m_toggleList: cc.Toggle[] = [];
private _m_teamList: cc.Node[] = [];
/** 各玩家分數比賽次數記錄 */
2022-05-08 12:36:56 +00:00
private _m_results: Map<string, ScoreResult> = new Map<string, ScoreResult>();
2022-05-02 13:04:23 +00:00
/** 比賽歷史記錄(記錄每場次的參賽玩家組合與順序) [{time,team:[[name1,name2],[name3,name4]],type,score:[t1,t2] },] */
private _m_history: GameRecord[] = [];
2022-05-08 12:36:56 +00:00
private _isLoopStartDistribution: boolean = false;
2022-05-02 13:04:23 +00:00
//#endregion
//#region get set
2022-05-08 12:36:56 +00:00
public static get Today(): string { return NodePackageManager.Instance.Dayjs().format("YYYYMMDD"); }
2022-05-02 13:04:23 +00:00
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;
2022-05-05 11:19:28 +00:00
let self: this = this;
2022-05-08 12:36:56 +00:00
new NodePackageManager();
2022-05-02 13:04:23 +00:00
new LocalStorageData();
2022-05-05 11:19:28 +00:00
let AsyncFunction: () => IterableIterator<any> = function* (): IterableIterator<any> {
yield CoroutineV2.Parallel(
2022-05-08 12:36:56 +00:00
self.Config.Init(),
self.Record.Init(),
2022-05-05 11:19:28 +00:00
).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>();
2022-05-15 06:34:42 +00:00
self.HistoryPanel.Initial(self);
2022-05-07 02:54:33 +00:00
self.AvatarPanel.Initial(self);
2022-05-05 11:19:28 +00:00
CoroutineV2.Single(self.Show()).Start();
};
CoroutineV2.Single(AsyncFunction()).Start();
2022-05-02 13:04:23 +00:00
}
2022-05-08 12:36:56 +00:00
protected update(dt: number): void {
if (this._isLoopStartDistribution) {
this.OnClickStartDistribution();
}
}
2022-05-05 11:19:28 +00:00
public *Show(): IterableIterator<any> {
2022-05-02 13:04:23 +00:00
CoroutineV2.Single(this.ScoreBoard.Hide()).Start();
this._initUI();
2022-05-15 06:34:42 +00:00
this.LoadStatus();
// 跨日後計分清除
if (LocalStorageData.Instance.Date !== Badminton.Today) {
cc.warn("跨日後計分清除");
this.OnClickClearAllGameResult();
}
URLSchemeHandler.Init();
2022-05-02 13:04:23 +00:00
}
//#endregion
//#region Custom
private _initUI(): void {
2022-05-05 11:19:28 +00:00
let self: this = this;
2022-05-02 13:04:23 +00:00
this._updateCurSelMember();
// this.toggleItem.gameObject.SetActive(false);
// this.teamItem.gameObject.SetActive(false);
2022-05-07 02:54:33 +00:00
2022-05-02 13:04:23 +00:00
let parent: cc.Node = this.TeamItemContent;
2022-05-07 02:54:33 +00:00
// for (let i: number = parent.childrenCount - 1; i > 0; i--) {
// parent.children[i].destroy();
// }
parent.removeAllChildren();
2022-05-02 13:04:23 +00:00
this._m_teamList.Clear();
parent = this.ToggleItemContent;
2022-05-07 02:54:33 +00:00
// for (let i: number = parent.childrenCount - 1; i > 0; i--) {
// parent.children[i].destroy();
// }
parent.removeAllChildren();
2022-05-02 13:04:23 +00:00
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);
2022-05-05 11:19:28 +00:00
item.node.getChildByName("Name").getComponent(cc.Label).string = memberName;
2022-05-02 13:04:23 +00:00
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) {
2022-05-08 12:36:56 +00:00
picObj.getComponent(cc.Sprite).spriteFrame = this.Config.GetAvatarPicById(this.TeamMemberList[idx].AvatarId);
2022-05-07 02:54:33 +00:00
picObj.parent.getComponent(HoldButton).OnInvoke.AddListener(() => { this.OnChangeAvatar(+idx); });
2022-05-05 11:19:28 +00:00
picObj.parent.on("click", () => {
item.isChecked = !item.isChecked;
self._onChangeSelMember(item);
}, this);
2022-05-02 13:04:23 +00:00
}
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) {
2022-05-05 11:19:28 +00:00
this.CurMemberList.push(member.node.getChildByName("Name").getComponent(cc.Label).string);
2022-05-02 13:04:23 +00:00
}
});
if (this.TeamMemberList != null && this.TeamMemberList.length > 0) {
this.CurMemberList.push(this.GetDefaultMemberName());
}
}
2022-05-08 12:36:56 +00:00
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;
}
2022-05-02 13:04:23 +00:00
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++) {
2022-05-05 11:19:28 +00:00
let memberName: string = team.getChildByName("Member_" + (j + 1)).getChildByName("Name").getComponent(cc.Label).string;
2022-05-02 13:04:23 +00:00
chkMemberList.push(memberName);
}
}
return chkMemberList;
}
public GetDefaultMemberName(): string {
return "那個";
}
private _updateTeamShow(chkMemberList: string[]): void {
2022-05-05 11:19:28 +00:00
let teamCount: number = Math.floor(chkMemberList.length / 2);
2022-05-02 13:04:23 +00:00
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];
}
2022-05-05 11:19:28 +00:00
obj.getChildByName("Member_1").getChildByName("Name").getComponent(cc.Label).string = "";
obj.getChildByName("Member_2").getChildByName("Name").getComponent(cc.Label).string = "";
2022-05-02 13:04:23 +00:00
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);
}
2022-05-05 11:19:28 +00:00
team.getChildByName("Member_" + (j + 1)).getChildByName("Name").getComponent(cc.Label).string = name;
2022-05-02 13:04:23 +00:00
team.getChildByName("Member_" + (j + 1)).getComponent(cc.Sprite).enabled = name !== this.GetDefaultMemberName();
2022-05-08 12:36:56 +00:00
team.getChildByName("Member_" + (j + 1)).getComponent(cc.Sprite).spriteFrame = this.Config.GetAvatarPicByName(name);
2022-05-02 13:04:23 +00:00
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];
2022-05-05 11:19:28 +00:00
team.getChildByName("Member_1").getChildByName("Name").getComponent(cc.Label).string = name_1;
team.getChildByName("Member_2").getChildByName("Name").getComponent(cc.Label).string = name_2;
2022-05-02 13:04:23 +00:00
team.getChildByName("Member_1").getComponent(cc.Sprite).enabled = true;
2022-05-08 12:36:56 +00:00
team.getChildByName("Member_1").getComponent(cc.Sprite).spriteFrame = this.Config.GetAvatarPicByName(name_1);
2022-05-02 13:04:23 +00:00
team.getChildByName("No").getComponent(cc.Label).string = (index + 1).toString();
team.active = true;
}
}
2022-05-08 12:36:56 +00:00
public OnClickCleanTeam(): void {
for (let obj of this._m_toggleList) {
obj.isChecked = false;
this._onChangeSelMember(obj);
}
}
2022-05-02 13:04:23 +00:00
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();
}
}
2022-05-08 12:36:56 +00:00
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();
}
2022-05-02 13:04:23 +00:00
public OnChangeAvatar(index: number): void {
2022-05-07 02:54:33 +00:00
CoroutineV2.Single(this.AvatarPanel.Show(this.TeamMemberList[index])).Start();
2022-05-02 13:04:23 +00:00
}
2022-05-08 12:36:56 +00:00
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;
}
}
2022-05-05 11:19:28 +00:00
public LoadStatus(): void {
2022-05-08 12:36:56 +00:00
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();
2022-05-05 11:19:28 +00:00
}
2022-05-15 06:34:42 +00:00
public OnClickBtn_History(): void {
CoroutineV2.Single(this.HistoryPanel.Show()).Start();
}
public OnClickBtn_Sound(): void {
CoroutineV2.Single(this.VoicePanel.Show()).Start();
}
2022-05-02 13:04:23 +00:00
//#endregion
2022-05-08 12:36:56 +00:00
public Log(a: any, b: any): void {
console.log(b);
}
}