add: channel switch

This commit is contained in:
Vick Scarlet
2026-08-16 20:06:16 +08:00
committed by 神戸小鳥
parent ce74c5221f
commit 4307904239
16 changed files with 484 additions and 524 deletions
+6
View File
@@ -4,6 +4,12 @@
// 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387 // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0", "version": "0.2.0",
"configurations": [ "configurations": [
{
"name": "Launch Editor Browser",
"request": "launch",
"type": "editor-browser",
"url": "http://localhost:5173",
},
{ {
"type": "node", "type": "node",
"request": "launch", "request": "launch",
+1 -9
View File
@@ -15,21 +15,13 @@
<meta name="laya" screenorientation ="landscape"/> <meta name="laya" screenorientation ="landscape"/>
<meta http-equiv="expires" content="0"/> <meta http-equiv="expires" content="0"/>
<meta http-equiv="Cache-Control" content="no-siteapp"/> <meta http-equiv="Cache-Control" content="no-siteapp"/>
<font-face font-family="方正像素12" src="fonts/方正像素12.ttf"/>
<title>Life Restart</title> <title>Life Restart</title>
<!--
<script type="text/javascript" src="libs/laya/laya.core.js"></script>
<script type="text/javascript" src="libs/laya/laya.webgl.js"></script>
<script type="text/javascript" src="libs/laya/laya.filter.js"></script>
<script type="text/javascript" src="libs/laya/laya.html.js"></script>
<script type="text/javascript" src="libs/laya/laya.particle.js"></script>
<script type="text/javascript" src="libs/laya/laya.ui.js"></script>
-->
<script type="text/javascript" src="libs/laya/min/laya.core.min.js"></script> <script type="text/javascript" src="libs/laya/min/laya.core.min.js"></script>
<script type="text/javascript" src="libs/laya/min/laya.webgl.min.js"></script> <script type="text/javascript" src="libs/laya/min/laya.webgl.min.js"></script>
<script type="text/javascript" src="libs/laya/min/laya.filter.min.js"></script> <script type="text/javascript" src="libs/laya/min/laya.filter.min.js"></script>
<script type="text/javascript" src="libs/laya/min/laya.particle.min.js"></script> <script type="text/javascript" src="libs/laya/min/laya.particle.min.js"></script>
<script type="text/javascript" src="libs/laya/min/laya.ui.min.js"></script> <script type="text/javascript" src="libs/laya/min/laya.ui.min.js"></script>
<script type="module" src="public/channel.js"></script>
<script type="module" src="src/index.js"></script> <script type="module" src="src/index.js"></script>
</head> </head>
<body style="background:black"></body> <body style="background:black"></body>
+1
View File
@@ -0,0 +1 @@
globalThis.$channel = {}
+86 -89
View File
@@ -1,179 +1,176 @@
import './ui/laya.patch.js'; import './ui/laya.patch.js'
import './ui/runtime.js'; import './ui/runtime.js'
import './ui/pluginFunction.js' import './ui/pluginFunction.js'
import './ui/promisesLaya.js' import './ui/promisesLaya.js'
import './ui/layaUI.max.all.js'; import './ui/layaUI.max.all.js'
import UIManager from './ui/uiManager.js'; import UIManager from './ui/uiManager.js'
import * as utils from './functions/util.js'; import * as utils from './functions/util.js'
globalThis.UIManager = globalThis.UIManager = globalThis.UI = UIManager
globalThis.UI =
UIManager;
globalThis.$_ = utils; globalThis.$_ = utils
globalThis.goto = async tag => { globalThis.goto = async tag => {
let url; let url
switch (tag) { switch (tag) {
case 'github': url = 'https://github.com/VickScarlet/lifeRestart'; break; case 'github': url = 'https://github.com/VickScarlet/lifeRestart'; break
case 'discord': url = 'https://discord.gg/U3qrf49NMQ'; break; case 'discord': url = 'https://discord.gg/U3qrf49NMQ'; break
case 'sponsor_afd': url = 'https://afdian.com/a/LifeRestart'; break; case 'sponsor_afd': url = 'https://afdian.com/a/LifeRestart'; break
case 'sponsor_ddf': url = 'https://dun.mianbaoduo.com/@vickscarlet'; break; case 'sponsor_ddf': url = 'https://dun.mianbaoduo.com/@vickscarlet'; break
} }
try { try {
if (Laya.Browser.onIOS) { if (Laya.Browser.onIOS) {
window.location.href = url; window.location.href = url
} else { } else {
window.open(url, '_blank'); window.open(url, '_blank')
} }
} catch (error) { } catch (error) {
console.error(error); console.error(error)
} }
} }
class App { class App {
name = 'lifeRestart'
version = '2.1.0'
constructor() { constructor() {
this.name = 'lifeRestart'; console.log(`${this.name} ${this.version}`)
this.version = '2.0.0';
console.log(`${this.name} ${this.version}`);
} }
#language; #language
static languages = { static languages = {
'zh-cn': 'zh-cn', 'zh-cn': 'zh-cn',
'en-us': 'en-us', 'en-us': 'en-us',
}; }
#initLaya() { #initLaya() {
/** /**
*...特殊的字符,如泰文,必须重新实现这个类 *...特殊的字符,如泰文,必须重新实现这个类
*/ */
//class laya.webgl.text.CharSegment //class laya.webgl.text.CharSegment
class CharSegment { class CharSegment {
constructor() { _sourceStr = null
this._sourceStr = null; constructor() {}
}
textToSpit(str) { textToSpit(str) {
this._sourceStr = str; this._sourceStr = str
var texLen = str.length; const texLen = str.length
var idx = -1; let idx = -1
this._words = []; this._words = []
while (++idx < texLen) { while (++idx < texLen) {
var character = str.charAt(idx); const character = str.charAt(idx)
var code = str.charCodeAt(idx); const code = str.codePointAt(idx)
if (code >= 0xD800 && code <= 0xDBFF) { if (code >= 0xd800 && code <= 0xdbff) {
this._words.push(character + str.charAt(++idx)); this._words.push(character + str.charAt(++idx))
} else { } else {
this._words.push(character); this._words.push(character)
} }
} }
} }
getChar(i) { getChar(i) {
return this._words; return this._words
} }
getCharCode(i) { getCharCode(i) {
return this._words[i].codePointAt(0); return this._words[i].codePointAt(0)
} }
length() { length() {
return this._words.length; return this._words.length
} }
} }
Laya.class(CharSegment, 'laya.webgl.text.CharSegment'); Laya.class(CharSegment, 'laya.webgl.text.CharSegment')
Laya.imps(CharSegment.prototype, { "laya.webgl.text.ICharSegment": true }) Laya.imps(CharSegment.prototype, { 'laya.webgl.text.ICharSegment': true })
// Laya.init(1125, 2436, Laya.WebGL); // Laya.init(1125, 2436, Laya.WebGL);
Laya.Config.isAntialias = true; Laya.Config.isAntialias = true
Laya.init(...this.#fitScreen, Laya.WebGL); Laya.init(...this.#fitScreen, Laya.WebGL)
Laya.stage.alignV = Laya.Stage.ALIGN_MIDDLE; Laya.stage.alignV = Laya.Stage.ALIGN_MIDDLE
Laya.stage.alignH = Laya.Stage.ALIGN_CENTER; Laya.stage.alignH = Laya.Stage.ALIGN_CENTER
Laya.stage.scaleMode = "showall"; Laya.stage.scaleMode = 'showall'
Laya.stage.bgColor = "#000000"; Laya.stage.bgColor = '#000000'
window.onresize = () => Laya.stage.size(...this.#fitScreen); window.onresize = () => Laya.stage.size(...this.#fitScreen)
} }
get #fitScreen() { get #fitScreen() {
const designWidth = 1125; const designWidth = 1125
const designHeight = 2436; const designHeight = 2436
const maxWidth = designHeight * 3 / 4; const maxWidth = (designHeight * 3) / 4
const maxHeight = designWidth * 24 / 9; const maxHeight = (designWidth * 24) / 9
const designRatio = designWidth / designHeight; const designRatio = designWidth / designHeight
const screenWidth = window.innerWidth; const screenWidth = window.innerWidth
const screenHeight = window.innerHeight; const screenHeight = window.innerHeight
const screenRatio = screenWidth / screenHeight; const screenRatio = screenWidth / screenHeight
if (screenRatio > designRatio) { if (screenRatio > designRatio) {
return [ return [
Math.min(screenWidth * designHeight / screenHeight, maxWidth), Math.min((screenWidth * designHeight) / screenHeight, maxWidth),
designHeight designHeight,
] ]
} else { } else {
return [ return [
designWidth, designWidth,
Math.min(screenHeight * designWidth / screenWidth, maxHeight) Math.min((screenHeight * designWidth) / screenWidth, maxHeight),
] ]
} }
} }
async setLanguage(language) { async setLanguage(language) {
return this.#setLanguage(language); return this.#setLanguage(language)
} }
async #setLanguage(language) { async #setLanguage(language) {
switch (language) { switch (language) {
case App.languages['en-us']: case App.languages['en-us']:
case App.languages['zh-cn']: case App.languages['zh-cn']:
this.#language = language; this.#language = language
break; break
default: default:
this.#language = App.languages['zh-cn']; this.#language = App.languages['zh-cn']
break; break
} }
globalThis.$lang = globalThis.$lang =
Laya.Text.langPacks = Laya.Text.langPacks =
(await import(`./i18n/${this.#language}.js`)).default; (await import(`./i18n/${this.#language}.js`)).default
} }
resigterEvent() { resigterEvent() {
$$on('achievement', achievement => { $$on('achievement', achievement => {
$ui.popup(UI.popups.ACHIEVEMENT, { achievement }); $ui.popup(UI.popups.ACHIEVEMENT, { achievement })
}) })
$$on('message', ([message, ...args]) => { $$on('message', ([message, ...args]) => {
if (Array.isArray(message)) { if (Array.isArray(message)) {
message = message.map(([m, ...a]) => $_.format($lang[m], ...a)).join('\n'); message = message.map(([m, ...a]) => $_.format($lang[m], ...a)).join('\n')
} else { } else {
message = $_.format( message = $_.format($lang[message], ...args)
$lang[message], ...args
);
} }
$ui.popup(UI.popups.MESSAGE, { message }); $ui.popup(UI.popups.MESSAGE, { message })
}) })
} }
async start({ async start(
language = App.languages['zh-cn'], { language = App.languages['zh-cn'], theme = 'default' },
theme = 'default', features = [],
}) { ) {
this.resigterEvent(); this.resigterEvent()
this.#initLaya(); this.#initLaya()
globalThis.$ui = UIManager.getInstance(); globalThis.$ui = UIManager.getInstance()
if (theme == 'default') { if (theme == 'default') {
theme = localStorage.getItem('theme') || 'default'; theme = localStorage.getItem('theme') || 'default'
} }
$ui.theme = theme; $ui.theme = theme
await this.#setLanguage(language); await this.#setLanguage(language)
await $ui.setLoading(UI.pages.LOADING); await $ui.setLoading(UI.pages.LOADING)
await $ui.switchView(UI.pages.LOADING); await $ui.switchView(UI.pages.LOADING)
await core.initial( await core.initial(
dataSet => Laya.promises.loader.load(`data/${this.#language}/${dataSet}.json`, null, Laya.Loader.JSON), dataSet => Laya.promises.loader.load(`data/${this.#language}/${dataSet}.json`, null, Laya.Loader.JSON),
dataSet => Laya.promises.loader.load(`data/${dataSet}.json`, null, Laya.Loader.JSON), dataSet => Laya.promises.loader.load(`data/${dataSet}.json`, null, Laya.Loader.JSON),
); )
await $ui.switchView(UI.pages.MAIN); await $ui.switchView(UI.pages.MAIN)
for (const { feature, options } of features) {
const f = await import(`./features/${feature}.js`)
await f.default(options)
}
} }
} }
export default App; export default App
+79 -82
View File
@@ -1,127 +1,124 @@
function parseCondition(condition) { function parseCondition(condition) {
const conditions = []
const conditions = []; const length = condition.length
const length = condition.length; const stack = []
const stack = []; stack.unshift(conditions)
stack.unshift(conditions); let cursor = 0
let cursor = 0;
const catchString = i => { const catchString = i => {
const str = condition.substring(cursor, i).trim(); const str = condition.substring(cursor, i).trim()
cursor = i; cursor = i
if(str) stack[0].push(str); if (str) stack[0].push(str)
}; }
for(let i=0; i<length; i++) { for (let i = 0; i < length; i++) {
switch(condition[i]) { switch (condition[i]) {
case ' ': continue; case ' ': continue
case '(':
catchString(i);
cursor ++;
const sub = [];
stack[0].push(sub);
stack.unshift(sub);
break;
case '(': {
catchString(i)
cursor++
const sub = []
stack[0].push(sub)
stack.unshift(sub)
break
}
case ')': case ')':
catchString(i); catchString(i)
cursor ++; cursor++
stack.shift(); stack.shift()
break; break
case '|': case '|':
case '&': case '&':
catchString(i); catchString(i)
catchString(i+1); catchString(i + 1)
break; break
default: continue; default: continue
} }
} }
catchString(length); catchString(length)
return conditions; return conditions
} }
export function checkCondition(property, condition) { export function checkCondition(property, condition) {
const conditions = parseCondition(condition); const conditions = parseCondition(condition)
return checkParsedConditions(property, conditions); return checkParsedConditions(property, conditions)
} }
function checkParsedConditions(property, conditions) { function checkParsedConditions(property, conditions) {
if(!Array.isArray(conditions)) return checkProp(property, conditions); if (!Array.isArray(conditions)) return checkProp(property, conditions)
if(conditions.length == 0) return true; if (conditions.length == 0) return true
if(conditions.length == 1) return checkParsedConditions(property, conditions[0]); if (conditions.length == 1) return checkParsedConditions(property, conditions[0])
let ret = checkParsedConditions(property, conditions[0]); let ret = checkParsedConditions(property, conditions[0])
for(let i=1; i<conditions.length; i+=2) { for (let i = 1; i < conditions.length; i += 2) {
switch(conditions[i]) { switch (conditions[i]) {
case '&': case '&':
if(ret) ret = checkParsedConditions(property, conditions[i+1]); if (ret) ret = checkParsedConditions(property, conditions[i + 1])
break; break
case '|': case '|':
if(ret) return true; if (ret) return true
ret = checkParsedConditions(property, conditions[i+1]); ret = checkParsedConditions(property, conditions[i + 1])
break; break
default: return false; default: return false
} }
} }
return ret; return ret
} }
function checkProp(property, condition) { function checkProp(property, condition) {
const length = condition.length
let i = condition.search(/[><!?=]/)
const length = condition.length; const prop = condition.substring(0, i)
let i = condition.search(/[><\!\?=]/); const symbol = condition.substring(i, (i += condition[i + 1] == '=' ? 2 : 1))
const d = condition.substring(i, length)
const prop = condition.substring(0,i); const propData = property.get(prop)
const symbol = condition.substring(i, i+=(condition[i+1]=='='?2:1)); const conditionData = d[0] == '[' ? JSON.parse(d) : Number(d)
const d = condition.substring(i, length);
const propData = property.get(prop); switch (symbol) {
const conditionData = d[0]=='['? JSON.parse(d): Number(d); case '>': return propData > conditionData
case '<': return propData < conditionData
switch(symbol) { case '>=': return propData >= conditionData
case '>': return propData > conditionData; case '<=': return propData <= conditionData
case '<': return propData < conditionData;
case '>=': return propData >= conditionData;
case '<=': return propData <= conditionData;
case '=': case '=':
if(Array.isArray(propData)) if (Array.isArray(propData)) return propData.includes(conditionData)
return propData.includes(conditionData); return propData == conditionData
return propData == conditionData;
case '!=': case '!=':
if(Array.isArray(propData)) if (Array.isArray(propData))
return !propData.includes(conditionData); return !propData.includes(conditionData)
return propData != conditionData; return propData != conditionData
case '?': case '?':
if(Array.isArray(propData)) { if (Array.isArray(propData)) {
for(const p of propData) for (const p of propData)
if(conditionData.includes(p)) return true; if (conditionData.includes(p)) return true
return false; return false
} }
return conditionData.includes(propData); return conditionData.includes(propData)
case '!': case '!':
if(Array.isArray(propData)) { if (Array.isArray(propData)) {
for(const p of propData) for (const p of propData)
if(conditionData.includes(p)) return false; if (conditionData.includes(p)) return false
return true; return true
} }
return !conditionData.includes(propData); return !conditionData.includes(propData)
default: return false; default: return false
} }
} }
export function extractMaxTriggers(condition) { export function extractMaxTriggers(condition) {
// Assuming only age related talents can be triggered multiple times. // Assuming only age related talents can be triggered multiple times.
const RE_AGE_CONDITION = /AGE\?\[([0-9\,]+)\]/; const RE_AGE_CONDITION = /AGE\?\[([0-9,]+)\]/
const match_object = RE_AGE_CONDITION.exec(condition); const match_object = RE_AGE_CONDITION.exec(condition)
if (match_object == null) { if (match_object == null) {
// Not age related, single trigger. // Not age related, single trigger.
return 1; return 1
} }
const age_list = match_object[1].split(","); const age_list = match_object[1].split(',')
return age_list.length; return age_list.length
} }
+6 -6
View File
@@ -1,4 +1,4 @@
export default ({ export default {
UI_Next: 'Next', UI_Next: 'Next',
UI_Back: 'Back', UI_Back: 'Back',
UI_Skip: 'Skip', UI_Skip: 'Skip',
@@ -26,7 +26,7 @@ export default ({
UI_Property_Spirit: 'SPR', UI_Property_Spirit: 'SPR',
UI_Title_Remake: 'Remake Simulate', UI_Title_Remake: 'Remake Simulate',
UI_Title_Subsequent: 'The rubbish life doesn\'t want to stay for a second', UI_Title_Subsequent: "The rubbish life doesn't want to stay for a second",
UI_Remake: '↻Remake Now', UI_Remake: '↻Remake Now',
UI_Thanks: 'Thx', UI_Thanks: 'Thx',
UI_Achievement: 'Achv', UI_Achievement: 'Achv',
@@ -146,11 +146,11 @@ export default ({
UI_UniqueWaTaShiContent: '\nUnique character card different from other 60 million player\nAll property, All talent, All random\nAll has only one chance', UI_UniqueWaTaShiContent: '\nUnique character card different from other 60 million player\nAll property, All talent, All random\nAll has only one chance',
UI_GenerateNow: 'Generate Now', UI_GenerateNow: 'Generate Now',
M_NoRank: 'There is no rank', M_NoRank: 'There is no rank',
M_PleaseSelectOne: 'Please Select One', M_PleaseSelectOne: 'Please Select One',
M_UnGenerate: 'Unique Character no generate', M_UnGenerate: 'Unique Character no generate',
M_DisableExtendTalent: 'Celebrity mode can\'t extends talent', M_DisableExtendTalent: "Celebrity mode can't extends talent",
M_SponsorThanks: 'Thanks for your support',
F_RemakeTimes: 'Remake {0} Times', F_RemakeTimes: 'Remake {0} Times',
F_AchievementCount: 'Achievement {0}', F_AchievementCount: 'Achievement {0}',
@@ -160,5 +160,5 @@ export default ({
F_TalentSelectNotComplect: 'Please select {0} talent', F_TalentSelectNotComplect: 'Please select {0} talent',
F_PropertyPointLeft: 'You have left {0} property point', F_PropertyPointLeft: 'You have left {0} property point',
F_TalentReplace: 'Talent replace [{source.name}] -> [{target.name}]', F_TalentReplace: 'Talent replace [{source.name}] -> [{target.name}]',
F_PropertyStr: 'CHR{CHR} INT{INT} STR{STR} MNY{MNY}' F_PropertyStr: 'CHR{CHR} INT{INT} STR{STR} MNY{MNY}',
}); }
+4 -3
View File
@@ -1,4 +1,4 @@
export default ({ export default {
UI_Next: '下一步', UI_Next: '下一步',
UI_Back: '返回', UI_Back: '返回',
UI_Skip: '跳过', UI_Skip: '跳过',
@@ -152,6 +152,7 @@ export default ({
M_PleaseSelectOne: '请选择一个名人', M_PleaseSelectOne: '请选择一个名人',
M_UnGenerate: '独一无二的我还没有生成', M_UnGenerate: '独一无二的我还没有生成',
M_DisableExtendTalent: '名人模式不能继承天赋', M_DisableExtendTalent: '名人模式不能继承天赋',
M_SponsorThanks: '感谢支持',
F_RemakeTimes: '已重开{0}次', F_RemakeTimes: '已重开{0}次',
F_AchievementCount: '成就达成{0}个', F_AchievementCount: '成就达成{0}个',
@@ -161,5 +162,5 @@ export default ({
F_TalentSelectNotComplect: '要选满{0}个天赋', F_TalentSelectNotComplect: '要选满{0}个天赋',
F_PropertyPointLeft: '你还有 {0} 属性点没有分配完', F_PropertyPointLeft: '你还有 {0} 属性点没有分配完',
F_TalentReplace: '天赋替换【{source.name}】->【{target.name}】', F_TalentReplace: '天赋替换【{source.name}】->【{target.name}】',
F_PropertyStr: '颜值{CHR} 智力{INT} 体质{STR} 家境{MNY}' F_PropertyStr: '颜值{CHR} 智力{INT} 体质{STR} 家境{MNY}',
}); }
+117 -126
View File
@@ -1,74 +1,65 @@
import App from './app.js'; import App from './app.js'
import Life from './modules/life.js'; import Life from './modules/life.js'
globalThis.$$eventMap = new Map(); if (!globalThis.$channel) globalThis.$channel = {}
globalThis.$$eventMap = new Map()
globalThis.$$event = (tag, data) => { globalThis.$$event = (tag, data) => {
const listener = $$eventMap.get(tag); const listener = $$eventMap.get(tag)
if(listener) listener.forEach(fn=>fn(data)); if (listener) listener.forEach(fn => fn(data))
} }
globalThis.$$on = (tag, fn) => { globalThis.$$on = (tag, fn) => {
let listener = $$eventMap.get(tag); let listener = $$eventMap.get(tag)
if(!listener) { if (!listener) {
listener = new Set(); listener = new Set()
$$eventMap.set(tag, listener); $$eventMap.set(tag, listener)
} }
listener.add(fn); listener.add(fn)
} }
globalThis.$$off = (tag, fn) => { globalThis.$$off = (tag, fn) => {
const listener = $$eventMap.get(tag); const listener = $$eventMap.get(tag)
if(listener) listener.delete(fn); if (listener) listener.delete(fn)
} }
globalThis.$$copy = async text => { globalThis.$$copy = async text => {
const result = await navigator.permissions.query({ name: "clipboard-write" }) const result = await navigator.permissions.query({ name: 'clipboard-write' })
if (result.state == "granted" || result.state == "prompt") { if (result.state == 'granted' || result.state == 'prompt') {
navigator.clipboard.writeText(text) navigator.clipboard.writeText(text)
return true; return true
} }
const input = document.createElement('input'); return false
input.setAttribute('style', 'opacity: 0;');
document.body.appendChild(input);
input.value = text;
input.select();
const r = document.execCommand("copy");
document.body.removeChild(input);
return r;
} }
globalThis.$$read = async ()=>{ globalThis.$$read = async () => {
const result = await navigator.permissions.query({ name: "clipboard-read" }) const result = await navigator.permissions.query({ name: 'clipboard-read' })
if (result.state == "granted" || result.state == "prompt") { if (result.state == 'granted' || result.state == 'prompt') {
return await navigator.clipboard.readText(); return await navigator.clipboard.readText()
} }
const input = document.createElement('input'); return null
input.setAttribute('style', 'opacity: 0;'); }
document.body.appendChild(input);
input.focus();
const r = document.execCommand("paste");
const text = input.value;
document.body.removeChild(input);
return r?text:r;
};
const core = new Life(); const core = new Life()
const game = new App(); const game = new App()
globalThis.core = core; globalThis.core = core
globalThis.game = game; globalThis.game = game
const query = {}; const query = {}
location.search.substr(1).split('&').forEach(item => { location.search
const parts = item.split('='); .substring(1)
query[parts[0]] = parts[1]; .split('&')
}); .forEach(item => {
const parts = item.split('=')
query[parts[0]] = parts[1]
})
core.config({ core.config({
defaultPropertyPoints: 20, // default number of points for a property defaultPropertyPoints: 20, // default number of points for a property
talentSelectLimit: 3, // max number of talents that can be selected talentSelectLimit: 3, // max number of talents that can be selected
propertyAllocateLimit: [0, 10], // scoop of properties that can be allocated, propertyAllocateLimit: [0, 10], // scoop of properties that can be allocated,
defaultPropertys: { SPR: 5 }, // default properties defaultPropertys: { SPR: 5 }, // default properties
talentConfig: { // config for talent talentConfig: {
// config for talent
talentPullCount: 10, // number of talents to pull from the talent pool talentPullCount: 10, // number of talents to pull from the talent pool
talentRate: { 1:100, 2:10, 3:1, total: 1000 }, // rate of talent pull talentRate: { 1: 100, 2: 10, 3: 1, total: 1000 }, // rate of talent pull
additions: { additions: {
TMS: [ TMS: [
[ 10, { 2: 1 }], [ 10, { 2: 1 }],
@@ -83,78 +74,78 @@ core.config({
[ 50, { 2: 3 }], [ 50, { 2: 3 }],
[ 70, { 2: 4 }], [ 70, { 2: 4 }],
[100, { 2: 5 }], [100, { 2: 5 }],
] ],
}, },
}, },
propertyConfig: { // config for property propertyConfig: { // config for property
judge: { judge: {
// type: [min, grade, judge] // type: [min, grade, judge]
RTLT: [ RTLT: [
[ 0, 0], [0, 0],
[ 0.3, 1], [0.3, 1],
[ 0.6, 2], [0.6, 2],
[ 0.9, 3], [0.9, 3],
], ],
REVT: [ REVT: [
[ 0, 0], [0, 0],
[ 0.2, 1], [0.2, 1],
[ 0.4, 2], [0.4, 2],
[ 0.6, 3], [0.6, 3],
], ],
TMS: [ TMS: [
[ 0, 0, 'UI_Remake_Times_Judge_Level_0'], [ 0, 0, 'UI_Remake_Times_Judge_Level_0'],
[ 10, 1, 'UI_Remake_Times_Judge_Level_1'], [ 10, 1, 'UI_Remake_Times_Judge_Level_1'],
[ 30, 1, 'UI_Remake_Times_Judge_Level_2'], [ 30, 1, 'UI_Remake_Times_Judge_Level_2'],
[ 50, 2, 'UI_Remake_Times_Judge_Level_3'], [ 50, 2, 'UI_Remake_Times_Judge_Level_3'],
[ 70, 2, 'UI_Remake_Times_Judge_Level_4'], [ 70, 2, 'UI_Remake_Times_Judge_Level_4'],
[ 100, 3, 'UI_Remake_Times_Judge_Level_5'], [100, 3, 'UI_Remake_Times_Judge_Level_5'],
], ],
CACHV: [ CACHV: [
[ 0, 0, 'UI_Achievement_Count_Judge_Level_0'], [ 0, 0, 'UI_Achievement_Count_Judge_Level_0'],
[ 10, 1, 'UI_Achievement_Count_Judge_Level_1'], [ 10, 1, 'UI_Achievement_Count_Judge_Level_1'],
[ 30, 1, 'UI_Achievement_Count_Judge_Level_2'], [ 30, 1, 'UI_Achievement_Count_Judge_Level_2'],
[ 50, 2, 'UI_Achievement_Count_Judge_Level_3'], [ 50, 2, 'UI_Achievement_Count_Judge_Level_3'],
[ 70, 2, 'UI_Achievement_Count_Judge_Level_4'], [ 70, 2, 'UI_Achievement_Count_Judge_Level_4'],
[ 100, 3, 'UI_Achievement_Count_Judge_Level_5'], [100, 3, 'UI_Achievement_Count_Judge_Level_5'],
], ],
HCHR: [ HCHR: [
[ 0, 0, 'UI_Judge_Level_0'], [ 0, 0, 'UI_Judge_Level_0'],
[ 1, 0, 'UI_Judge_Level_1'], [ 1, 0, 'UI_Judge_Level_1'],
[ 2, 0, 'UI_Judge_Level_2'], [ 2, 0, 'UI_Judge_Level_2'],
[ 4, 0, 'UI_Judge_Level_3'], [ 4, 0, 'UI_Judge_Level_3'],
[ 7, 1, 'UI_Judge_Level_4'], [ 7, 1, 'UI_Judge_Level_4'],
[ 9, 2, 'UI_Judge_Level_5'], [ 9, 2, 'UI_Judge_Level_5'],
[ 11, 3, 'UI_Judge_Level_6'], [11, 3, 'UI_Judge_Level_6'],
], ],
HMNY: [ HMNY: [
[ 0, 0, 'UI_Judge_Level_0'], [ 0, 0, 'UI_Judge_Level_0'],
[ 1, 0, 'UI_Judge_Level_1'], [ 1, 0, 'UI_Judge_Level_1'],
[ 2, 0, 'UI_Judge_Level_2'], [ 2, 0, 'UI_Judge_Level_2'],
[ 4, 0, 'UI_Judge_Level_3'], [ 4, 0, 'UI_Judge_Level_3'],
[ 7, 1, 'UI_Judge_Level_4'], [ 7, 1, 'UI_Judge_Level_4'],
[ 9, 2, 'UI_Judge_Level_5'], [ 9, 2, 'UI_Judge_Level_5'],
[ 11, 3, 'UI_Judge_Level_6'], [11, 3, 'UI_Judge_Level_6'],
], ],
HSPR: [ HSPR: [
[ 0, 0, 'UI_Spirit_Judge_Level_0'], [ 0, 0, 'UI_Spirit_Judge_Level_0'],
[ 1, 0, 'UI_Spirit_Judge_Level_1'], [ 1, 0, 'UI_Spirit_Judge_Level_1'],
[ 2, 0, 'UI_Spirit_Judge_Level_2'], [ 2, 0, 'UI_Spirit_Judge_Level_2'],
[ 4, 0, 'UI_Spirit_Judge_Level_3'], [ 4, 0, 'UI_Spirit_Judge_Level_3'],
[ 7, 1, 'UI_Spirit_Judge_Level_4'], [ 7, 1, 'UI_Spirit_Judge_Level_4'],
[ 9, 2, 'UI_Spirit_Judge_Level_5'], [ 9, 2, 'UI_Spirit_Judge_Level_5'],
[ 11, 3, 'UI_Spirit_Judge_Level_6'], [11, 3, 'UI_Spirit_Judge_Level_6'],
], ],
HINT: [ HINT: [
[ 0, 0, 'UI_Judge_Level_0'], [ 0, 0, 'UI_Judge_Level_0'],
[ 1, 0, 'UI_Judge_Level_1'], [ 1, 0, 'UI_Judge_Level_1'],
[ 2, 0, 'UI_Judge_Level_2'], [ 2, 0, 'UI_Judge_Level_2'],
[ 4, 0, 'UI_Judge_Level_3'], [ 4, 0, 'UI_Judge_Level_3'],
[ 7, 1, 'UI_Judge_Level_4'], [ 7, 1, 'UI_Judge_Level_4'],
[ 9, 2, 'UI_Judge_Level_5'], [ 9, 2, 'UI_Judge_Level_5'],
[ 11, 3, 'UI_Judge_Level_6'], [ 11, 3, 'UI_Judge_Level_6'],
[ 21, 3, 'UI_Intelligence_Judge_Level_7'], [ 21, 3, 'UI_Intelligence_Judge_Level_7'],
[ 131, 3, 'UI_Intelligence_Judge_Level_8'], [131, 3, 'UI_Intelligence_Judge_Level_8'],
[ 501, 3, 'UI_Intelligence_Judge_Level_9'], [501, 3, 'UI_Intelligence_Judge_Level_9'],
], ],
HSTR: [ HSTR: [
[ 0, 0, 'UI_Judge_Level_0'], [ 0, 0, 'UI_Judge_Level_0'],
@@ -171,28 +162,28 @@ core.config({
[2001, 3, 'UI_Strength_Judge_Level_11'], [2001, 3, 'UI_Strength_Judge_Level_11'],
], ],
HAGE: [ HAGE: [
[ 0, 0, 'UI_AGE_Judge_Level_0'], [ 0, 0, 'UI_AGE_Judge_Level_0'],
[ 1, 0, 'UI_AGE_Judge_Level_1'], [ 1, 0, 'UI_AGE_Judge_Level_1'],
[ 10, 0, 'UI_AGE_Judge_Level_2'], [ 10, 0, 'UI_AGE_Judge_Level_2'],
[ 18, 0, 'UI_AGE_Judge_Level_3'], [ 18, 0, 'UI_AGE_Judge_Level_3'],
[ 40, 0, 'UI_AGE_Judge_Level_4'], [ 40, 0, 'UI_AGE_Judge_Level_4'],
[ 60, 1, 'UI_AGE_Judge_Level_5'], [ 60, 1, 'UI_AGE_Judge_Level_5'],
[ 70, 1, 'UI_AGE_Judge_Level_6'], [ 70, 1, 'UI_AGE_Judge_Level_6'],
[ 80, 2, 'UI_AGE_Judge_Level_7'], [ 80, 2, 'UI_AGE_Judge_Level_7'],
[ 90, 2, 'UI_AGE_Judge_Level_8'], [ 90, 2, 'UI_AGE_Judge_Level_8'],
[ 95, 3, 'UI_AGE_Judge_Level_9'], [ 95, 3, 'UI_AGE_Judge_Level_9'],
[ 100, 3, 'UI_AGE_Judge_Level_10'], [100, 3, 'UI_AGE_Judge_Level_10'],
[ 500, 3, 'UI_AGE_Judge_Level_11'], [500, 3, 'UI_AGE_Judge_Level_11'],
], ],
SUM: [ SUM: [
[ 0, 0, 'UI_Judge_Level_0'], [ 0, 0, 'UI_Judge_Level_0'],
[ 41, 0, 'UI_Judge_Level_1'], [ 41, 0, 'UI_Judge_Level_1'],
[ 50, 0, 'UI_Judge_Level_2'], [ 50, 0, 'UI_Judge_Level_2'],
[ 60, 0, 'UI_Judge_Level_3'], [ 60, 0, 'UI_Judge_Level_3'],
[ 80, 1, 'UI_Judge_Level_4'], [ 80, 1, 'UI_Judge_Level_4'],
[ 100, 2, 'UI_Judge_Level_5'], [100, 2, 'UI_Judge_Level_5'],
[ 110, 3, 'UI_Judge_Level_6'], [110, 3, 'UI_Judge_Level_6'],
[ 120, 3, 'UI_Judge_Level_7'], [120, 3, 'UI_Judge_Level_7'],
], ],
}, },
}, },
@@ -213,12 +204,12 @@ core.config({
[10, 1], [10, 1],
], ],
talentWeight: [ talentWeight: [
[ 1, 1], [1, 1],
[ 2, 2], [2, 2],
[ 3, 3], [3, 3],
[ 4, 2], [4, 2],
[ 5, 1], [5, 1],
], ],
}, },
}); })
game.start(query); game.start(query, globalThis.$channel.features ?? [])
+2 -2
View File
@@ -1,8 +1,8 @@
// 滚动条太灵敏 // 滚动条太灵敏
const SCROLL_START_DISTANCE = 30; const SCROLL_START_DISTANCE = 30;
Laya.ScrollBar.prototype.loop=function(){ Laya.ScrollBar.prototype.loop=function(){
var mouseY=Laya.stage.mouseY; let mouseY=Laya.stage.mouseY;
var mouseX=Laya.stage.mouseX; let mouseX=Laya.stage.mouseX;
this._lastOffset=this.isVertical ? (mouseY-this._lastPoint.y):(mouseX-this._lastPoint.x); this._lastOffset=this.isVertical ? (mouseY-this._lastPoint.y):(mouseX-this._lastPoint.x);
if (this._clickOnly){ if (this._clickOnly){
if (Math.abs(this._lastOffset *(this.isVertical ? Laya.stage._canvasTransform.getScaleY():Laya.stage._canvasTransform.getScaleX()))> SCROLL_START_DISTANCE){ if (Math.abs(this._lastOffset *(this.isVertical ? Laya.stage._canvasTransform.getScaleY():Laya.stage._canvasTransform.getScaleX()))> SCROLL_START_DISTANCE){
+1 -1
View File
@@ -12,7 +12,7 @@ plugin.extractComponents = function(uiView, componentNames) {
uiView.child.splice(i, 1); uiView.child.splice(i, 1);
continue; continue;
} }
deepSearch(child, componentNames, components); deepSearch(child, componentNames);
} }
}; };
deepSearch(uiView, componentNames); deepSearch(uiView, componentNames);
+8 -33
View File
@@ -3,16 +3,12 @@ Laya.runtime = {};
runtime.ColorFilterItem = runtime.ColorFilterItem =
class ColorFilterItem extends Laya.Image { class ColorFilterItem extends Laya.Image {
constructor() {
super();
}
#hexToRgba = (hex) => { #hexToRgba = (hex) => {
const rgba = []; const rgba = [];
hex = hex.replace('#', ''); hex = hex.replace('#', '');
hex = hex.match(new RegExp('(.{2})(.{2})(.{2})(.{2})', 'i')); hex = hex.match(/(.{2})(.{2})(.{2})(.{2})/i);
hex.forEach((item, index) => { hex.forEach((item, index) => {
rgba[index] = parseInt(item, 16); rgba[index] = Number.parseInt(item, 16);
}); });
rgba.shift(); rgba.shift();
return rgba; return rgba;
@@ -47,26 +43,9 @@ class ColorFilterItem extends Laya.Image {
} }
} }
} }
runtime.UIBase = runtime.UIBase = class UIBase extends Laya.View {}
class UIBase extends Laya.View { runtime.ViewBase = class ViewBase extends runtime.UIBase {}
constructor() { runtime.DialogBase = class DialogBase extends runtime.UIBase {}
super();
}
}
runtime.ViewBase =
class ViewBase extends runtime.UIBase {
constructor() {
super();
}
}
runtime.DialogBase =
class DialogBase extends runtime.UIBase {
constructor() {
super();
}
}
runtime.ScaleButton = runtime.ScaleButton =
class ScaleButton extends Laya.Button { class ScaleButton extends Laya.Button {
@@ -156,12 +135,12 @@ class RGBAItem {
} }
#hex(v) { #hex(v) {
v = parseInt(v).toString(16); v = Number.parseInt(v).toString(16);
return v.length == 1 ? '0' + v : v; return v.length == 1 ? '0' + v : v;
} }
#dec(v) { #dec(v) {
return parseInt(v, 16); return Number.parseInt(v, 16);
} }
get hex() { get hex() {
@@ -303,7 +282,7 @@ class ColorfulBox extends Laya.Box {
const tween = (colorItem, target, last) => { const tween = (colorItem, target, last) => {
Laya.Tween.clearAll(colorItem); Laya.Tween.clearAll(colorItem);
const distance = colorItem.distance(target, last); const distance = colorItem.distance(target, last);
if(!isFinite(distance)) { if(!Number.isFinite(distance)) {
colorItem.hex = target; colorItem.hex = target;
return; return;
} }
@@ -544,10 +523,6 @@ class BlankBox extends Laya.Box {
runtime.ColorAgentLabel = runtime.ColorAgentLabel =
class ColorAgentLabel extends Laya.Label { class ColorAgentLabel extends Laya.Label {
constructor(...args) {
super(...args);
}
get #brothers() { get #brothers() {
const brothers = []; const brothers = [];
if(!this.parent) return brothers; if(!this.parent) return brothers;
+29 -24
View File
@@ -1,38 +1,43 @@
export default class CyberMain extends ui.view.CyberTheme.CyberMainUI { export default class CyberMain extends ui.view.CyberTheme.CyberMainUI {
constructor() { constructor() {
super(); super()
this.btnRemake.on(Laya.Event.CLICK, this, ()=>$ui.switchView(UI.pages.MODE)); this.btnRemake.on(Laya.Event.CLICK, this, () => $ui.switchView(UI.pages.MODE))
this.btnAchievement.on(Laya.Event.CLICK, this, ()=>$ui.switchView(UI.pages.ACHIEVEMENT)); this.btnAchievement.on(Laya.Event.CLICK, this, () => $ui.switchView(UI.pages.ACHIEVEMENT))
this.btnThanks.on(Laya.Event.CLICK, this, ()=>$ui.switchView(UI.pages.THANKS)); this.btnThanks.on(Laya.Event.CLICK, this, () => $ui.switchView(UI.pages.THANKS))
this.btnGithub.on(Laya.Event.CLICK, this, goto, ['github']); this.btnGithub.on(Laya.Event.CLICK, this, goto, ['github'])
this.btnDiscord.on(Laya.Event.CLICK, this, goto, ['discord']); this.btnDiscord.on(Laya.Event.CLICK, this, goto, ['discord'])
this.btnThemes.on(Laya.Event.CLICK, this, ()=>$ui.showDialog(UI.pages.THEMES)); this.btnThemes.on(Laya.Event.CLICK, this, () => $ui.showDialog(UI.pages.THEMES))
this.btnSaveLoad.on(Laya.Event.CLICK, this, ()=>$ui.showDialog(UI.pages.SAVELOAD)); this.btnSaveLoad.on(Laya.Event.CLICK, this, () => $ui.showDialog(UI.pages.SAVELOAD))
this.on(Laya.Event.RESIZE, this, () => { this.on(Laya.Event.RESIZE, this, () => {
const scale = Math.max( const scale = Math.max(
this.width / this.imgBg.width, this.width / this.imgBg.width,
this.height / this.imgBg.height this.height / this.imgBg.height,
); )
this.imgBg.scale(scale, scale); this.imgBg.scale(scale, scale)
}); })
} }
static load() { static load() {
return [ return [
"fonts/方正像素12.ttf", 'fonts/方正像素12.ttf',
"images/atlas/images/accessories.atlas", 'images/atlas/images/accessories.atlas',
"images/atlas/images/border.atlas", 'images/atlas/images/border.atlas',
"images/atlas/images/button.atlas", 'images/atlas/images/button.atlas',
"images/atlas/images/icons.atlas", 'images/atlas/images/icons.atlas',
"images/atlas/images/progress.atlas", 'images/atlas/images/progress.atlas',
"images/atlas/images/slider.atlas", 'images/atlas/images/slider.atlas',
] ]
} }
init() { init() {
this.banner.visible = const leastOnce = !!core.times
this.btnDiscord.visible = this.banner.visible = leastOnce
this.btnAchievement.visible = this.btnAchievement.visible = leastOnce
this.btnThanks.visible = !!core.times; this.btnThanks.visible = leastOnce
const disabled = globalThis.$channel?.disabled || {}
this.btnDiscord.visible = leastOnce && !disabled.discord
this.btnGithub.visible = !disabled.github
this.btnSaveLoad.visible = !disabled.saveload
} }
} }
+23 -19
View File
@@ -1,28 +1,32 @@
export default class Main extends ui.view.DefaultTheme.MainUI { export default class Main extends ui.view.DefaultTheme.MainUI {
constructor() { constructor() {
super(); super()
this.btnRemake.on(Laya.Event.CLICK, this, ()=>$ui.switchView(UI.pages.MODE)); this.btnRemake.on(Laya.Event.CLICK, this, () => $ui.switchView(UI.pages.MODE))
this.btnAchievement.on(Laya.Event.CLICK, this, ()=>$ui.switchView(UI.pages.ACHIEVEMENT)); this.btnAchievement.on(Laya.Event.CLICK, this, () => $ui.switchView(UI.pages.ACHIEVEMENT))
this.btnThanks.on(Laya.Event.CLICK, this, ()=>$ui.switchView(UI.pages.THANKS)); this.btnThanks.on(Laya.Event.CLICK, this, () => $ui.switchView(UI.pages.THANKS))
this.btnGithub.on(Laya.Event.CLICK, this, goto, ['github']); this.btnGithub.on(Laya.Event.CLICK, this, goto, ['github'])
this.btnDiscord.on(Laya.Event.CLICK, this, goto, ['discord']); this.btnDiscord.on(Laya.Event.CLICK, this, goto, ['discord'])
this.btnThemes.on(Laya.Event.CLICK, this, ()=>$ui.showDialog(UI.pages.THEMES)); this.btnThemes.on(Laya.Event.CLICK, this, () => $ui.showDialog(UI.pages.THEMES))
this.btnSaveLoad.on(Laya.Event.CLICK, this, ()=>$ui.showDialog(UI.pages.SAVELOAD)); this.btnSaveLoad.on(Laya.Event.CLICK, this, () => $ui.showDialog(UI.pages.SAVELOAD))
} }
static load() { static load() {
return [ return ['images/atlas/images/icons.atlas']
"images/atlas/images/icons.atlas",
]
} }
init() { init() {
this.banner.visible = const text = this.labSubTitle.text
this.btnDiscord.visible = this.labSubTitle.text = ' '
this.btnAchievement.visible = this.labSubTitle.text = text
this.btnThanks.visible = !!core.times;
const text = this.labSubTitle.text; const leastOnce = !!core.times
this.labSubTitle.text = ' '; this.banner.visible = leastOnce
this.labSubTitle.text = text; this.btnAchievement.visible = leastOnce
this.btnThanks.visible = leastOnce
const disabled = globalThis.$channel?.disabled || {}
this.btnDiscord.visible = leastOnce && !disabled.discord
this.btnGithub.visible = !disabled.github
this.btnSaveLoad.visible = !disabled.saveload
} }
} }
+7 -2
View File
@@ -5,8 +5,13 @@ export default class Thanks extends ui.view.DefaultTheme.ThanksUI {
this.listSupports.renderHandler = Laya.Handler.create(this, this.renderSupport, null, false); this.listSupports.renderHandler = Laya.Handler.create(this, this.renderSupport, null, false);
this.panelTopSupports.vScrollBar.elasticDistance = 150; this.panelTopSupports.vScrollBar.elasticDistance = 150;
this.listSupports.scrollBar.elasticDistance = 150; this.listSupports.scrollBar.elasticDistance = 150;
this.btnAFD.on(Laya.Event.CLICK, this, goto, ['sponsor_afd']); if (globalThis.$channel?.disabled?.sponsor) {
this.btnDDF.on(Laya.Event.CLICK, this, goto, ['sponsor_ddf']); this.btnAFD.on(Laya.Event.CLICK, this, $$event, ['message', ['M_SponsorThanks']]);
} else {
this.btnAFD.on(Laya.Event.CLICK, this, goto, ['sponsor_afd']);
// this.btnDDF.on(Laya.Event.CLICK, this, goto, ['sponsor_ddf']);
}
this.btnDDF.on(Laya.Event.CLICK, this, $$event, ['message', ['M_SponsorThanks']]);
} }
static #createComponent = Laya.plugin.extractComponents(Thanks.uiView, ['boxTopSupport']); static #createComponent = Laya.plugin.extractComponents(Thanks.uiView, ['boxTopSupport']);
+89 -96
View File
@@ -1,78 +1,77 @@
export default class SaveLoad extends ui.view.SaveLoadUI { export default class SaveLoad extends ui.view.SaveLoadUI {
constructor() { constructor() {
super(); super()
this.btnClose.on(Laya.Event.CLICK, this, async ()=>{ this.btnClose.on(Laya.Event.CLICK, this, async () => {
await this.close(); await this.close()
$ui.switchView(UI.pages.MAIN); $ui.switchView(UI.pages.MAIN)
}); })
this.btnRead.on(Laya.Event.CLICK, this, async ()=>{ this.btnRead.on(Laya.Event.CLICK, this, async () => {
const result = await $$copy(this.input.text = this.data); this.input.text = this.data
$$event('message', [result? 'UI_CopySuccess': 'UI_CopyFailed']); const result = await $$copy(this.data)
}); $$event('message', [result ? 'UI_CopySuccess' : 'UI_CopyFailed'])
this.btnWrite.on(Laya.Event.CLICK, this, async ()=>{ })
const text = await $$read(); this.btnWrite.on(Laya.Event.CLICK, this, async () => {
if(text == false) { const text = await $$read()
if (text == null) {
this.data = [ this.data = [
this.input.text, this.input.text,
'UI_PasteFailedDecodeSuccess', 'UI_PasteFailedDecodeSuccess',
'UI_PasteFailedDecodeFailed' 'UI_PasteFailedDecodeFailed',
]; ]
} else { } else {
this.input.text = text; this.input.text = text
this.data = [ this.data = [
text, text,
'UI_PasteSuccessDecodeSuccess', 'UI_PasteSuccessDecodeSuccess',
'UI_PasteSuccessDecodeFailed' 'UI_PasteSuccessDecodeFailed',
]; ]
} }
});
this.btnSave.on(Laya.Event.CLICK, this, ()=>{
let blob = new Blob([this.data], { type: 'application/json' });
const slice = blob.slice || blob.webkitSlice || blob.mozSlice;
blob = slice.call(blob, 0, blob.size, 'application/octet-stream');
const a = document.createElementNS('http://www.w3.org/1999/xhtml', 'a');
a.href = URL.createObjectURL(blob);
a.download = `Remake_save_${new Date().toISOString().replace(':','.')}.json`;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
URL.revokeObjectURL(a.href);
});
this.btnLoad.on(Laya.Event.CLICK, this, ()=>{
const file = document.createElement('input');
file.setAttribute('type', 'file');
file.setAttribute('name', 'file');
file.setAttribute('accept', 'application/json');
file.setAttribute('style', 'display: none;');
document.body.appendChild(file);
file.click();
file.onchange = (e)=>{
const file = e.target.files[0];
if(!file) return;
const reader = new FileReader();
reader.onload = () => this.data = [reader.result];
reader.readAsText(file);
document.body.removeChild(file);
};
});
this.input.on(Laya.Event.MOUSE_DOWN, this, ()=>{
this.input.setSelection(0, this.input.text.length);
}) })
this.btnBackup.on(Laya.Event.CLICK, this, ()=>{ this.btnSave.on(Laya.Event.CLICK, this, () => {
const board = document.createElement("div"); let blob = new Blob([this.data], { type: 'application/json' })
document.body.appendChild(board); const slice = blob.slice || blob.webkitSlice || blob.mozSlice
blob = slice.call(blob, 0, blob.size, 'application/octet-stream')
const a = document.createElementNS('http://www.w3.org/1999/xhtml', 'a')
a.href = URL.createObjectURL(blob)
a.download = `Remake_save_${new Date().toISOString().replace(':', '.')}.json`
document.body.appendChild(a)
a.click()
a.remove()
URL.revokeObjectURL(a.href)
})
this.btnLoad.on(Laya.Event.CLICK, this, () => {
const file = document.createElement('input')
file.setAttribute('type', 'file')
file.setAttribute('name', 'file')
file.setAttribute('accept', 'application/json')
file.setAttribute('style', 'display: none;')
document.body.appendChild(file)
file.click()
file.onchange = async e => {
const f = e.target.files[0]
if (!f) return
this.data = [await f.text()]
file.remove()
}
})
this.input.on(Laya.Event.MOUSE_DOWN, this, () => {
this.input.setSelection(0, this.input.text.length)
})
this.btnBackup.on(Laya.Event.CLICK, this, () => {
const board = document.createElement('div')
document.body.appendChild(board)
board.style = ` board.style = `
position: fixed; position: fixed;
top: 0; top: 0;
left: 0; left: 0;
right: 0; right: 0;
bottom: 0; bottom: 0;
opacity: 0.95`; opacity: 0.95`
const bg = document.createElement("div"); const bg = document.createElement('div')
bg.style = ` bg.style = `
position: absolute; position: absolute;
top: 0; top: 0;
@@ -80,18 +79,14 @@ export default class SaveLoad extends ui.view.SaveLoadUI {
right: 0; right: 0;
bottom: 0; bottom: 0;
background: #fff; background: #fff;
opacity: 0.95`; opacity: 0.95`
document.body.appendChild(board); document.body.appendChild(board)
board.appendChild(bg); board.appendChild(bg)
const textarea = document.createElement("textarea"); const textarea = document.createElement('textarea')
textarea.style = `position: absolute; width: ${window.innerWidth}px; height: ${window.innerHeight}px;` textarea.style = `position: absolute; width: ${window.innerWidth}px; height: ${window.innerHeight}px;`
textarea.value = JSON.stringify( textarea.value = JSON.stringify(JSON.parse(this.data), null, 4)
JSON.parse(this.data), board.appendChild(textarea)
null, const close = document.createElement('div')
4
);
board.appendChild(textarea);
const close = document.createElement("div");
close.style = ` close.style = `
position: absolute; position: absolute;
top: 0; top: 0;
@@ -103,12 +98,12 @@ export default class SaveLoad extends ui.view.SaveLoadUI {
padding: 0; padding: 0;
line-height: 100px; line-height: 100px;
color: white; color: white;
opacity: 0.7`; opacity: 0.7`
close.innerHTML = '×'; close.innerHTML = '×'
board.appendChild(close); board.appendChild(close)
close.onclick = ()=>board.remove(); close.onclick = () => board.remove()
const load = document.createElement("div"); const load = document.createElement('div')
load.style = ` load.style = `
position: absolute; position: absolute;
bottom: 0; bottom: 0;
@@ -120,43 +115,41 @@ export default class SaveLoad extends ui.view.SaveLoadUI {
padding: 0; padding: 0;
line-height: 50px; line-height: 50px;
color: white; color: white;
opacity: 0.7`; opacity: 0.7`
load.innerHTML = 'LOAD<br>读取'; load.innerHTML = 'LOAD<br>读取'
board.appendChild(load); board.appendChild(load)
load.onclick = ()=>this.data = [textarea.value, '成功/success', '失败/failed', true]; load.onclick = () => (this.data = [textarea.value, '成功/success', '失败/failed', true])
}); })
} }
static load() { static load() {
return ["images/atlas/images/radio.atlas"]; return ['images/atlas/images/radio.atlas']
} }
init() { init() {
this.input.text = this.data; this.input.text = this.data
} }
get data() { get data() {
const data = {}; const data = {}
Object Object.keys(localStorage)
.keys(localStorage) .filter(v => !v.startsWith('goog'))
.filter(v=>v.substr(0,4)!='goog') .forEach(key => (data[key] = localStorage[key]))
.forEach(key=>data[key] = localStorage[key]); return JSON.stringify(data)
return JSON.stringify(data);
} }
set data([v, success = 'UI_LoadSuccess', failed = 'UI_LoadFailed', altMsg]) { set data([v, success = 'UI_LoadSuccess', failed = 'UI_LoadFailed', altMsg]) {
try { try {
const data = JSON.parse(v); const data = JSON.parse(v)
for(const key in data) for (const key in data) localStorage.setItem(key, data[key])
localStorage.setItem(key, data[key]); if (altMsg) alert(success)
if(altMsg) alert(success); else $$event('message', [success])
else $$event('message', [success]); $ui.theme = $ui.theme ?? null
$ui.theme = $ui.theme; this.btnClose.event(Laya.Event.CLICK)
this.btnClose.event(Laya.Event.CLICK);
} catch (e) { } catch (e) {
console.error(e); console.error(e)
if(altMsg) alert(`${failed}\n${e}`); if (altMsg) alert(`${failed}\n${e}`)
else $$event('message', [failed]); else $$event('message', [failed])
} }
} }
} }
+25 -32
View File
@@ -34,7 +34,7 @@ export default class UIManager {
this.#dialogMask.graphics.drawRect(0, 0, 5000, 5000, '#000000') this.#dialogMask.graphics.drawRect(0, 0, 5000, 5000, '#000000')
this.#dialogMask.alpha = 0.4 this.#dialogMask.alpha = 0.4
this.#dialogMask.on(Laya.Event.CLICK, this, () => { this.#dialogMask.on(Laya.Event.CLICK, this, () => {
this.#dialogStack[this.#dialogStack.length - 1]?.close?.() this.#dialogStack.at(-1)?.close?.()
}) })
} }
@@ -86,7 +86,7 @@ export default class UIManager {
args, args,
actions?.load, actions?.load,
viewName, viewName,
'pages' 'pages',
) )
view.top = view.bottom = view.left = view.right = 0 view.top = view.bottom = view.left = view.right = 0
@@ -115,7 +115,7 @@ export default class UIManager {
if (this.#loading) { if (this.#loading) {
timeout = setTimeout( timeout = setTimeout(
() => this.#stage.addChild(this.#loading), () => this.#stage.addChild(this.#loading),
3000 3000,
) )
} }
const onProgress = this.#loading?.onProgress const onProgress = this.#loading?.onProgress
@@ -128,7 +128,7 @@ export default class UIManager {
? this.scanResource(ViewClass.uiView) ? this.scanResource(ViewClass.uiView)
: [] : []
if (preload) { if (preload) {
preload = [].concat(preload).concat(scanedResourceList) preload = preload.concat(scanedResourceList)
} else { } else {
preload = scanedResourceList preload = scanedResourceList
} }
@@ -162,19 +162,19 @@ export default class UIManager {
async loadRes(resourceList, preload, onProgress) { async loadRes(resourceList, preload, onProgress) {
const cnt = (resourceList?.length || 0) + (preload?.length || 0) const cnt = (resourceList?.length || 0) + (preload?.length || 0)
if (resourceList && resourceList.length) { if (resourceList?.length) {
const s = resourceList.length / cnt const s = resourceList.length / cnt
await Laya.promises.loader.load( await Laya.promises.loader.load(
resourceList, resourceList,
Laya.Handler.create(null, prg => onProgress?.(prg * s)) Laya.Handler.create(null, prg => onProgress?.(prg * s)),
) )
} }
if (preload && preload.length) { if (preload?.length) {
const s = 1 - preload.length / cnt const s = 1 - preload.length / cnt
const l = preload.length / cnt const l = preload.length / cnt
await Laya.promises.loader.load( await Laya.promises.loader.load(
preload, preload,
Laya.Handler.create(null, prg => onProgress?.(prg * l + s)) Laya.Handler.create(null, prg => onProgress?.(prg * l + s)),
) )
} }
} }
@@ -202,7 +202,7 @@ export default class UIManager {
args, args,
actions?.load, actions?.load,
dialogName, dialogName,
'pages' 'pages',
) )
const index = this.#dialogStack.indexOf(dialog) const index = this.#dialogStack.indexOf(dialog)
@@ -223,7 +223,7 @@ export default class UIManager {
dialog, dialog,
{ scaleX: 1, scaleY: 1 }, { scaleX: 1, scaleY: 1 },
300, 300,
Laya.Ease.backOut Laya.Ease.backOut,
) )
}) })
await open(dialog) await open(dialog)
@@ -237,7 +237,7 @@ export default class UIManager {
dialog, dialog,
{ scaleX: 0, scaleY: 0 }, { scaleX: 0, scaleY: 0 },
300, 300,
Laya.Ease.strongIn Laya.Ease.strongIn,
) )
} }
const index = this.#dialogStack.indexOf(dialog) const index = this.#dialogStack.indexOf(dialog)
@@ -255,7 +255,7 @@ export default class UIManager {
const popup = await this.getView(className, args, null, type, 'popups') const popup = await this.getView(className, args, null, type, 'popups')
this.#popupLayer.addChild(popup) this.#popupLayer.addChild(popup)
await popup.popup(args, this.#popupLayer) await popup.popup(args, this.#popupLayer)
this.#popupLayer.removeChild(popup) popup.removeSelf()
} }
clearAllDialog() { clearAllDialog() {
@@ -266,7 +266,7 @@ export default class UIManager {
#config(view, key, type) { #config(view, key, type) {
const config = this.#configs?.[type]?.[key] const config = this.#configs?.[type]?.[key]
if (!config) return if (!config) return
if (view.config && view.config(config)) return if (view.config?.(config)) return
const applyConfig = (target, config) => { const applyConfig = (target, config) => {
if (!target) return if (!target) return
if (typeof config == 'string') { if (typeof config == 'string') {
@@ -278,7 +278,7 @@ export default class UIManager {
if (config.names) if (config.names)
for (const name in config.names) for (const name in config.names)
this.#deepGetChildsByName(view, name).forEach(child => this.#deepGetChildsByName(view, name).forEach(child =>
applyConfig(child, config.names[name]) applyConfig(child, config.names[name]),
) )
if (config.vars) if (config.vars)
@@ -288,7 +288,7 @@ export default class UIManager {
#deepGetChildsByName(parent, name) { #deepGetChildsByName(parent, name) {
const list = [] const list = []
if (!parent || !parent._childs) return list if (!parent?._childs) return list
for (const child of parent._childs) { for (const child of parent._childs) {
if (child.name == name) list.push(child) if (child.name == name) list.push(child)
@@ -311,7 +311,7 @@ export default class UIManager {
} }
#subSkin(skin, type) { #subSkin(skin, type) {
if (!skin || !skin.replace(/\s/g, '')) return [] if (!skin?.replace(/\s/g, '')) return []
switch (type) { switch (type) {
case 'ProgressBar': case 'ProgressBar':
return [skin, ...this.#progressBarSkin(skin)] return [skin, ...this.#progressBarSkin(skin)]
@@ -340,21 +340,14 @@ export default class UIManager {
scanResource(uiView) { scanResource(uiView) {
if (!uiView) return [] if (!uiView) return []
const resourceList = [] return [
this.#subSkin(uiView.props?.skin, uiView.type),
resourceList.push(...this.#subSkin(uiView.props?.skin, uiView.type)) this.#subSkin(uiView.props?.hScrollBarSkin, 'ScrollBar'),
resourceList.push( this.#subSkin(uiView.props?.vScrollBarSkin, 'ScrollBar'),
...this.#subSkin(uiView.props?.hScrollBarSkin, 'ScrollBar') uiView.child?.flatMap(child => this.scanResource(child)),
) ]
resourceList.push( .flat()
...this.#subSkin(uiView.props?.vScrollBarSkin, 'ScrollBar') .filter(item => !!item)
)
uiView.child?.forEach(child => {
resourceList.push(...this.scanResource(child))
})
return resourceList
} }
get currentView() { get currentView() {
@@ -362,7 +355,7 @@ export default class UIManager {
} }
get currentDialog() { get currentDialog() {
return this.#dialogStack[this.#dialogStack.length - 1] return this.#dialogStack.at(-1)
} }
get theme() { get theme() {