45 Commits

Author SHA1 Message Date
Vick Scarlet
f12a147093 fix: format param force to string 2026-03-30 17:49:37 +08:00
dependabot[bot]
59a10587a7 Bump @isaacs/brace-expansion
Bumps the npm_and_yarn group with 1 update in the / directory: @isaacs/brace-expansion.


Updates `@isaacs/brace-expansion` from 5.0.0 to 5.0.1

---
updated-dependencies:
- dependency-name: "@isaacs/brace-expansion"
  dependency-version: 5.0.1
  dependency-type: indirect
  dependency-group: npm_and_yarn
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-02-07 21:48:26 +08:00
Vick Scarlet
dd5a003801 update: dependencies 2026-01-26 18:21:44 +08:00
Vick Scarlet
ddc87ebf40 update: dependencies 2026-01-26 17:50:24 +08:00
dependabot[bot]
23bcae0b74 Bump js-yaml in the npm_and_yarn group across 1 directory
Bumps the npm_and_yarn group with 1 update in the / directory: [js-yaml](https://github.com/nodeca/js-yaml).


Updates `js-yaml` from 4.1.0 to 4.1.1
- [Changelog](https://github.com/nodeca/js-yaml/blob/master/CHANGELOG.md)
- [Commits](https://github.com/nodeca/js-yaml/compare/4.1.0...4.1.1)

---
updated-dependencies:
- dependency-name: js-yaml
  dependency-version: 4.1.1
  dependency-type: indirect
  dependency-group: npm_and_yarn
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-01-26 15:14:19 +08:00
dependabot[bot]
e075dfc23d Bump vite in the npm_and_yarn group across 1 directory
Bumps the npm_and_yarn group with 1 update in the / directory: [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite).


Updates `vite` from 6.3.6 to 6.4.1
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/main/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/create-vite@6.4.1/packages/vite)

---
updated-dependencies:
- dependency-name: vite
  dependency-version: 6.4.1
  dependency-type: direct:development
  dependency-group: npm_and_yarn
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-01-26 15:09:16 +08:00
Vick Scarlet
9088ab0eb1 add: support template prop 2026-01-26 14:47:35 +08:00
dependabot[bot]
39388c6eaf Bump the npm_and_yarn group across 1 directory with 2 updates
Bumps the npm_and_yarn group with 2 updates in the / directory: [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) and [brace-expansion](https://github.com/juliangruber/brace-expansion).


Updates `vite` from 6.2.5 to 6.3.6
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/v6.3.6/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v6.3.6/packages/vite)

Updates `brace-expansion` from 2.0.1 to 2.0.2
- [Release notes](https://github.com/juliangruber/brace-expansion/releases)
- [Commits](https://github.com/juliangruber/brace-expansion/compare/v2.0.1...v2.0.2)

---
updated-dependencies:
- dependency-name: vite
  dependency-version: 6.3.6
  dependency-type: direct:development
  dependency-group: npm_and_yarn
- dependency-name: brace-expansion
  dependency-version: 2.0.2
  dependency-type: indirect
  dependency-group: npm_and_yarn
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-24 17:46:20 +08:00
神戸小鳥
0ce9b0ed02 Add Dependabot configuration for updates
Configured Dependabot for version updates with a weekly schedule.
2025-09-24 17:45:01 +08:00
Vick Scarlet
aee4fcf164 fix: 修复冲突天赋漏填出错 2025-05-17 21:27:01 +08:00
Vick Scarlet
5c0fe56915 fix: 修复冲突天赋漏填出错 2025-05-17 21:17:21 +08:00
Vick Scarlet
b82da6c9a7 delete: unuse 2025-04-06 20:38:54 +08:00
su226
b1ffae9eaf fix: wrong data 2025-04-06 19:39:05 +08:00
Vick Scarlet
fee986432d update: use min lib 2025-04-05 18:37:04 +08:00
Vick Scarlet
25fc74398a update: readme 2025-04-05 18:26:55 +08:00
Vick Scarlet
35c5fe36fb update: readme 2025-04-05 18:03:43 +08:00
Vick Scarlet
3f58e3deae fix: script 2025-04-05 17:58:08 +08:00
Vick Scarlet
788c864e71 change: vite build base 2025-04-05 17:47:35 +08:00
Vick Scarlet
680a4f8a5a remove: unuse 2025-04-05 17:43:21 +08:00
Vick Scarlet
8f46e286dd update: depence 2025-04-05 17:40:22 +08:00
Vick Scarlet
2eaf7a1ba2 update: toolchan 2025-04-05 17:27:00 +08:00
Vick Scarlet
6b58fa99cf change: ui 2025-04-05 12:35:59 +08:00
Vick Scarlet
5d1b623230 add: banner 2025-04-05 12:29:01 +08:00
Vick Scarlet
6e442c14c1 update: afd url 2024-09-17 18:31:30 +08:00
Vick Scarlet
2eadb6fb23 update event 2024-07-31 19:40:42 +08:00
Vick Scarlet
d19afd7b1a update special thanks 2024-02-02 16:33:05 +08:00
Vick Scarlet
98eda94f66 update: special thanks 2023-10-12 19:07:46 +08:00
Vick Scarlet
e0f5cb71c5 update specialthanks 2023-02-14 19:43:30 +08:00
Vick Scarlet
58140fd4d2 fix #379 2023-01-03 09:39:52 +08:00
Vick Scarlet
b44e0e65a5 update: specialthanks 2023-01-03 09:38:51 +08:00
Vick Scarlet
cc460d6108 update specialthanks 2022-11-15 22:02:46 +08:00
Vick Scarlet
1dd1927612 dev: update v-transform 2022-10-07 14:19:18 +08:00
Vick Scarlet
21d4c9d568 update specialthanks 2022-09-24 16:36:49 +08:00
Vick Scarlet
35eac7d19d update data 2022-09-12 14:05:09 +08:00
Vick Scarlet
c1ed14385a update special thanks 2022-09-01 23:19:47 +08:00
Vick Scarlet
50ad3d35e7 update: events 2022-08-29 15:35:11 +08:00
Vick Scarlet
4df53d9f58 update specialthanks 2022-08-18 15:10:38 +08:00
Vick Scarlet
8a6f50dda6 update specialthanks 2022-07-16 13:32:10 +08:00
Miller-du
49488505e2 Update webpack.config.cjs 2022-06-08 11:39:31 +08:00
Vick Scarlet
dd64e8f44e update specialthanks 2022-05-31 04:15:31 +08:00
Vick Scarlet
b39772fd94 update event 2022-05-17 22:17:08 +08:00
Vick Scarlet
fc1135a621 update new event 2022-04-28 01:21:05 +08:00
Vick Scarlet
d7ea91a1b8 update specialthanks 2022-04-27 16:39:16 +08:00
Vick Scarlet
53a8729968 fix test 2022-04-07 15:44:22 +08:00
Vick Scarlet
ad93703a45 update specialthanks 2022-04-07 15:21:56 +08:00
102 changed files with 2342 additions and 189108 deletions

11
.github/dependabot.yml vendored Normal file
View File

@@ -0,0 +1,11 @@
# To get started with Dependabot version updates, you'll need to specify which
# package ecosystems to update and where the package manifests are located.
# Please see the documentation for all configuration options:
# https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file
version: 2
updates:
- package-ecosystem: "" # See documentation for possible values
directory: "/" # Location of package manifests
schedule:
interval: "weekly"

29
.github/workflows/deploy.yml vendored Normal file
View File

@@ -0,0 +1,29 @@
name: Build and Deploy
on:
push:
branches: [main]
permissions:
contents: write
jobs:
build-and-deploy:
concurrency: ci-${{ github.ref }} # Recommended if you intend to make multiple deployments in quick succession.
runs-on: ubuntu-latest
steps:
- name: Checkout 🛎️
uses: actions/checkout@v4
- name: Install pnpm
uses: pnpm/action-setup@v4
with:
version: 10
- name: Install and Build 🔧 # This example project is built using npm and outputs the result to the 'build' folder. Replace with the commands required to build your project, or remove this step entirely if your site is pre-built.
run: |
pnpm install
pnpm xlsx2json
pnpm build
- name: Deploy 🚀
uses: JamesIves/github-pages-deploy-action@v4
with:
folder: template # The folder the action should deploy.

View File

@@ -1,31 +0,0 @@
# This workflow will do a clean install of node dependencies, cache/restore them, build the source code and run tests across different versions of node
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions
name: Node.js CI
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [14.x, 16.x]
# See supported Node.js release schedule at https://nodejs.org/en/about/releases/
steps:
- uses: actions/checkout@v2
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v2
with:
node-version: ${{ matrix.node-version }}
cache: 'npm'
- run: npm install
- run: npm run build --if-present
- run: npm test

5
.gitignore vendored
View File

@@ -107,4 +107,7 @@ utils/xlsxTransform-*
/.idea
__localStorage.json
__localStorage.json
template/public
public/data

View File

@@ -1,3 +0,0 @@
{
"esversion": 9
}

29
.vscode/launch.json vendored
View File

@@ -4,40 +4,15 @@
// 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Launch Chrome",
"request": "launch",
"type": "pwa-chrome",
"url": "http://127.0.0.1:8000/public/index.html",
"webRoot": "${workspaceFolder}"
},
{
"type": "node",
"request": "launch",
"name": "test",
"program": "${workspaceFolder}/test",
"skipFiles": [
"<node_internals>/**"
"<node_internals>/**",
"**/node_modumes/**"
]
},
{
"type": "node",
"request": "launch",
"name": "xlsx2json",
"program": "${workspaceFolder}/node_modules/v-transform/src/index.js",
"args": ["transform", "jobs/xlsx2json/config.json"],
"skipFiles": [
"<node_internals>/**"
]
},
{
"name": "Attach by Process ID",
"processId": "${command:PickProcess}",
"request": "attach",
"skipFiles": [
"<node_internals>/**"
],
"type": "node"
},
]
}

View File

@@ -1,5 +0,0 @@
{
"cSpell.words": [
"Laya"
]
}

1
CNAME
View File

@@ -1 +0,0 @@
liferestart.syaro.io

View File

@@ -14,38 +14,22 @@
<summary><strong>网页版</strong></summary>
<br />
1. 下载项目代码。
```bash
# 1. 下载项目代码
git clone https://github.com/VickScarlet/lifeRestart.git my-project
# 2. 进入目录安装依赖
cd my-project
pnpm install
# 3. 转换XLSX表
pnpm xlsx2json
# 4. 启动本地开发服务器
pnpm dev
```
2. 进入目录安装依赖
```bash
yarn install
```
或者
```bash
npm install
```
3. 启动本地服务器。
```bash
yarn dev
```
或者
```bash
npm run dev
```
4. 启动完成后会自动打开浏览器访问 [http://localhost:8081/view/index.html](http://localhost:8081/view/index.html)。
启动完成后打开浏览器访问 [http://localhost:5173](http://localhost:5173)
</details>

View File

@@ -14,38 +14,23 @@ English | [简体中文](./README-zh_CN.md)
<summary><strong>Web Version</strong></summary>
<br />
1. Clone project code.
```bash
# 1. Clone project code.
git clone git@github.com:VickScarlet/lifeRestart.git my-project
cd my-project
# 2. Installation dependence.
pnpm install
# 3. Transform XLSX
pnpm xlsx2json
# 4. Start local dev server.
pnpm dev
```
2. Installation dependence.
```bash
yarn install
```
Or
```bash
npm install
```
3. Start local server.
```bash
yarn dev
```
Or
```bash
npm run dev
```
4. After the startup is complete, will automatically open a browser and visit [http://localhost:8081/view/index.html](http://localhost:8081/view/index.html).
After the startup is complete, open a browser and visit [http://localhost:5173](http://localhost:5173).
</details>
<details>

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -15,12 +15,22 @@
<meta name="laya" screenorientation ="landscape"/>
<meta http-equiv="expires" content="0"/>
<meta http-equiv="Cache-Control" content="no-siteapp"/>
<font-face font-family="方正像素12" src="fonts/方正像素12.ttf"/>
<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.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.particle.min.js"></script>
<script type="text/javascript" src="libs/laya/min/laya.ui.min.js"></script>
<script type="module" src="src/index.js"></script>
</head>
<body style="background:black"></body>
</html>

View File

@@ -1,19 +0,0 @@
{
"configurations": [
{
"source": [
"../../data/specialthanks-afd.xlsx",
"../../data/specialthanks-dun.xlsx"
],
"target": "../../public/data"
},
{
"source": "../../data/zh-cn",
"target": "../../public/data/zh-cn"
},
{
"source": "../../data/en-us",
"target": "../../public/data/en-us"
}
]
}

View File

@@ -1,12 +1,10 @@
{
// See http://go.microsoft.com/fwlink/?LinkId=759670
// for the documentation about the jsconfig.json format
"compilerOptions": {
"target": "es5"
},
"exclude": [
"node_modules",
"public",
"view"
]
// See http://go.microsoft.com/fwlink/?LinkId=759670
// for the documentation about the jsconfig.json format
"compilerOptions": {
"module": "esnext",
"target": "es6",
},
"include":["src", "repl", "vite.config.js"],
"exclude": ["node_modules", "public", "view"]
}

View File

@@ -1,8 +1,8 @@
{
"x":0,
"type":"View",
"selectedBox":1,
"selecteID":12,
"selectedBox":93,
"selecteID":94,
"props":{"y":1218,"x":562,"width":1125,"sceneColor":"#000000","sceneBg":"laya/views/view/CyberTheme/CyberMain.png","runtime":"Laya.runtime.ViewBase","height":2436,"anchorY":0.5,"anchorX":0.5},
"nodeParent":-1,
"label":"View",
@@ -548,14 +548,13 @@
"props":{"width":1,"left":0,"height":1,"bottom":0},
"nodeParent":1,
"label":"Box",
"isOpen":true,
"isOpen":false,
"isDirectory":true,
"isAniNode":true,
"hasChild":true,
"compId":85,
"child":[
{
"x":30,
"type":"Box",
"props":{"y":-175,"x":100,"width":160,"var":"btnGithub","runtime":"Laya.runtime.ScaleButton","name":"btnGithub","height":160,"anchorY":0.5,"anchorX":0.5},
"nodeParent":85,
@@ -580,7 +579,6 @@
}]
},
{
"x":30,
"type":"Box",
"props":{"y":-355,"x":100,"width":160,"var":"btnDiscord","runtime":"Laya.runtime.ScaleButton","name":"btnDiscord","height":160,"anchorY":0.5,"anchorX":0.5},
"nodeParent":85,
@@ -611,14 +609,13 @@
"props":{"right":0,"bottom":0},
"nodeParent":1,
"label":"Box",
"isOpen":true,
"isOpen":false,
"isDirectory":true,
"isAniNode":true,
"hasChild":true,
"compId":88,
"child":[
{
"x":30,
"type":"Box",
"props":{"y":-300,"x":-100,"width":110,"runtime":"Laya.runtime.ScaleButton","height":110,"anchorY":0.5,"anchorX":0.5},
"nodeParent":88,
@@ -630,7 +627,6 @@
"compId":90,
"child":[
{
"x":45,
"type":"Box",
"props":{"width":110,"var":"btnSaveLoad","runtime":"Laya.runtime.ColorfulBox","name":"btnSmall","height":110,"centerY":0,"centerX":0,"anchorY":0.5,"anchorX":0.5},
"nodeParent":90,
@@ -642,7 +638,6 @@
"compId":91,
"child":[
{
"x":60,
"type":"Image",
"props":{"width":80,"skin":"images/icons/icon_save.png","height":80,"centerY":0,"centerX":0},
"nodeParent":91,
@@ -657,7 +652,6 @@
}]
},
{
"x":30,
"type":"Box",
"props":{"y":-175,"x":-100,"width":110,"runtime":"Laya.runtime.ScaleButton","height":110,"anchorY":0.5,"anchorX":0.5},
"nodeParent":88,
@@ -669,7 +663,6 @@
"compId":89,
"child":[
{
"x":45,
"type":"Box",
"props":{"width":110,"var":"btnThemes","runtime":"Laya.runtime.ColorfulBox","name":"btnThemes","height":110,"centerY":0,"centerX":0,"anchorY":0.5,"anchorX":0.5},
"nodeParent":89,
@@ -694,6 +687,32 @@
}]
}]
}]
},
{
"x":15,
"type":"Box",
"props":{"x":572,"var":"banner","centerX":0,"bottom":100,"anchorY":1,"anchorX":0.5},
"nodeParent":1,
"label":"Box(banner)",
"isOpen":true,
"isDirectory":true,
"isAniNode":true,
"hasChild":true,
"compId":93,
"child":[
{
"x":30,
"type":"Label",
"props":{"text":"UI_Banner","fontSize":40,"font":"方正像素12","color":"#00fffd"},
"nodeParent":93,
"label":"Label",
"isDirectory":false,
"isAniNode":true,
"hasChild":false,
"compId":94,
"child":[
]
}]
}],
"animations":[
{

View File

@@ -1,8 +1,8 @@
{
"x":0,
"type":"View",
"selectedBox":99,
"selecteID":100,
"selectedBox":101,
"selecteID":102,
"props":{"y":1218,"x":562,"width":1125,"sceneColor":"#000000","runtime":"Laya.runtime.ViewBase","height":2436,"anchorY":0.5,"anchorX":0.5},
"nodeParent":-1,
"label":"View",
@@ -276,6 +276,32 @@
"child":[
]
}]
},
{
"x":15,
"type":"Box",
"props":{"x":562,"var":"banner","centerX":0,"bottom":100,"anchorY":1,"anchorX":0.5},
"nodeParent":1,
"label":"Box(banner)",
"isOpen":true,
"isDirectory":true,
"isAniNode":true,
"hasChild":true,
"compId":101,
"child":[
{
"x":30,
"type":"Label",
"props":{"text":"UI_Banner","name":"title","fontSize":40,"font":"SimHei","color":"#ffffff"},
"nodeParent":101,
"label":"Label(title)",
"isDirectory":false,
"isAniNode":true,
"hasChild":false,
"compId":102,
"child":[
]
}]
}],
"animations":[
{

View File

@@ -1,24 +1,19 @@
{
"name": "life_restart",
"type": "module",
"bin": "repl/index.js",
"version": "2.0.0",
"main": "repl/index.js",
"version": "2.1.0",
"author": "Vick Scarlet <vick@syaro.io>",
"scripts": {
"test": "node test",
"xlsxTransform": "vt transform data",
"xlsx2json": "vt transform jobs/xlsx2json/config.json",
"dev": "webpack serve --open /view/index.html",
"build": "webpack --mode production"
"xlsx2json": "vt transform -d public \"data/**/*.xlsx\"",
"dev": "vite",
"build": "vite build",
"start": "vite preview",
"test": "vitest"
},
"devDependencies": {
"@babel/core": "^7.15.4",
"@babel/preset-env": "^7.15.4",
"babel-loader": "^8.2.2",
"core-js": "^3.17.2",
"html-webpack-plugin": "^5.5.0",
"v-transform": "^1.0.2",
"webpack": "^5.64.4",
"webpack-cli": "^4.8.0",
"webpack-dev-server": "^4.1.0"
"v-transform": "^2.2.1",
"vite": "^8.0.3",
"vitest": "^4.1.2"
}
}

1111
pnpm-lock.yaml generated Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,74 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no">
<meta name="description" content="やり直すんだ。そして、次はうまくやる。"/>
<meta name="keywords" content="人生重开模拟器 liferestart life restart remake 人生重来"/>
<meta name="renderer" content="webkit"/>
<meta name="apple-mobile-web-app-capable" content="yes"/>
<meta name="full-screen" content="true"/>
<meta name="x5-fullscreen" content="true"/>
<meta name="360-fullscreen" content="true"/>
<meta name="theme-color" content="#157878"/>
<meta name="laya" screenorientation ="landscape"/>
<meta http-equiv="expires" content="0"/>
<meta http-equiv="Cache-Control" content="no-siteapp"/>
<font-face font-family="方正像素12" src="fonts/方正像素12.ttf"/>
<title>Life Restart</title>
</head>
<body style="background:black">
<!--以下引用了常用类库,如果不使用,可以删除-->
<!--核心包,封装了显示对象渲染,事件,时间管理,时间轴动画,缓动,消息交互,socket本地存储鼠标触摸声音加载颜色滤镜位图字体等-->
<script type="text/javascript" src="libs/laya/laya.core.js"></script>
<!--提供了微信小游戏的适配-->
<!-- <script type="text/javascript" src="libs/laya/laya.wxmini.js"></script> -->
<!--提供了百度小游戏的适配-->
<!-- <script type="text/javascript" src="libs/laya/laya.bdmini.js"></script> -->
<!--提供了小米小游戏的适配-->
<!-- <script type="text/javascript" src="libs/laya/laya.xmmini.js"></script> -->
<!--提供了OPPO小游戏的适配-->
<!-- <script type="text/javascript" src="libs/laya/laya.quickgamemini.js"></script> -->
<!--提供了bilibili小游戏的适配-->
<!-- <script type="text/javascript" src="libs/laya/laya.bilimini.js"></script> -->
<!--提供了Alipay小游戏的适配-->
<!-- <script type="text/javascript" src="libs/laya/laya.Alipaymini.js"></script> -->
<!--提供了qq小游戏的适配-->
<!-- <script type="text/javascript" src="libs/laya/laya.qqmini.js"></script> -->
<!--提供了字节跳动小游戏的适配-->
<!-- <script type="text/javascript" src="libs/laya/laya.ttmini.js"></script> -->
<!--提供了华为快游戏的适配-->
<!-- <script type="text/javascript" src="libs/laya/laya.hwmini.js"></script> -->
<!--提供了淘宝商家应用的适配-->
<!-- <script type="text/javascript" src="libs/laya/laya.tbmini.js"></script> -->
<!--提供了淘宝小部件的适配-->
<!-- <script type="text/javascript" src="libs/laya/laya.tbplugin.js"></script> -->
<!--封装了webgl渲染管线如果使用webgl渲染可以在初始化时调用Laya.init(1000,800,laya.webgl.WebGL);-->
<script type="text/javascript" src="libs/laya/laya.webgl.js"></script>
<!--提供了VIVO小游戏的适配-->
<!-- <script type="text/javascript" src="libs/laya/laya.vvmini.js"></script> -->
<!--是动画模块包含了swf动画骨骼动画等-->
<!-- <script type="text/javascript" src="libs/laya/laya.ani.js"></script> -->
<!--包含更多webgl滤镜比如外发光阴影模糊以及更多-->
<script type="text/javascript" src="libs/laya/laya.filter.js"></script>
<!--封装了html动态排版功能-->
<script type="text/javascript" src="libs/laya/laya.html.js"></script>
<!--粒子类库-->
<script type="text/javascript" src="libs/laya/laya.particle.js"></script>
<!--提供tileMap解析支持-->
<!-- <script type="text/javascript" src="libs/laya/laya.tiledmap.js"></script> -->
<!--提供了制作UI的各种组件实现-->
<script type="text/javascript" src="libs/laya/laya.ui.js"></script>
<!-- 提供LayaAir3d接口 -->
<!-- <script type="text/javascript" src="libs/laya/laya.d3.js"></script> -->
<!-- 物理引擎matter.js -->
<!--自定义的js(src文件夹下)文件自动添加到下面jsfile模块标签里面里js的顺序可以手动修改修改后保留修改的顺序新增加的js会默认依次追加到标签里-->
<!--删除标签ide不会自动添加js文件请谨慎操作-->
<!--jsfile--startTag-->
<script type="module" src="../src/index.js"></script>
<!--jsfile--endTag-->
</body>
</html>

View File

@@ -1 +0,0 @@
<!doctype html><html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"><meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no"><meta name="description" content="やり直すんだ。そして、次はうまくやる。"/><meta name="keywords" content="人生重开模拟器 liferestart life restart remake 人生重来"/><meta name="renderer" content="webkit"/><meta name="apple-mobile-web-app-capable" content="yes"/><meta name="full-screen" content="true"/><meta name="x5-fullscreen" content="true"/><meta name="360-fullscreen" content="true"/><meta name="theme-color" content="#157878"/><meta name="laya" screenorientation="landscape"/><meta http-equiv="expires" content="0"/><meta http-equiv="Cache-Control" content="no-siteapp"/><title>Life Restart</title><script src="libs/laya/min/laya.core.min.js"></script><script src="libs/laya/min/laya.webgl.min.js"></script><script src="libs/laya/min/laya.filter.min.js"></script><script src="libs/laya/min/laya.particle.min.js"></script><script src="libs/laya/min/laya.ui.min.js"></script><script defer="defer" src="chunk/main.76985.js"></script></head><body style="background:black"></body></html>

File diff suppressed because it is too large Load Diff

View File

@@ -1,32 +1,44 @@
import App from './app.js';
import { readFile, writeFile } from 'fs/promises';
import { fileURLToPath } from 'url'
import { dirname } from 'path'
const __filename = fileURLToPath(import.meta.url)
const __dirname = dirname(__filename)
import App from './app.js'
import { readFile, writeFile } from 'fs/promises'
async function main() {
try {
globalThis.localStorage = JSON.parse(await readFile('__localStorage.json'));
globalThis.localStorage = JSON.parse(
await readFile(__dirname + '/__localStorage.json')
)
} catch (e) {
globalThis.localStorage = {};
globalThis.localStorage = {}
}
localStorage.getItem = key => localStorage[key]===void 0? null: localStorage[key];
localStorage.setItem = (key, value) => (localStorage[key] = value);
localStorage.getItem = key =>
localStorage[key] === void 0 ? null : localStorage[key]
localStorage.setItem = (key, value) => (localStorage[key] = value)
globalThis.dumpLocalStorage = async ()=>await writeFile('__localStorage.json', JSON.stringify( global.localStorage))
globalThis.dumpLocalStorage = async () =>
await writeFile(
__dirname + '/__localStorage.json',
JSON.stringify(global.localStorage)
)
const app = new App();
const app = new App()
app.io(
repl => process.stdin.on('data', data=>repl(data.toString().trim())),
(data, isRepl) => process.stdout.write(`${data}${isRepl?'\n>':''}`),
code=>process.exit(code)
repl => process.stdin.on('data', data => repl(data.toString().trim())),
(data, isRepl) => process.stdout.write(`${data}${isRepl ? '\n>' : ''}`),
code => process.exit(code)
)
await app.initial();
await app.initial()
}
main();
main()
// process.stdin.setRawMode(true);
// process.openStdin().on('keypress', function (chunk, key) {
// process.stdout.write('Get Chunk: ' + chunk + '\n');
// if (key && key.ctrl && key.name == 'c') process.exit();
// });
// });

View File

@@ -7,21 +7,21 @@ import UIManager from './ui/uiManager.js';
import * as utils from './functions/util.js';
globalThis.UIManager =
globalThis.UI =
UIManager;
globalThis.UI =
UIManager;
globalThis.$_ = utils;
globalThis.goto = async tag => {
let url;
switch(tag) {
switch (tag) {
case 'github': url = 'https://github.com/VickScarlet/lifeRestart'; break;
case 'discord': url = 'https://discord.gg/U3qrf49NMQ'; break;
case 'sponsor_afd': url = 'https://afdian.net/@LifeRestart'; break;
case 'sponsor_afd': url = 'https://afdian.com/a/LifeRestart'; break;
case 'sponsor_ddf': url = 'https://dun.mianbaoduo.com/@vickscarlet'; break;
}
try {
if(Laya.Browser.onIOS) {
if (Laya.Browser.onIOS) {
window.location.href = url;
} else {
window.open(url, '_blank');
@@ -30,8 +30,8 @@ globalThis.goto = async tag => {
console.error(error);
}
}
class App{
constructor(){
class App {
constructor() {
this.name = 'lifeRestart';
this.version = '2.0.0';
console.log(`${this.name} ${this.version}`);
@@ -50,10 +50,10 @@ class App{
//class laya.webgl.text.CharSegment
class CharSegment {
constructor() {
this._sourceStr=null;
this._sourceStr = null;
}
textToSpit(str) {
this._sourceStr=str;
this._sourceStr = str;
var texLen = str.length;
var idx = -1;
this._words = [];
@@ -67,18 +67,18 @@ class App{
}
}
}
getChar(i){
getChar(i) {
return this._words;
}
getCharCode(i){
getCharCode(i) {
return this._words[i].codePointAt(0);
}
length(){
length() {
return this._words.length;
}
}
Laya.class(CharSegment,'laya.webgl.text.CharSegment');
Laya.imps(CharSegment.prototype,{"laya.webgl.text.ICharSegment":true})
Laya.class(CharSegment, 'laya.webgl.text.CharSegment');
Laya.imps(CharSegment.prototype, { "laya.webgl.text.ICharSegment": true })
// Laya.init(1125, 2436, Laya.WebGL);
@@ -103,15 +103,15 @@ class App{
const screenWidth = window.innerWidth;
const screenHeight = window.innerHeight;
const screenRatio = screenWidth / screenHeight;
if(screenRatio > designRatio) {
if (screenRatio > designRatio) {
return [
Math.min(screenWidth*designHeight/screenHeight, maxWidth),
Math.min(screenWidth * designHeight / screenHeight, maxWidth),
designHeight
]
} else {
return [
designWidth,
Math.min(screenHeight*designWidth/screenWidth, maxHeight)
Math.min(screenHeight * designWidth / screenWidth, maxHeight)
]
}
}
@@ -121,7 +121,7 @@ class App{
}
async #setLanguage(language) {
switch(language) {
switch (language) {
case App.languages['en-us']:
case App.languages['zh-cn']:
this.#language = language;
@@ -131,23 +131,23 @@ class App{
break;
}
globalThis.$lang =
Laya.Text.langPacks =
Laya.Text.langPacks =
(await import(`./i18n/${this.#language}.js`)).default;
}
resigterEvent() {
$$on('achievement', achievement => {
$ui.popup(UI.popups.ACHIEVEMENT, {achievement});
$ui.popup(UI.popups.ACHIEVEMENT, { achievement });
})
$$on('message', ([message, ...args]) => {
if(Array.isArray(message)) {
message = message.map(([m, ...a]) => $_.format($lang[m], ...a)) .join('\n');
if (Array.isArray(message)) {
message = message.map(([m, ...a]) => $_.format($lang[m], ...a)).join('\n');
} else {
message = $_.format(
$lang[message], ...args
);
}
$ui.popup(UI.popups.MESSAGE, {message});
$ui.popup(UI.popups.MESSAGE, { message });
})
}
@@ -159,7 +159,7 @@ class App{
this.#initLaya();
globalThis.$ui = UIManager.getInstance();
if(theme=='default') {
if (theme == 'default') {
theme = localStorage.getItem('theme') || 'default';
}
@@ -168,8 +168,8 @@ class App{
await $ui.setLoading(UI.pages.LOADING);
await $ui.switchView(UI.pages.LOADING);
await core.initial(
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/${this.#language}/${dataSet}.json`, null, Laya.Loader.JSON),
dataSet => Laya.promises.loader.load(`data/${dataSet}.json`, null, Laya.Loader.JSON),
);
await $ui.switchView(UI.pages.MAIN);

View File

@@ -43,7 +43,7 @@ function parseCondition(condition) {
return conditions;
}
function checkCondition(property, condition) {
export function checkCondition(property, condition) {
const conditions = parseCondition(condition);
return checkParsedConditions(property, conditions);
}
@@ -113,7 +113,7 @@ function checkProp(property, condition) {
}
}
function extractMaxTriggers(condition) {
export function extractMaxTriggers(condition) {
// Assuming only age related talents can be triggered multiple times.
const RE_AGE_CONDITION = /AGE\?\[([0-9\,]+)\]/;
const match_object = RE_AGE_CONDITION.exec(condition);
@@ -124,6 +124,4 @@ function extractMaxTriggers(condition) {
const age_list = match_object[1].split(",");
return age_list.length;
}
export { checkCondition, extractMaxTriggers };
}

View File

@@ -0,0 +1,103 @@
import { expect, test, describe } from 'vitest'
import { checkCondition } from './condition'
function withProp(prop) {
const p = {
get(key) {
return prop[key]
},
}
return condition => checkCondition(p, condition)
}
describe('condition', () => {
const check = withProp({
n1: 0,
n2: -10,
n3: 10,
nl1: [1, 2, 3],
nl2: [0],
nl3: [],
})
test('gt(>)', () => {
expect(check('n3>11')).toBe(false)
expect(check('n3>10')).toBe(false)
expect(check('n3>9')).toBe(true)
})
test('gte(>=)', () => {
expect(check('n3>=11')).toBe(false)
expect(check('n3>=10')).toBe(true)
expect(check('n3>=9')).toBe(true)
})
test('lt(<)', () => {
expect(check('n3<9')).toBe(false)
expect(check('n3<10')).toBe(false)
expect(check('n3<11')).toBe(true)
})
test('lte(<=)', () => {
expect(check('n3<=9')).toBe(false)
expect(check('n3<=10')).toBe(true)
expect(check('n3<=11')).toBe(true)
})
test('eq(=)', () => {
expect(check('n3=9')).toBe(false)
expect(check('n3=10')).toBe(true)
expect(check('n3=11')).toBe(false)
expect(check('nl1=0')).toBe(false)
expect(check('nl1=1')).toBe(true)
expect(check('nl1=2')).toBe(true)
expect(check('nl1=3')).toBe(true)
})
test('ne(!=)', () => {
expect(check('n3!=9')).toBe(true)
expect(check('n3!=10')).toBe(false)
expect(check('n3!=11')).toBe(true)
expect(check('nl1!=0')).toBe(true)
expect(check('nl1!=1')).toBe(false)
expect(check('nl1!=2')).toBe(false)
expect(check('nl1!=3')).toBe(false)
})
test('in(?)', () => {
expect(check('n3?[1,2,3]')).toBe(false)
expect(check('n3?[10,11,12]')).toBe(true)
expect(check('nl1?[0,1]')).toBe(true)
expect(check('nl2?[1,2,3]')).toBe(false)
expect(check('nl3?[1,2,3]')).toBe(false)
expect(check('nl2?[]')).toBe(false)
expect(check('nl3?[]')).toBe(false)
})
test('notin(!)', () => {
expect(check('n3![1,2,3]')).toBe(true)
expect(check('n3![10,11,12]')).toBe(false)
expect(check('nl1![0,1]')).toBe(false)
expect(check('nl2![1,2,3]')).toBe(true)
expect(check('nl3![1,2,3]')).toBe(true)
expect(check('nl2![]')).toBe(true)
expect(check('nl3![]')).toBe(true)
})
test('and(&)', () => {
expect(check('n1>=0&n2<0')).toBe(true)
expect(check('n2>0&n3>0')).toBe(false)
expect(check('n2<0&n3<0')).toBe(false)
expect(check('n2<0&n3>0')).toBe(true)
expect(check('n1=0&n2<0&n3>0')).toBe(true)
expect(check('n1=0&n2>0&n3>0')).toBe(false)
})
test('or(|)', () => {
expect(check('n1>=0|n2<0')).toBe(true)
expect(check('n2>0|n3>0')).toBe(true)
expect(check('n2<0|n3<0')).toBe(true)
expect(check('n2<0|n3>0')).toBe(true)
expect(check('n2>0|n3<0')).toBe(false)
expect(check('n1=0|n2<0|n3>0')).toBe(true)
expect(check('n1=0|n2>0|n3>0')).toBe(true)
expect(check('n1!=0|n2>0|n3<0')).toBe(false)
})
test('mix', () => {
expect(check('(n1=0|n2<0|n3>0)&(n1=0|n2>0|n3>0)')).toBe(true)
expect(check('(n1=0|n2<0|n3>0)&(n1!=0|n2>0|n3<0)')).toBe(false)
expect(check('n1=0|n2<0|n3>0&n1!=0|n2>0|n3<0')).toBe(true)
expect(check('(n1>0|n1?[-10,0])&(n2>0|n3![0,1])')).toBe(true)
expect(check('(n1>0&n1?[-10,0])|(n2<0&n3![0,1])')).toBe(true)
})
})

View File

@@ -31,6 +31,7 @@ export default ({
UI_Thanks: 'Thx',
UI_Achievement: 'Achv',
UI_Cyber_Theme_Art_Design: 'UI Design by 晰晰',
UI_Banner: '作者的新作《纸上谈亲》已上线小程序\n微信/抖音搜索“纸上谈亲”即可游玩~',
UI_Title_Talent: 'Talent Draw',
UI_Talent_Draw: '!10 Pulls!',

View File

@@ -33,6 +33,7 @@ export default ({
UI_Thanks: '感谢',
UI_Achievement: '成就',
UI_Cyber_Theme_Art_Design: 'UI 设计 by 晰晰',
UI_Banner: '作者的新作《纸上谈亲》已上线小程序\n微信/抖音搜索“纸上谈亲”即可游玩~',
UI_Title_Talent: '天赋抽卡',
UI_Talent_Draw: '10连抽',

View File

@@ -54,7 +54,7 @@ class Life {
this.#specialThanks = specialThanks;
const total = {
[this.PropertyTypes.TACEV]: this.#achievement.initial({achievements}),
[this.PropertyTypes.TACHV]: this.#achievement.initial({achievements}),
[this.PropertyTypes.TEVT]: this.#event.initial({events}),
[this.PropertyTypes.TTLT]: this.#talent.initial({talents}),
};
@@ -174,7 +174,7 @@ class Life {
type: this.PropertyTypes.TLT,
name,
grade,
description,
description: this.format(description),
})
if(!effect) continue;
this.#property.effect(effect);
@@ -188,8 +188,8 @@ class Life {
this.#property.effect(effect);
const content = {
type: this.PropertyTypes.EVT,
description,
postEvent,
description: this.format(description),
postEvent: postEvent && this.format(postEvent),
grade,
}
if(next) return [content, this.doEvent(next)].flat();
@@ -245,6 +245,23 @@ class Life {
return util.getListValuesMap(types.flat(), key => this.#property.get(key));
}
format(discription) {
return `${discription}`.replaceAll(/\{\s*[0-9a-zA-Z_-]+\s*?\}/g, (match) => this.#format(match));
}
#format(key) {
switch (key.slice(1, -1).trim().toLowerCase()) {
case 'currentyear': return new Date().getFullYear()
case 'age': return this.#property.get(this.PropertyTypes.AGE)
case 'charm': return this.#property.get(this.PropertyTypes.CHR)
case 'intelligence': return this.#property.get(this.PropertyTypes.INT)
case 'strength': return this.#property.get(this.PropertyTypes.STR)
case 'money': return this.#property.get(this.PropertyTypes.MNY)
case 'spirit': return this.#property.get(this.PropertyTypes.SPR)
default: return key
}
}
get lastExtendTalent() {
return this.#property.get(this.PropertyTypes.EXT);
}

View File

@@ -68,10 +68,17 @@ class Talent {
exclude(talents, excludeId) {
const { exclude } = this.get(excludeId);
if(!exclude) return null;
for(const talent of talents) {
for(const e of exclude) {
if(talent == e) return talent;
if(exclude) {
for(const e of exclude) {
if(talent == e) return talent;
}
}
const excludeReverse = this.get(talent).exclude;
if(excludeReverse) {
for (const e of excludeReverse) {
if (excludeId == e) return talent
}
}
}
return null;

File diff suppressed because one or more lines are too long

View File

@@ -30,6 +30,7 @@ export default class CyberMain extends ui.view.CyberTheme.CyberMainUI {
}
init() {
this.banner.visible =
this.btnDiscord.visible =
this.btnAchievement.visible =
this.btnThanks.visible = !!core.times;

View File

@@ -17,6 +17,7 @@ export default class Main extends ui.view.DefaultTheme.MainUI {
}
init() {
this.banner.visible =
this.btnDiscord.visible =
this.btnAchievement.visible =
this.btnThanks.visible = !!core.times;

View File

@@ -1,360 +1,397 @@
import Views from './themes/views.js';
import Views from './views.js'
export default class UIManager {
constructor(stage) {
UIManager.#views = Views;
UIManager.#views = Views
if(!stage) {
stage = Laya.stage;
if (!stage) {
stage = Laya.stage
}
this.#stage = stage;
this.#stage = stage
stage.addChild(this.#viewLayer);
this.#viewLayer.zOrder = 1;
stage.addChild(this.#dialogLayer);
this.#dialogLayer.zOrder = 2;
stage.addChild(this.#popupLayer);
this.#popupLayer.zOrder = 3;
stage.addChild(this.#viewLayer)
this.#viewLayer.zOrder = 1
stage.addChild(this.#dialogLayer)
this.#dialogLayer.zOrder = 2
stage.addChild(this.#popupLayer)
this.#popupLayer.zOrder = 3
this.#viewLayer.top =
this.#viewLayer.bottom =
this.#viewLayer.left =
this.#viewLayer.right =
this.#dialogLayer.top =
this.#dialogLayer.bottom =
this.#dialogLayer.left =
this.#dialogLayer.right =
this.#popupLayer.top =
this.#popupLayer.bottom =
this.#popupLayer.left =
this.#popupLayer.right =
this.#dialogMask.top =
this.#dialogMask.bottom =
this.#dialogMask.left =
this.#dialogMask.right = 0;
this.#dialogMask.graphics.drawRect(0, 0, 5000, 5000, '#000000');
this.#dialogMask.alpha = 0.4;
this.#dialogMask.on(Laya.Event.CLICK, this, ()=>{
this.#dialogStack[this.#dialogStack.length - 1]?.close?.();
this.#viewLayer.bottom =
this.#viewLayer.left =
this.#viewLayer.right =
this.#dialogLayer.top =
this.#dialogLayer.bottom =
this.#dialogLayer.left =
this.#dialogLayer.right =
this.#popupLayer.top =
this.#popupLayer.bottom =
this.#popupLayer.left =
this.#popupLayer.right =
this.#dialogMask.top =
this.#dialogMask.bottom =
this.#dialogMask.left =
this.#dialogMask.right =
0
this.#dialogMask.graphics.drawRect(0, 0, 5000, 5000, '#000000')
this.#dialogMask.alpha = 0.4
this.#dialogMask.on(Laya.Event.CLICK, this, () => {
this.#dialogStack[this.#dialogStack.length - 1]?.close?.()
})
}
static #instance = {};
static #views;
#stage;
#loading;
#currentView;
#viewLayer = new Laya.Panel();
#dialogLayer = new Laya.Panel();
#popupLayer = new Laya.Panel();
#dialogMask = new Laya.Sprite();
#viewMap = new Map();
#class = new Map();
#dialogStack = [];
static #instance = {}
static #views
#stage
#loading
#currentView
#viewLayer = new Laya.Panel()
#dialogLayer = new Laya.Panel()
#popupLayer = new Laya.Panel()
#dialogMask = new Laya.Sprite()
#viewMap = new Map()
#class = new Map()
#dialogStack = []
static get inst() {
return this.getInstance();
return this.getInstance()
}
static getInstance(name="default") {
return this.#instance[name] || (this.#instance[name] = new UIManager());
static getInstance(name = 'default') {
return this.#instance[name] || (this.#instance[name] = new UIManager())
}
static get pages() {
return this.#views.pages;
return this.#views.pages
}
static get popups() {
return this.#views.popups;
return this.#views.popups
}
static theme(theme, prop) {
return this.#views.themes[theme][prop];
return this.#views.themes[theme][prop]
}
async setLoading(loading) {
const className = this.#pages[loading];
const view = await this.getView(className, null, null, loading);
view.top = view.bottom = view.left = view.right = 0;
view.zOrder = 4;
this.#loading = view;
const className = this.#pages[loading]
const view = await this.getView(className, null, null, loading)
view.top = view.bottom = view.left = view.right = 0
view.zOrder = 4
this.#loading = view
}
async switchView(viewName, args, actions) {
const className = this.#pages[viewName];
const className = this.#pages[viewName]
// get view instance
const view = await this.getView(className, args, actions?.load, viewName, 'pages');
const view = await this.getView(
className,
args,
actions?.load,
viewName,
'pages'
)
view.top = view.bottom = view.left = view.right = 0;
view.top = view.bottom = view.left = view.right = 0
// close current view
this.clearAllDialog();
await this.#currentView?.__close?.(view);
await this.#currentView?.close?.(view);
this.#viewLayer.removeChildren();
this.clearAllDialog()
await this.#currentView?.__close?.(view)
await this.#currentView?.close?.(view)
this.#viewLayer.removeChildren()
// open new view
await view.init?.(args);
await view.init?.(args)
this.#currentView = view;
this.#viewLayer.addChild(view);
this.#currentView = view
this.#viewLayer.addChild(view)
view.__close = actions?.close;
await actions?.open?.(view);
await view.show?.();
view.__close = actions?.close
await actions?.open?.(view)
await view.show?.()
}
async getView(className, args, preload, viewName, type) {
// check if view is already loaded
let view = await this.#viewMap.get(className);
let view = await this.#viewMap.get(className)
let timeout;
if(this.#loading) {
let timeout
if (this.#loading) {
timeout = setTimeout(
()=>this.#stage.addChild(this.#loading),
() => this.#stage.addChild(this.#loading),
3000
);
)
}
const onProgress = this.#loading?.onProgress;
const onProgress = this.#loading?.onProgress
if(!view) {
if (!view) {
// load view
const ViewClass = await this.loadView(className);
const resourceList = await ViewClass.load?.(args);
const scanedResourceList = this.#loading? this.scanResource(ViewClass.uiView): [];
if(preload) {
preload = [].concat(preload).concat(scanedResourceList);
const ViewClass = await this.loadView(className)
const resourceList = await ViewClass.load?.(args)
const scanedResourceList = this.#loading
? this.scanResource(ViewClass.uiView)
: []
if (preload) {
preload = [].concat(preload).concat(scanedResourceList)
} else {
preload = scanedResourceList;
preload = scanedResourceList
}
await this.loadRes(resourceList, preload, onProgress);
await this.loadRes(resourceList, preload, onProgress)
// create view
view = new ViewClass();
view = new ViewClass()
// add view to map
this.#viewMap.set(className, view);
this.#viewMap.set(className, view)
} else {
// load resource
const resourceList = await view.constructor.load?.(args);
await this.loadRes(resourceList, preload, onProgress);
const resourceList = await view.constructor.load?.(args)
await this.loadRes(resourceList, preload, onProgress)
}
if(timeout) clearTimeout(timeout);
this.#loading?.removeSelf();
if (timeout) clearTimeout(timeout)
this.#loading?.removeSelf()
this.#config(view, viewName, type);
this.#config(view, viewName, type)
// return view
return view;
return view
}
async loadView(className) {
// load view
if(this.#class.has(className)) return this.#class.get(className);
const c = (await import(`./themes/${className}.js`)).default;
this.#class.set(className, c);
return c;
if (this.#class.has(className)) return this.#class.get(className)
const views = import.meta.glob('./themes/**/*.js')
const view = (await views[`./themes/${className}.js`]()).default
this.#class.set(className, view)
return view
}
async loadRes(resourceList, preload, onProgress) {
const cnt = (resourceList?.length || 0)
+(preload?.length || 0);
if(resourceList && resourceList.length) {
const s = resourceList.length / cnt;
await Laya.promises.loader.load(resourceList, Laya.Handler.create(null, prg=>onProgress?.(prg*s)));
const cnt = (resourceList?.length || 0) + (preload?.length || 0)
if (resourceList && resourceList.length) {
const s = resourceList.length / cnt
await Laya.promises.loader.load(
resourceList,
Laya.Handler.create(null, prg => onProgress?.(prg * s))
)
}
if(preload && preload.length) {
const s = 1 - preload.length / cnt;
const l = preload.length / cnt;
await Laya.promises.loader.load(preload, Laya.Handler.create(null, prg=>onProgress?.(prg*l+s)));
if (preload && preload.length) {
const s = 1 - preload.length / cnt
const l = preload.length / cnt
await Laya.promises.loader.load(
preload,
Laya.Handler.create(null, prg => onProgress?.(prg * l + s))
)
}
}
#showDialogStack() {
if(this.#dialogStack.length == 0) {
this.#dialogLayer.visible = false;
return;
if (this.#dialogStack.length == 0) {
this.#dialogLayer.visible = false
return
}
this.#dialogLayer.visible = true;
this.#dialogStack.forEach((dialog, i)=>{
this.#dialogLayer.addChild(dialog);
dialog.zOrder = i;
this.#dialogLayer.visible = true
this.#dialogStack.forEach((dialog, i) => {
this.#dialogLayer.addChild(dialog)
dialog.zOrder = i
})
this.#dialogLayer.addChild(this.#dialogMask);
const l = this.#dialogStack.length;
this.#dialogMask.zOrder = l -1;
this.#dialogStack[l -1].zOrder = l;
this.#dialogLayer.addChild(this.#dialogMask)
const l = this.#dialogStack.length
this.#dialogMask.zOrder = l - 1
this.#dialogStack[l - 1].zOrder = l
}
async showDialog(dialogName, args, actions) {
const className = this.#pages[dialogName];
const dialog = await this.getView(className, args, actions?.load, dialogName, 'pages');
const className = this.#pages[dialogName]
const dialog = await this.getView(
className,
args,
actions?.load,
dialogName,
'pages'
)
const index = this.#dialogStack.indexOf(dialog);
if(index != -1) {
this.#dialogStack.splice(index, 1);
const index = this.#dialogStack.indexOf(dialog)
if (index != -1) {
this.#dialogStack.splice(index, 1)
}
this.#dialogStack.push(dialog);
dialog.init?.(args);
dialog.centerX = dialog.centerY = 0;
this.#showDialogStack();
this.#dialogStack.push(dialog)
dialog.init?.(args)
dialog.centerX = dialog.centerY = 0
this.#showDialogStack()
const open = actions?.open || (async () => {
dialog.scaleX = 0;
dialog.scaleY = 0;
await Laya.promises.Tween.to(dialog, { scaleX: 1, scaleY: 1 }, 300, Laya.Ease.backOut);
});
await open(dialog);
dialog.mouseThrough = true;
dialog.mouseEnabled = true;
dialog.close = async ()=>{
if(actions?.close) {
await actions.close();
const open =
actions?.open ||
(async () => {
dialog.scaleX = 0
dialog.scaleY = 0
await Laya.promises.Tween.to(
dialog,
{ scaleX: 1, scaleY: 1 },
300,
Laya.Ease.backOut
)
})
await open(dialog)
dialog.mouseThrough = true
dialog.mouseEnabled = true
dialog.close = async () => {
if (actions?.close) {
await actions.close()
} else {
await Laya.promises.Tween.to(dialog, { scaleX: 0, scaleY: 0 }, 300, Laya.Ease.strongIn);
await Laya.promises.Tween.to(
dialog,
{ scaleX: 0, scaleY: 0 },
300,
Laya.Ease.strongIn
)
}
const index = this.#dialogStack.indexOf(dialog);
if(index != -1) {
this.#dialogStack.splice(index, 1);
const index = this.#dialogStack.indexOf(dialog)
if (index != -1) {
this.#dialogStack.splice(index, 1)
}
this.#showDialogStack();
this.#showDialogStack()
}
this.#dialogLayer.addChild(dialog);
this.#dialogLayer.addChild(dialog)
}
async popup(type, args) {
const className = this.#popups[type];
const popup = await this.getView(className, args, null, type, 'popups');
this.#popupLayer.addChild(popup);
await popup.popup(args, this.#popupLayer);
this.#popupLayer.removeChild(popup);
const className = this.#popups[type]
const popup = await this.getView(className, args, null, type, 'popups')
this.#popupLayer.addChild(popup)
await popup.popup(args, this.#popupLayer)
this.#popupLayer.removeChild(popup)
}
clearAllDialog() {
this.#dialogStack = [];
this.#showDialogStack();
this.#dialogStack = []
this.#showDialogStack()
}
#config(view, key, type) {
const config = this.#configs?.[type]?.[key];
if(!config) return;
if(view.config && view.config(config)) return;
const config = this.#configs?.[type]?.[key]
if (!config) return
if (view.config && view.config(config)) return
const applyConfig = (target, config) => {
if(!target) return;
if(typeof config == 'string') {
config = this.#configs?.class?.[config];
if (!target) return
if (typeof config == 'string') {
config = this.#configs?.class?.[config]
}
$_.deepMapSet(target, config);
};
$_.deepMapSet(target, config)
}
if(config.names)
for(const name in config.names)
this.#deepGetChildsByName(view, name)
.forEach(child => applyConfig(child, config.names[name]));
if(config.vars)
for(const key in config.vars)
applyConfig(view[key], config.vars[key]);
if (config.names)
for (const name in config.names)
this.#deepGetChildsByName(view, name).forEach(child =>
applyConfig(child, config.names[name])
)
if (config.vars)
for (const key in config.vars)
applyConfig(view[key], config.vars[key])
}
#deepGetChildsByName(parent, name) {
const list = [];
if(!parent || !parent._childs) return list;
const list = []
if (!parent || !parent._childs) return list
for(const child of parent._childs) {
if(child.name == name) list.push(child);
if(child._childs) list.push(...this.#deepGetChildsByName(child, name));
for (const child of parent._childs) {
if (child.name == name) list.push(child)
if (child._childs)
list.push(...this.#deepGetChildsByName(child, name))
}
return list;
return list
}
#cutPath(path) {
path = ''+path;
let index = path.length;
path = '' + path
let index = path.length
do {
index --;
if(path[index] == '.') {
break;
index--
if (path[index] == '.') {
break
}
} while (index>0)
return [
path.substring(0, index),
path.substring(index, path.length)
];
} while (index > 0)
return [path.substring(0, index), path.substring(index, path.length)]
}
#subSkin(skin, type) {
if(!skin || !skin.replace(/\s/g, '')) return [];
if (!skin || !skin.replace(/\s/g, '')) return []
switch (type) {
case 'ProgressBar':
return [ skin, ...this.#progressBarSkin(skin) ];
return [skin, ...this.#progressBarSkin(skin)]
case 'ScrollBar':
return [ skin, ...this.#scrollBarSkin(skin) ];
return [skin, ...this.#scrollBarSkin(skin)]
default:
return [skin]
}
}
#progressBarSkin(skin) {
if(!skin.replace(/\s/g, '')) return [];
let p = this.#cutPath(skin);
return [`${p[0]}$bar${p[1]}`];
if (!skin.replace(/\s/g, '')) return []
let p = this.#cutPath(skin)
return [`${p[0]}$bar${p[1]}`]
}
#scrollBarSkin(skin) {
if(!skin.replace(/\s/g, '')) return [];
let p = this.#cutPath(skin);
if (!skin.replace(/\s/g, '')) return []
let p = this.#cutPath(skin)
return [
`${p[0]}$bar${p[1]}`,
`${p[0]}$up${p[1]}`,
`${p[0]}$down${p[1]}`
];
`${p[0]}$down${p[1]}`,
]
}
scanResource(uiView) {
if(!uiView) return [];
const resourceList = [];
if (!uiView) return []
const resourceList = []
resourceList.push(...this.#subSkin(uiView.props?.skin, uiView.type));
resourceList.push(...this.#subSkin(uiView.props?.hScrollBarSkin, 'ScrollBar'));
resourceList.push(...this.#subSkin(uiView.props?.vScrollBarSkin, 'ScrollBar'));
resourceList.push(...this.#subSkin(uiView.props?.skin, uiView.type))
resourceList.push(
...this.#subSkin(uiView.props?.hScrollBarSkin, 'ScrollBar')
)
resourceList.push(
...this.#subSkin(uiView.props?.vScrollBarSkin, 'ScrollBar')
)
uiView.child?.forEach(child => {
resourceList.push(...this.scanResource(child));
});
resourceList.push(...this.scanResource(child))
})
return resourceList;
return resourceList
}
get currentView() {
return this.#currentView;
return this.#currentView
}
get currentDialog() {
return this.#dialogStack[this.#dialogStack.length -1];
return this.#dialogStack[this.#dialogStack.length - 1]
}
get theme() {
return localStorage.getItem('theme');
return localStorage.getItem('theme')
}
set theme(value) {
localStorage.setItem('theme', value);
this.#stage.bgColor = this.#configs.bgColor;
document?.querySelector?.('meta[name="theme-color"]')?.setAttribute?.('content', this.#configs.bgColor);
localStorage.setItem('theme', value)
this.#stage.bgColor = this.#configs.bgColor
document
?.querySelector?.('meta[name="theme-color"]')
?.setAttribute?.('content', this.#configs.bgColor)
}
get #pages() {
return UIManager.theme(this.theme, 'pages');
return UIManager.theme(this.theme, 'pages')
}
get #popups() {
return UIManager.theme(this.theme, 'popups');
return UIManager.theme(this.theme, 'popups')
}
get #configs() {
return UIManager.theme(this.theme, 'configs');
return UIManager.theme(this.theme, 'configs')
}
get common() {
return this.#configs.common;
return this.#configs.common
}
gradeColor(grade) {
return this.common.grade[grade];
return this.common.grade[grade]
}
gradeFilter(grade) {
return this.common.filter[grade];
return this.common.filter[grade]
}
}
}

View File

@@ -10,32 +10,32 @@ const pages = {
THEMES: 'THEMES',
SAVELOAD: 'SAVELOAD',
MODE: 'MODE',
CELEBRITY: 'CELEBRITY'
};
CELEBRITY: 'CELEBRITY',
}
const popups = {
ACHIEVEMENT: 'POPUP_ACHIEVEMENT',
MESSAGE: 'POPUP_MESSAGE',
};
}
const cyber = {
pages: {
[pages.LOADING]: "loading",
[pages.MAIN]: "cyber/main",
[pages.TALENT]: "cyber/talent",
[pages.PROPERTY]: "cyber/property",
[pages.TRAJECTORY]: "cyber/trajectory",
[pages.SUMMARY]: "cyber/summary",
[pages.ACHIEVEMENT]: "cyber/achievement",
[pages.THANKS]: "default/thanks",
[pages.LOADING]: 'loading',
[pages.MAIN]: 'cyber/main',
[pages.TALENT]: 'cyber/talent',
[pages.PROPERTY]: 'cyber/property',
[pages.TRAJECTORY]: 'cyber/trajectory',
[pages.SUMMARY]: 'cyber/summary',
[pages.ACHIEVEMENT]: 'cyber/achievement',
[pages.THANKS]: 'default/thanks',
[pages.THEMES]: 'themes',
[pages.SAVELOAD]: 'saveload',
[pages.MODE]: 'cyber/mode',
[pages.CELEBRITY]: 'cyber/celebrity',
},
popups: {
[popups.ACHIEVEMENT]: "cyber/popup/achievementPopup",
[popups.MESSAGE]: "message",
[popups.ACHIEVEMENT]: 'cyber/popup/achievementPopup',
[popups.MESSAGE]: 'message',
},
configs: {
bgColor: '#04131f',
@@ -47,18 +47,8 @@ const cyber = {
hoverStroke: '#ffa500',
},
defaultFontColor: '#cccccc',
grade: [
'#cccccc',
'#55fffe',
'#b17cff',
'#ffce45',
],
filter: [
'#ccccccff',
'#55fffeff',
'#b17cffff',
'#ffce45ff',
],
grade: ['#cccccc', '#55fffe', '#b17cff', '#ffce45'],
filter: ['#ccccccff', '#55fffeff', '#b17cffff', '#ffce45ff'],
gradeBlk: [
{
visible: false,
@@ -78,7 +68,7 @@ const cyber = {
hoverColor: '#ffce45',
visible: true,
},
]
],
},
pages: {
[pages.MAIN]: {
@@ -97,7 +87,7 @@ const cyber = {
lineWidth: 0,
radius: 100,
},
}
},
},
[pages.THANKS]: {
vars: {
@@ -147,7 +137,7 @@ const cyber = {
hoverLabel: '#ffffff',
radius: 80,
},
}
},
},
[pages.SAVELOAD]: {
vars: {
@@ -184,31 +174,31 @@ const cyber = {
radius: 80,
defaultLabel: '#ffffff',
hoverLabel: '#ffffff',
}
}
},
},
},
}
}
},
},
}
const dark = {
pages: {
[pages.LOADING]: "loading",
[pages.MAIN]: "default/main",
[pages.TALENT]: "default/talent",
[pages.PROPERTY]: "default/property",
[pages.TRAJECTORY]: "default/trajectory",
[pages.SUMMARY]: "default/summary",
[pages.ACHIEVEMENT]: "default/achievement",
[pages.THANKS]: "default/thanks",
[pages.LOADING]: 'loading',
[pages.MAIN]: 'default/main',
[pages.TALENT]: 'default/talent',
[pages.PROPERTY]: 'default/property',
[pages.TRAJECTORY]: 'default/trajectory',
[pages.SUMMARY]: 'default/summary',
[pages.ACHIEVEMENT]: 'default/achievement',
[pages.THANKS]: 'default/thanks',
[pages.THEMES]: 'themes',
[pages.SAVELOAD]: 'saveload',
[pages.MODE]: 'default/mode',
[pages.CELEBRITY]: 'default/celebrity',
},
popups: {
[popups.ACHIEVEMENT]: "default/popup/achievementPopup",
[popups.MESSAGE]: "message",
[popups.ACHIEVEMENT]: 'default/popup/achievementPopup',
[popups.MESSAGE]: 'message',
},
configs: {
bgColor: '#222831',
@@ -248,18 +238,8 @@ const dark = {
hoverColor: '#ffc500',
hoverStroke: '#ffa500',
},
grade: [
'#cccccc',
'#55fffe',
'#b17cff',
'#ffce45',
],
filter: [
'#ccccccff',
'#55fffeff',
'#b17cffff',
'#ffce45ff',
],
grade: ['#cccccc', '#55fffe', '#b17cff', '#ffce45'],
filter: ['#ccccccff', '#55fffeff', '#b17cffff', '#ffce45ff'],
card: [
{
normal: {
@@ -281,7 +261,7 @@ const dark = {
hoverLabel: '#3b3b3b',
lineWidth: 4,
radius: 4,
}
},
},
{
normal: {
@@ -303,7 +283,7 @@ const dark = {
hoverLabel: '#3b3b3b',
lineWidth: 4,
radius: 4,
}
},
},
{
normal: {
@@ -325,7 +305,7 @@ const dark = {
hoverLabel: '#3b3b3b',
lineWidth: 4,
radius: 4,
}
},
},
{
normal: {
@@ -347,8 +327,8 @@ const dark = {
hoverLabel: '#3b3b3b',
lineWidth: 4,
radius: 4,
}
}
},
},
],
summary: [
{
@@ -360,7 +340,8 @@ const dark = {
hoverLabel: '#3b3b3b',
lineWidth: 2,
radius: 0,
},{
},
{
defaultColor: '#6495ed',
defaultStroke: '#f8f8f8',
defaultLabel: '#eeeeee',
@@ -369,7 +350,8 @@ const dark = {
hoverLabel: '#3b3b3b',
lineWidth: 2,
radius: 0,
},{
},
{
defaultColor: '#e2a7ff',
defaultStroke: '#f8f8f8',
defaultLabel: '#eeeeee',
@@ -388,7 +370,7 @@ const dark = {
hoverLabel: '#3b3b3b',
lineWidth: 2,
radius: 0,
}
},
],
achievement: [
{
@@ -400,7 +382,8 @@ const dark = {
hoverLabel: '#3b3b3b',
lineWidth: 4,
radius: 0,
},{
},
{
defaultColor: '#6495ed',
defaultStroke: '#f8f8f8',
defaultLabel: '#eeeeee',
@@ -409,7 +392,8 @@ const dark = {
hoverLabel: '#3b3b3b',
lineWidth: 4,
radius: 0,
},{
},
{
defaultColor: '#e2a7ff',
defaultStroke: '#f8f8f8',
defaultLabel: '#eeeeee',
@@ -428,7 +412,7 @@ const dark = {
hoverLabel: '#3b3b3b',
lineWidth: 4,
radius: 0,
}
},
],
characterItem: {
name: {
@@ -488,7 +472,7 @@ const dark = {
},
font_default: {
color: '#eeeeee',
}
},
},
pages: {
[pages.MAIN]: {
@@ -512,14 +496,14 @@ const dark = {
names: {
title: 'title',
btnSmall: 'btn_small',
}
},
},
[pages.TALENT]: {
vars: {
btnDrawCard: 'btn_main',
btnNext: 'btn_main',
title: 'title',
}
},
},
[pages.PROPERTY]: {
vars: {
@@ -530,9 +514,9 @@ const dark = {
names: {
font_default: 'font_default',
property: {
colorFilter: '#eeeeeeff'
}
}
colorFilter: '#eeeeeeff',
},
},
},
[pages.TRAJECTORY]: {
vars: {
@@ -548,8 +532,8 @@ const dark = {
radius: 4,
},
boxSpeed: {
colorFilter: '#ffffffff'
}
colorFilter: '#ffffffff',
},
},
names: {
propertyBox: {
@@ -571,8 +555,8 @@ const dark = {
hoverLabel: '#222831',
lineWidth: 0,
radius: 4,
}
}
},
},
},
[pages.SUMMARY]: {
vars: {
@@ -581,7 +565,7 @@ const dark = {
},
names: {
font_default: 'font_default',
}
},
},
[pages.ACHIEVEMENT]: {
vars: {
@@ -591,7 +575,7 @@ const dark = {
names: {
font_default: 'font_default',
title: 'title',
}
},
},
[pages.THANKS]: {
vars: {
@@ -632,7 +616,7 @@ const dark = {
hoverLabel: '#ffffff',
radius: 80,
},
}
},
},
[pages.SAVELOAD]: {
vars: {
@@ -669,20 +653,20 @@ const dark = {
radius: 80,
defaultLabel: '#ffffff',
hoverLabel: '#ffffff',
}
}
},
},
},
[pages.MODE]: {
names: {
font_default: 'font_default',
btn: 'btn_main',
}
},
},
[pages.CELEBRITY]: {
vars: {
btnRetry: 'btn_main',
btnNext: 'btn_main2',
}
},
},
},
popups: {
@@ -693,31 +677,31 @@ const dark = {
defaultStroke: '#84ff55',
hoverColor: '#292a28',
hoverStroke: '#84ff55',
}
}
}
}
}
},
},
},
},
},
}
const light = {
pages: {
[pages.LOADING]: "loading",
[pages.MAIN]: "default/main",
[pages.TALENT]: "default/talent",
[pages.PROPERTY]: "default/property",
[pages.TRAJECTORY]: "default/trajectory",
[pages.SUMMARY]: "default/summary",
[pages.ACHIEVEMENT]: "default/achievement",
[pages.THANKS]: "default/thanks",
[pages.LOADING]: 'loading',
[pages.MAIN]: 'default/main',
[pages.TALENT]: 'default/talent',
[pages.PROPERTY]: 'default/property',
[pages.TRAJECTORY]: 'default/trajectory',
[pages.SUMMARY]: 'default/summary',
[pages.ACHIEVEMENT]: 'default/achievement',
[pages.THANKS]: 'default/thanks',
[pages.THEMES]: 'themes',
[pages.SAVELOAD]: 'saveload',
[pages.MODE]: 'default/mode',
[pages.CELEBRITY]: 'default/celebrity',
},
popups: {
[popups.ACHIEVEMENT]: "default/popup/achievementPopup",
[popups.MESSAGE]: "message",
[popups.ACHIEVEMENT]: 'default/popup/achievementPopup',
[popups.MESSAGE]: 'message',
},
configs: {
bgColor: '#ffffff',
@@ -757,18 +741,8 @@ const light = {
hoverColor: '#ffc500',
hoverStroke: '#ffa500',
},
grade: [
'#000000',
'#55fffe',
'#b17cff',
'#ffce45',
],
filter: [
'#000000ff',
'#55fffeff',
'#b17cffff',
'#ffce45ff',
],
grade: ['#000000', '#55fffe', '#b17cff', '#ffce45'],
filter: ['#000000ff', '#55fffeff', '#b17cffff', '#ffce45ff'],
card: [
{
normal: {
@@ -790,7 +764,7 @@ const light = {
hoverLabel: '#ffffff',
lineWidth: 4,
radius: 4,
}
},
},
{
normal: {
@@ -812,7 +786,7 @@ const light = {
hoverLabel: '#ffffff',
lineWidth: 4,
radius: 4,
}
},
},
{
normal: {
@@ -834,7 +808,7 @@ const light = {
hoverLabel: '#ffffff',
lineWidth: 4,
radius: 4,
}
},
},
{
normal: {
@@ -856,8 +830,8 @@ const light = {
hoverLabel: '#ffffff',
lineWidth: 4,
radius: 4,
}
}
},
},
],
summary: [
{
@@ -869,7 +843,8 @@ const light = {
hoverLabel: '#ffffff',
lineWidth: 4,
radius: 4,
},{
},
{
defaultColor: '#6495ed',
defaultStroke: '#f8f8f8',
defaultLabel: '#ffffff',
@@ -878,7 +853,8 @@ const light = {
hoverLabel: '#666666',
lineWidth: 4,
radius: 4,
},{
},
{
defaultColor: '#e2a7ff',
defaultStroke: '#f8f8f8',
defaultLabel: '#ffffff',
@@ -887,7 +863,8 @@ const light = {
hoverLabel: '#666666',
lineWidth: 4,
radius: 4,
},{
},
{
defaultColor: '#ffa07a',
defaultStroke: '#f8f8f8',
defaultLabel: '#ffffff',
@@ -908,7 +885,8 @@ const light = {
hoverLabel: '#efefef',
lineWidth: 4,
radius: 0,
},{
},
{
defaultColor: '#6495ed',
defaultStroke: '#cccccc',
defaultLabel: '#eeeeee',
@@ -917,7 +895,8 @@ const light = {
hoverLabel: '#3b3b3b',
lineWidth: 4,
radius: 0,
},{
},
{
defaultColor: '#e2a7ff',
defaultStroke: '#cccccc',
defaultLabel: '#eeeeee',
@@ -926,7 +905,8 @@ const light = {
hoverLabel: '#3b3b3b',
lineWidth: 4,
radius: 0,
},{
},
{
defaultColor: '#ffa07a',
defaultStroke: '#cccccc',
defaultLabel: '#eeeeee',
@@ -935,7 +915,7 @@ const light = {
hoverLabel: '#3b3b3b',
lineWidth: 4,
radius: 0,
}
},
],
characterItem: {
name: {
@@ -995,7 +975,7 @@ const light = {
},
font_default: {
color: '#000000',
}
},
},
pages: {
[pages.MAIN]: {
@@ -1019,14 +999,14 @@ const light = {
names: {
title: 'title',
btnSmall: 'btn_small',
}
},
},
[pages.TALENT]: {
vars: {
btnDrawCard: 'btn_main',
btnNext: 'btn_main',
title: 'title',
}
},
},
[pages.PROPERTY]: {
vars: {
@@ -1037,9 +1017,9 @@ const light = {
names: {
font_default: 'font_default',
property: {
colorFilter: '#000000ff'
}
}
colorFilter: '#000000ff',
},
},
},
[pages.TRAJECTORY]: {
vars: {
@@ -1055,8 +1035,8 @@ const light = {
radius: 4,
},
boxSpeed: {
colorFilter: '#666666ff'
}
colorFilter: '#666666ff',
},
},
names: {
propertyBox: {
@@ -1078,8 +1058,8 @@ const light = {
hoverLabel: '#222831',
lineWidth: 0,
radius: 4,
}
}
},
},
},
[pages.SUMMARY]: {
vars: {
@@ -1088,7 +1068,7 @@ const light = {
},
names: {
font_default: 'font_default',
}
},
},
[pages.ACHIEVEMENT]: {
vars: {
@@ -1098,7 +1078,7 @@ const light = {
names: {
font_default: 'font_default',
title: 'title',
}
},
},
[pages.THANKS]: {
vars: {
@@ -1120,7 +1100,7 @@ const light = {
hoverStroke: '#dc76a9',
hoverLabel: '#ffffff',
radius: 4,
}
},
},
},
[pages.THEMES]: {
@@ -1139,7 +1119,7 @@ const light = {
hoverLabel: '#ffffff',
radius: 80,
},
}
},
},
[pages.SAVELOAD]: {
vars: {
@@ -1176,20 +1156,20 @@ const light = {
radius: 80,
defaultLabel: '#ffffff',
hoverLabel: '#ffffff',
}
}
},
},
},
[pages.MODE]: {
names: {
font_default: 'font_default',
btn: 'btn_main',
}
},
},
[pages.CELEBRITY]: {
vars: {
btnRetry: 'btn_main',
btnNext: 'btn_main2',
}
},
},
},
popups: {
@@ -1201,14 +1181,13 @@ const light = {
hoverColor: '#ffffff',
hoverStroke: '#84ff55',
lineWidth: 1,
}
}
}
}
}
},
},
},
},
},
}
const themes = { default: dark, cyber, dark, light };
const themes = { default: dark, cyber, dark, light }
export default { themes, pages, popups };
export default { themes, pages, popups }

View File

@@ -2,10 +2,7 @@
<html lang="{{ site.lang | default: "en-US" }}">
<head>
<meta charset="UTF-8">
<script data-ad-client="ca-pub-9857163863537600" async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
{% seo %}
<link rel="preconnect" href="https://fonts.gstatic.com">
<link rel="preload" href="https://fonts.googleapis.com/css?family=Open+Sans:400,700&display=swap" as="style" type="text/css" crossorigin>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#157878">
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
@@ -18,8 +15,7 @@
<header class="page-header" role="banner">
<h1 class="project-name">{{ page.title | default: site.title | default: site.github.repository_name }}</h1>
<h2 class="project-tagline">{{ page.description | default: site.description | default: site.github.project_tagline }}</h2>
<a href="/view/" class="btn">RESTART</a>
<a href="/view/test.html" class="btn">Source Version</a>
<a href="/public/" class="btn">RESTART</a>
{% if site.github.is_project_page %}
<a href="{{ site.github.repository_url }}" class="btn">View on GitHub</a>
{% endif %}

View File

@@ -7,10 +7,8 @@
<meta name="description" content="やり直すんだ。そして、次はうまくやる。"/>
<meta name="keywords" content="人生重开模拟器 liferestart life restart remake 人生重来"/>
<title>Life Restart</title>
</head>
<body>
<script language="javascript" type="text/javascript">
window.location.href="/public/index.html";
</script>
</body>
</head>
</html>

View File

@@ -1,74 +0,0 @@
import { readFile } from 'fs/promises';
import Life from '../src/life.js'
globalThis.json = async fileName => JSON.parse(await readFile(`data/${fileName}.json`));
globalThis.localStorage = {};
localStorage.getItem = key => localStorage[key]===void 0? null: localStorage[key];
localStorage.setItem = (key, value) => (localStorage[key] = value);
globalThis.$$eventMap = new Map();
globalThis.$$event = (tag, data) => {
const listener = $$eventMap.get(tag);
if(listener) listener.forEach(fn=>fn(data));
}
globalThis.$$on = (tag, fn) => {
let listener = $$eventMap.get(tag);
if(!listener) {
listener = new Set();
$$eventMap.set(tag, listener);
}
listener.add(fn);
}
globalThis.$$off = (tag, fn) => {
const listener = $$eventMap.get(tag);
if(listener) listener.delete(fn);
}
async function debug() {
const life = new Life();
await life.initial();
life.restart({
CHR: 5, // 颜值 charm CHR
INT: 5, // 智力 intelligence INT
STR: 5, // 体质 strength STR
MNY: 5, // 家境 money MNY
SPR: 5, // 快乐 spirit SPR
// AGE: 100,
TLT: [1134, 1048, 1114], // 天赋 talent TLT
});
const lifeTrajectory = [];
let trajectory;
do{
try{
trajectory = life.next();
} catch(e) {
console.error(e);
// debugger
throw e;
}
lifeTrajectory.push(trajectory);
const { age, content } = trajectory;
console.debug(
`---------------------------------`,
`\n-- ${age}\n `,
content.map(
({type, description, rate, name, postEvent}) => {
switch(type) {
case 'TLT':
return `天赋【${name}】发动:${description}`;
case 'EVT':
return description + (postEvent?`\n ${postEvent}`:'');
}
}
).join('\n ')
);
if(age == 60) debugger
} while(!trajectory.isEnd)
// debugger;
}
debug();

7
vite.config.js Normal file
View File

@@ -0,0 +1,7 @@
/** @type {import('vite').UserConfig} */
export default {
base: './',
build: {
outDir: 'template/public',
},
}

Some files were not shown because too many files have changed in this diff Show More