You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
AdLike2048/assets/script/ui/PanelSettings/UIPanelSettings.ts

472 lines
14 KiB

3 weeks ago
//*********************
// create by 流云
// time: Thu Mar 06 2025
// desc:
//*********************
import { _decorator, Component, Node, find, sys, game, instantiate, EventTouch, Layout, UITransform, Vec2, Label } from 'cc';
import { Auto_PanelSettings } from './Auto_PanelSettings';
import { StatusType } from '../../game/GameData';
import { TableNames } from '../../game/ConfigTableData';
import { GEvent } from 'db://assets/mx/module/event/GEvent';
import { GM } from '../../game/GM';
import { UIID, GAudioPath } from '../../game/ConfigRes';
import { sdkConfig } from '../../sdk/sdkConfig';
import type { LangCode } from 'db://assets/mx/module/lang/Lang';
import { Lang } from 'db://assets/mx/module/lang/Lang';
import { HeadIconManager } from '../../manager/HeadIconManager';
const { ccclass, property } = _decorator;
@ccclass('UIPanelSettings')
export class UIPanelSettings extends Auto_PanelSettings {
clickTime: number = 0;
btnArray: Node[] = [];
btnKeyArray: string[] = [];
/** 头像列表数据 */
private _headRows: ITableHeadicon[] = [];
/** 当前选中下标(对应 _headRows) */
private _selectedHeadIdx = 0;
/** 头像项模板 */
private _headItemTemplate: Node | null = null;
/** 列表项节点(用于注销点击) */
private _headItemNodes: Node[] = [];
/** 打开时滚到选中项的重试次数 */
private _scrollHeadRetries = 0;
onLoad(): void {
super.onLoad();
}
onEnable(): void {
super.onEnable();
}
onDisable(): void {
this.unschedule(this._scrollHeadListToSelected);
this._scrollHeadRetries = 0;
this._unbindHeadList();
super.onDisable();
}
async onInit(): Promise<void> {
this.ui_boxLang.active = sdkConfig.config.noChangeLang;
if (sdkConfig.config.noChangeLang) {
this.btnKeyArray = [
"cn",
"cn",
"en",
"cn",
"cn",
"cn",
"cn",
"cn",
"cn",
"cn",
]
this.btnArray = [
this.btn_jtzw,
this.btn_fanti,
this.btn_english,
this.btn_hanyu,
this.btn_riben,
this.btn_xibanya,
this.btn_fayu,
this.btn_deyu,
this.btn_eluosi,
this.btn_putaoya,
]
//sdkConfig.defaultLang
this.refreshChangeBtn(false)
}
this.updateBtnStatus();
if (gg.data.doc.roleId == 1) {
this.btn_choseMan.getChildByName('choose').active = true
this.btn_choseWoman.getChildByName('choose').active = false
} else {
this.btn_choseMan.getChildByName('choose').active = false
this.btn_choseWoman.getChildByName('choose').active = true
}
this.btnGM.active = sys.isBrowser || sdkConfig.isOpenGM;
await HeadIconManager.syncUnlocksFromProgressAsync();
await this._buildHeadList();
}
/** 构建 Headicon 头像列表 */
private async _buildHeadList(): Promise<void> {
if (!this.ui_headItem?.isValid || !this.sv_headList?.content) {
console.log('[UIPanelSettings] 头像列表节点缺失');
return;
}
await gg.data.table.ensureTableLoaded(TableNames.Headicon);
this._unbindHeadList();
this._headItemTemplate = this.ui_headItem;
this._headItemTemplate.active = false;
const tplLock = this._findHeadItemLock(this._headItemTemplate);
if (tplLock) tplLock.active = false;
this._headRows = HeadIconManager.getHeadIconList();
if (this._headRows.length <= 0) {
console.log('[UIPanelSettings] Headicon 表无数据');
return;
}
const currentId = HeadIconManager.getPlayerHeadIconId();
const idx = this._headRows.findIndex((row) => row.id === currentId);
this._selectedHeadIdx = idx >= 0 ? idx : 0;
const content = this.sv_headList.content;
content.removeAllChildren();
this._headItemNodes = [];
for (let i = 0; i < this._headRows.length; i++) {
const item = instantiate(this._headItemTemplate);
item.parent = content;
item.setPosition(0, 0, 0);
item.active = true;
this._bindHeadItem(item, i);
this._headItemNodes.push(item);
}
content.getComponent(Layout)?.updateLayout();
this._scrollHeadRetries = 4;
this.scheduleOnce(this._scrollHeadListToSelected, 0);
}
/** 横向列表滚到当前选中头像(布局/弹窗入场后再算偏移) */
private _scrollHeadListToSelected = (): void => {
const sv = this.sv_headList;
const item = this._headItemNodes[this._selectedHeadIdx];
const content = sv?.content;
if (!sv?.isValid || !item?.isValid || !content?.isValid) {
this._scrollHeadRetries = 0;
return;
}
content.getComponent(Layout)?.updateLayout();
const viewUt = sv.node.getComponent(UITransform);
const contentUt = content.getComponent(UITransform);
const itemUt = item.getComponent(UITransform);
if (!viewUt || !contentUt || !itemUt) {
this._scrollHeadRetries = 0;
return;
}
const viewWidth = viewUt.contentSize.width;
const contentWidth = contentUt.contentSize.width;
const maxOffset = sv.getMaxScrollOffset();
if (contentWidth <= viewWidth || maxOffset.x <= 0) {
sv.stopAutoScroll();
sv.scrollToOffset(new Vec2(0, 0), 0);
this._scrollHeadRetries = 0;
return;
}
const itemCenterX = item.position.x;
let offsetX = itemCenterX - viewWidth * 0.5;
offsetX = Math.max(0, Math.min(offsetX, maxOffset.x));
sv.stopAutoScroll();
sv.scrollToOffset(new Vec2(offsetX, 0), 0.25);
this._scrollHeadRetries--;
if (this._scrollHeadRetries > 0) {
this.scheduleOnce(this._scrollHeadListToSelected, 0);
}
};
/** 绑定单个头像项 */
private _bindHeadItem(item: Node, index: number): void {
const row = this._headRows[index];
const select = item.getChildByName('select');
if (select) select.active = index === this._selectedHeadIdx;
const headNode = item.find('headMask/head') ?? item.getChildByName('head');
HeadIconManager.applyRowToNode(headNode, row);
const lockNode = this._findHeadItemLock(item);
if (lockNode) {
const showLock = HeadIconManager.shouldShowLock(row);
lockNode.active = showLock;
const unlockLb = lockNode.getChildByName('unlock')?.getComponent(Label);
if (unlockLb) {
unlockLb.string = showLock ? String(row.desc ?? '').trim() : '';
}
}
item.on(Node.EventType.TOUCH_END, this._onHeadItemTouch, this);
}
/** 查找头像项 lock 节点 */
private _findHeadItemLock(item: Node | null | undefined): Node | null {
if (!item?.isValid) return null;
return item.getChildByName('lock') ?? item.getChildByPath('lock');
}
/** 头像项点击:更新选中下标 */
private _onHeadItemTouch(ev: EventTouch): void {
let node: Node | null = ev.target as Node;
const content = this.sv_headList?.content ?? null;
while (node?.isValid && node !== content) {
const index = this._headItemNodes.indexOf(node);
if (index >= 0) {
const row = this._headRows[index];
if (row && !HeadIconManager.isUnlocked(row)) {
const tip = String(row.desc ?? '').trim();
gg.ui.showToast(tip || '头像未解锁');
return;
}
if (index !== this._selectedHeadIdx) {
this._selectedHeadIdx = index;
this._refreshHeadSelectState();
}
return;
}
node = node.parent;
}
}
/** 刷新列表选中框 */
private _refreshHeadSelectState(): void {
for (let i = 0; i < this._headItemNodes.length; i++) {
const item = this._headItemNodes[i];
if (!item?.isValid) continue;
const select = item.getChildByName('select');
if (select) select.active = i === this._selectedHeadIdx;
}
}
/** 注销头像列表点击 */
private _unbindHeadList(): void {
for (const item of this._headItemNodes) {
if (item?.isValid) {
item.off(Node.EventType.TOUCH_END, this._onHeadItemTouch, this);
}
}
this._headItemNodes = [];
}
click_btnSetting(): void {
const row = this._headRows[this._selectedHeadIdx];
if (!row) {
gg.ui.showToast('请选择头像');
return;
}
if (!HeadIconManager.isUnlocked(row)) {
const tip = String(row.desc ?? '').trim();
gg.ui.showToast(tip || '头像未解锁');
return;
}
HeadIconManager.setPlayerHeadIconId(row.id);
GEvent.Ins.emit(GEvent.UpdateHeadIcon);
this.close(2);
}
refreshChangeBtn(ischange: boolean = true) {
let defaultLang = sdkConfig.defaultLang;
this.btnArray.forEach((btnNode) => {
btnNode.getChildByName('choose').active = false
})
let findKey = 0
for (let i = 0; i < this.btnKeyArray.length; i++) {
if (this.btnKeyArray[i] == defaultLang) {
findKey = i;
break;
}
}
this.btnArray[findKey].getChildByName('choose').active = true
if (ischange) {
gg.lang.Current = defaultLang as LangCode;
}
}
_vibrateOpen = false;
click_btnMusic() {
gg.audio.MuteMusic = !gg.audio.MuteMusic;
gg.data.setStatus(StatusType.MuteMusic, gg.audio.MuteMusic ? 1 : 0);
this.updateBtnStatus();
if (!gg.audio.MuteMusic)
gg.audio.playMusic({ name: "首页背景音", path: GAudioPath.Bgm });
else
gg.audio.stopMusic();
}
click_btnEffect() {
gg.audio.MuteEffect = !gg.audio.MuteEffect;
gg.data.setStatus(StatusType.MuteEffect, gg.audio.MuteEffect ? 1 : 0);
this.updateBtnStatus();
}
click_btnVibrate() {
this._vibrateOpen = !this._vibrateOpen;
gg.sdk.Vibrate.IsEnable = !this._vibrateOpen;
this.updateBtnStatus();
}
click_btnSave() {
gg.data.saveLocal();
gg.data.saveToServer((res) => {
if (res) {
gg.ui.showToast("已保存");
} else {
gg.ui.showToast("保存失败");
}
});
}
click_btnClose() {
this.close(2);
}
updateBtn(btn, status) {
btn.getChildByName("open").active = !status;
btn.getChildByName("close").active = status;
}
click_btnGM() {
GM.show();
this.close(2);
}
click_btnRestart() {
gg.ui.openPanel(UIID.MsgBox, {
data: {
content: "重置将丢失当前游戏进度,重新开始游戏,确定重置吗?",
yesFun: () => {
gg.game.reset('设置重置');
}
}
})
}
updateBtnStatus() {
this.updateBtn(this.btnMusic, gg.audio.MuteMusic);
this.updateBtn(this.btnEffect, gg.audio.MuteEffect);
this.updateBtn(this.btnVibrate, this._vibrateOpen);
}
click_btn1(): void {
// this.time = game.totalTime;
// this.step = 1;
}
click_btn2(): void {
// if (this.step == 1)
// this.step = 2;
}
click_btn3(): void {
// let t = game.totalTime - this.time;
// if (this.step == 2 && t < 1500) {
// GM.show();
// this.close(2);
// }
}
time = 0;
step = 0;
click_btnResetArea() {
this.clickTime++
if (this.clickTime >= 10) {
this.btnRestart.active = true;
}
}
click_bgMask() {
this.close(2);
}
click_btnDuiHuan() {
gg.ui.openPanel(UIID.PanelCDK);
}
click_btn_jtzw() {
sdkConfig.defaultLang = this.btnKeyArray[0];
this.refreshChangeBtn();
}
click_btn_fanti() {
sdkConfig.defaultLang = this.btnKeyArray[1];
this.refreshChangeBtn();
}
click_btn_english() {
sdkConfig.defaultLang = this.btnKeyArray[2];
this.refreshChangeBtn();
}
click_btn_hanyu() {
sdkConfig.defaultLang = this.btnKeyArray[3];
this.refreshChangeBtn();
}
click_btn_riben() {
sdkConfig.defaultLang = this.btnKeyArray[4];
this.refreshChangeBtn();
}
click_btn_xibanya() {
sdkConfig.defaultLang = this.btnKeyArray[5];
this.refreshChangeBtn();
}
click_btn_fayu() {
sdkConfig.defaultLang = this.btnKeyArray[6];
this.refreshChangeBtn();
}
click_btn_deyu() {
sdkConfig.defaultLang = this.btnKeyArray[7];
this.refreshChangeBtn();
}
click_btn_eluosi() {
sdkConfig.defaultLang = this.btnKeyArray[8];
this.refreshChangeBtn();
}
click_btn_putaoya() {
sdkConfig.defaultLang = this.btnKeyArray[9];
this.refreshChangeBtn();
}
click_btn_choseMan() {
let homeShow = gg.ui.panelIsShow(UIID.Home);
if (!homeShow) {
gg.ui.showToast("请切换到战斗界面选择角色");
return;
}
if (gg.data.doc.roleId == 1) {
return;
}
//关闭角色界面
gg.ui.closePanel(UIID.Role);
this.btn_choseMan.getChildByName('choose').active = true
this.btn_choseWoman.getChildByName('choose').active = false
gg.data.doc.roleId = 1
}
click_btn_choseWoman() {
let homeShow = gg.ui.panelIsShow(UIID.Home);
if (!homeShow) {
gg.ui.showToast("请切换到战斗界面选择角色");
return;
}
if (gg.data.doc.roleId == 0) {
return;
}
//关闭角色界面
gg.ui.closePanel(UIID.Role);
this.btn_choseMan.getChildByName('choose').active = false
this.btn_choseWoman.getChildByName('choose').active = true
gg.data.doc.roleId = 0
}
}