Skip to content

Commit 84948c2

Browse files
Hardy--LeeHardyNLee
authored andcommitted
feat: use json for game config
refactor: change enableAppreciation to enableExtra refactor: change game logo type to string feat: support textbox max line and line height
1 parent f191b10 commit 84948c2

7 files changed

Lines changed: 79 additions & 74 deletions

File tree

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"gameName": "新的 WebGAL 游戏",
3+
"gameKey": "7fe160a6",
4+
"gameLogo": "WebGalEnter.webp",
5+
"titleImage": "WebGAL_New_Enter_Image.webp",
6+
"titleBgm": "s_Title.mp3",
7+
"enableExtra": true
8+
}

packages/webgal/public/game/config.txt

Lines changed: 0 additions & 6 deletions
This file was deleted.

packages/webgal/src/Core/initializeScript.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ export const initializeScript = (): void => {
4646
// 获得 user Animation
4747
getUserAnimation();
4848
// 获取游戏信息
49-
infoFetcher('./game/config.txt');
49+
infoFetcher('./game/config.json');
5050
// 获取start场景
5151
const sceneUrl: string = assetSetter('start.txt', fileType.scene);
5252
// 场景写入到运行时

packages/webgal/src/Core/util/coreInitialFunction/infoFetcher.ts

Lines changed: 59 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -2,71 +2,74 @@ import { webgalStore } from '@/store/store';
22
import { setGlobalVar } from '@/store/userDataReducer';
33
import { setEnableAppreciationMode } from '@/store/GUIReducer';
44
import { Live2D, WebGAL } from '@/Core/WebGAL';
5-
import { WebgalParser } from '@/Core/parser/sceneParser';
65
import { getStorageAsync, setStorage } from '@/Core/controller/storage/storageController';
76
import { initKey } from '@/Core/controller/storage/fastSaveLoad';
87
import { getFastSaveFromStorage, getSavesFromStorage } from '@/Core/controller/storage/savesController';
98
import { logger } from '@/Core/util/logger';
109
import axios from 'axios';
1110

11+
interface IWebgalConfig {
12+
gameName?: string; // 游戏名称
13+
gameKey?: string; // 游戏Key
14+
gameLogo?: string; // 游戏Logo
15+
titleImage?: string; // 标题图片
16+
titleBgm?: string; // 标题背景音乐
17+
description?: string; // 游戏描述
18+
defaultLanguage?: string; // 默认语言
19+
packageName?: string; // 包名
20+
steamAppId?: string; // Steam 应用 ID
21+
enableExtra?: boolean; // 启用鉴赏功能
22+
enablePanic?: boolean; // 启用紧急回避
23+
enableLegacyExpressionBlendMode?: boolean; // 启用旧版 Live2D 表情混合模式
24+
textboxMaxLine?: number; // 文字框最大行数
25+
textboxLineHeight?: number; // 文字框行高
26+
}
27+
1228
/**
1329
* 获取游戏信息
1430
* @param url 游戏信息路径
1531
*/
16-
export const infoFetcher = (url: string) => {
32+
export const infoFetcher = async (url: string) => {
1733
const dispatch = webgalStore.dispatch;
18-
axios.get(url).then(async (r) => {
19-
let gameConfigRaw: string = r.data;
20-
let gameConfig = WebgalParser.parseConfig(gameConfigRaw);
21-
logger.info('获取到游戏信息', gameConfig);
22-
// 先把 key 找到并设置了
23-
const keyItem = gameConfig.find((e) => e.command === 'Game_key');
24-
WebGAL.gameKey = (keyItem?.args?.[0] as string) ?? '';
25-
initKey();
26-
await getStorageAsync();
27-
getFastSaveFromStorage();
28-
getSavesFromStorage(0, 0);
29-
// 按照游戏的配置开始设置对应的状态
30-
gameConfig.forEach((e) => {
31-
const { command, args } = e;
32-
if (args.length > 0) {
33-
if (args.length > 1) {
34-
dispatch(
35-
setGlobalVar({
36-
key: command,
37-
value: args.join('|'),
38-
}),
39-
);
40-
} else {
41-
let res: any = args[0].trim();
42-
if (/^(true|false)$/g.test(args[0])) {
43-
res = res === 'true';
44-
} else if (/^[0-9]+\.?[0-9]+$/g.test(args[0])) {
45-
res = Number(res);
46-
}
47-
48-
dispatch(
49-
setGlobalVar({
50-
key: command,
51-
value: res,
52-
}),
53-
);
54-
55-
if (command === 'Enable_Appreciation') {
56-
dispatch(setEnableAppreciationMode(res));
57-
}
58-
if (command === 'Legacy_Expression_Blend_Mode') {
59-
Live2D.legacyExpressionBlendMode = res === true;
60-
}
61-
if (command === 'Steam_AppID') {
62-
const appId = String(res);
63-
WebGAL.steam.initialize(appId);
64-
}
65-
}
66-
}
67-
});
68-
// @ts-expect-error renderPromiseResolve is a global variable
69-
window.renderPromiseResolve();
70-
setStorage();
71-
});
34+
const resp = await axios.get(url);
35+
const gameConfig: IWebgalConfig = resp.data;
36+
logger.info('获取到游戏信息', gameConfig);
37+
// 先把 key 找到并设置了
38+
WebGAL.gameKey = gameConfig.gameKey ?? '';
39+
initKey();
40+
await getStorageAsync();
41+
getFastSaveFromStorage();
42+
getSavesFromStorage(0, 0);
43+
// 将游戏配置写入为全局变量
44+
for (const [key, value] of Object.entries(gameConfig)) {
45+
if (value === undefined) continue;
46+
if (typeof value === 'boolean' || typeof value === 'number' || typeof value === 'string') {
47+
dispatch(
48+
setGlobalVar({
49+
key: key,
50+
value: value,
51+
}),
52+
);
53+
} else {
54+
dispatch(
55+
setGlobalVar({
56+
key: key,
57+
value: String(value),
58+
}),
59+
);
60+
}
61+
}
62+
// 配置游戏
63+
if (gameConfig.enableExtra !== undefined) {
64+
dispatch(setEnableAppreciationMode(gameConfig.enableExtra));
65+
}
66+
if (gameConfig.enableLegacyExpressionBlendMode !== undefined) {
67+
Live2D.legacyExpressionBlendMode = gameConfig.enableLegacyExpressionBlendMode;
68+
}
69+
if (gameConfig.steamAppId !== undefined) {
70+
WebGAL.steam.initialize(gameConfig.steamAppId);
71+
}
72+
// @ts-expect-error renderPromiseResolve is a global variable
73+
window.renderPromiseResolve();
74+
setStorage();
7275
};

packages/webgal/src/Stage/TextBox/IMSSTextbox.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ export default function IMSSTextbox(props: ITextboxProps) {
189189

190190
const userDataState = useSelector((state: RootState) => state.userData);
191191
const lineHeightValue = textSizeState === textSize.medium ? 2.2 : 2;
192-
const textLineHeight = userDataState.globalGameVar.LineHeight;
192+
const textLineHeight = userDataState.globalGameVar.textboxLineHeight;
193193
const finalTextLineHeight = textLineHeight ? Number(textLineHeight) : lineHeightValue;
194194
const lineHeightCssStr = `line-height: ${finalTextLineHeight}em`;
195195
const lhCss = css(lineHeightCssStr);

packages/webgal/src/Stage/TextBox/TextBox.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,14 +33,14 @@ export const TextBox = () => {
3333
size = getTextSize(stageState.showTextSize) + '%';
3434
textSizeState = stageState.showTextSize;
3535
}
36-
const MaxTextLine = Number(userDataState.globalGameVar.Max_line); // congfig定义字体行数
37-
const lineLimit = Number.isNaN(MaxTextLine)
36+
const maxTextLine = Number(userDataState.globalGameVar.textboxMaxLine); // congfig定义字体行数
37+
const lineLimit = Number.isNaN(maxTextLine)
3838
? match(textSizeState)
3939
.with(textSize.small, () => 3)
4040
.with(textSize.medium, () => 2)
4141
.with(textSize.large, () => 2)
4242
.default(() => 2)
43-
: MaxTextLine;
43+
: maxTextLine;
4444
// 拆字
4545
const textArray = compileSentence(stageState.showText, lineLimit);
4646
const isHasName = stageState.showName !== '';

packages/webgal/src/hooks/useConfigData.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import { useEffect } from 'react';
99
import { useSelector } from 'react-redux';
1010

1111
const useConfigData = () => {
12-
const _map = ['Title_img', 'Game_Logo', 'Title_bgm', 'Game_name', 'Game_key'];
12+
const _map = ['titleImage', 'gameLogo', 'titleBgm', 'gameName', 'gameKey'];
1313
const configData = useSelector((state: RootState) => state.userData.globalGameVar);
1414
return useEffect(() => {
1515
// configData发生变化
@@ -19,33 +19,33 @@ const useConfigData = () => {
1919
}
2020
const val = configData[i] as string;
2121
switch (i) {
22-
case 'Title_img': {
22+
case 'titleImage': {
2323
const titleUrl = assetSetter(val, fileType.background);
2424
webgalStore.dispatch(setGuiAsset({ asset: 'titleBg', value: titleUrl }));
2525
setEbg(titleUrl);
2626
break;
2727
}
2828

29-
case 'Game_Logo': {
29+
case 'gameLogo': {
3030
const logos = val.split('|');
3131
const logoUrlList = logos.map((val) => assetSetter(val, fileType.background));
3232
webgalStore.dispatch(setLogoImage(logoUrlList));
3333
break;
3434
}
3535

36-
case 'Title_bgm': {
36+
case 'titleBgm': {
3737
const bgmUrl = assetSetter(val, fileType.bgm);
3838
webgalStore.dispatch(setGuiAsset({ asset: 'titleBgm', value: bgmUrl }));
3939
break;
4040
}
4141

42-
case 'Game_name': {
42+
case 'gameName': {
4343
WebGAL.gameName = val;
4444
document.title = val;
4545
break;
4646
}
4747

48-
case 'Game_key': {
48+
case 'gameKey': {
4949
WebGAL.gameKey = val;
5050
getStorage();
5151
getFastSaveFromStorage();
@@ -55,6 +55,6 @@ const useConfigData = () => {
5555
}
5656
}
5757
return () => {};
58-
}, [configData.Game_Logo, configData.Game_key, configData.Game_name, configData.Title_bgm, configData.Title_img]);
58+
}, [configData.gameLogo, configData.gameKey, configData.gameName, configData.titleBgm, configData.titleImage]);
5959
};
6060
export default useConfigData;

0 commit comments

Comments
 (0)