Skip to content

Commit a4a8c8a

Browse files
Merge pull request #506 from OpenWebGAL/dev
4.5.2
2 parents 055fb81 + 14c04ec commit a4a8c8a

File tree

24 files changed

+298
-170
lines changed

24 files changed

+298
-170
lines changed

packages/parser/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "webgal-parser",
3-
"version": "4.4.15",
3+
"version": "4.5.2",
44
"description": "WebGAL script parser",
55
"scripts": {
66
"test": "vitest",

packages/parser/src/scriptParser/scriptParser.ts

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,9 @@ export const scriptParser = (
3535

3636
// 正式开始解析
3737

38-
// 去分号,前面已做,这里不再需要
39-
let newSentenceRaw = sentenceRaw.split(';')[0];
38+
// 去分号
39+
let newSentenceRaw = sentenceRaw.split(/(?<!\\);/)[0];
40+
newSentenceRaw = newSentenceRaw.replaceAll('\\;',';');
4041
if (newSentenceRaw === '') {
4142
// 注释提前返回
4243
return {
@@ -56,7 +57,11 @@ export const scriptParser = (
5657
// 没有command,说明这是一条连续对话或单条语句
5758
if (getCommandResult === null) {
5859
commandRaw = newSentenceRaw;
59-
parsedCommand = commandParser(commandRaw, ADD_NEXT_ARG_LIST, SCRIPT_CONFIG_MAP);
60+
parsedCommand = commandParser(
61+
commandRaw,
62+
ADD_NEXT_ARG_LIST,
63+
SCRIPT_CONFIG_MAP,
64+
);
6065
command = parsedCommand.type;
6166
for (const e of parsedCommand.additionalArgs) {
6267
// 由于是连续对话,所以我们去除 speaker 参数。
@@ -72,7 +77,11 @@ export const scriptParser = (
7277
getCommandResult.index + 1,
7378
newSentenceRaw.length,
7479
);
75-
parsedCommand = commandParser(commandRaw, ADD_NEXT_ARG_LIST, SCRIPT_CONFIG_MAP);
80+
parsedCommand = commandParser(
81+
commandRaw,
82+
ADD_NEXT_ARG_LIST,
83+
SCRIPT_CONFIG_MAP,
84+
);
7685
command = parsedCommand.type;
7786
for (const e of parsedCommand.additionalArgs) {
7887
args.push(e);
@@ -91,12 +100,12 @@ export const scriptParser = (
91100
args.push(e);
92101
}
93102
}
94-
content = contentParser(newSentenceRaw, command, assetSetter); // 将语句内容里的文件名转为相对或绝对路径
103+
content = contentParser(newSentenceRaw.trim(), command, assetSetter); // 将语句内容里的文件名转为相对或绝对路径
95104
sentenceAssets = assetsScanner(command, content, args); // 扫描语句携带资源
96105
subScene = subSceneScanner(command, content); // 扫描语句携带子场景
97106
return {
98107
command: command, // 语句类型
99-
commandRaw: commandRaw, // 命令原始内容,方便调试
108+
commandRaw: commandRaw.trim(), // 命令原始内容,方便调试
100109
content: content, // 语句内容
101110
args: args, // 参数列表
102111
sentenceAssets: sentenceAssets, // 语句携带的资源列表
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,11 @@
11
setVar:a=1;
22
WebGAL:a=1? -when=a==1;
3+
4+
;正常解析
5+
WebGAL:test;
6+
7+
; : 异常测试
8+
WebGAL : test;
9+
10+
分号后应该被截断;看不到我!
11+
转义分号后应该不截断\;能看到我!

packages/webgal/package.json

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "webgal",
33
"private": true,
4-
"version": "4.5.1",
4+
"version": "4.5.2",
55
"scripts": {
66
"dev": "vite --host --port 3000",
77
"build": "cross-env NODE_ENV=production tsc && vite build --base=./",
@@ -31,8 +31,7 @@
3131
"react-redux": "^8.0.1",
3232
"sass": "^1.49.9",
3333
"uuid": "^9.0.0",
34-
"vite-plugin-package-version": "^1.0.2",
35-
"webgal-parser": "latest"
34+
"vite-plugin-package-version": "^1.0.2"
3635
},
3736
"devDependencies": {
3837
"@types/lodash": "^4.14.180",

packages/webgal/public/game/template/Stage/TextBox/textbox.scss

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@
1919
transition: left 0.33s;
2020
}
2121

22+
.TextBox_main_miniavatarOff {
23+
left: 25px;
24+
}
25+
2226
.TextBox_Background {
2327
z-index: 2;
2428
background: linear-gradient(rgba(245, 247, 250, 1) 0%, rgba(189, 198, 222, 1) 100%);
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
{
22
"name":"Default Template",
3-
"webgal-version":"4.5.1"
3+
"webgal-version":"4.5.2"
44
}

packages/webgal/src/Core/controller/gamePlay/nextSentence.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ export const nextSentence = () => {
6363
}
6464

6565
// 不处于 allSettled 状态,清除所有普通演出,强制进入settled。
66-
logger.warn('提前结束被触发,现在清除普通演出');
66+
logger.debug('提前结束被触发,现在清除普通演出');
6767
let isGoNext = false;
6868
for (let i = 0; i < WebGAL.gameplay.performController.performList.length; i++) {
6969
const e = WebGAL.gameplay.performController.performList[i];
Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
import { compile } from 'angular-expressions';
22

33
export function strIf(s: string) {
4-
const res = compile(s);
5-
return res();
4+
try {
5+
const res = compile(s);
6+
return res();
7+
} catch {
8+
return false;
9+
}
610
}

packages/webgal/src/Core/controller/stage/pixi/PixiController.ts

Lines changed: 84 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -284,36 +284,11 @@ export default class PixiStage {
284284
// Load mouth texture (reuse if already loaded)
285285
this.loadAsset(mouthTextureUrls[mouthState], () => {
286286
const texture = this.assetLoader.resources[mouthTextureUrls[mouthState]].texture;
287-
if (!texture) {
287+
const sprite = currentFigure?.children?.[0] as PIXI.Sprite;
288+
if (!texture || !sprite) {
288289
return;
289290
}
290-
const originalWidth = texture.width;
291-
const originalHeight = texture.height;
292-
const scaleX = this.stageWidth / originalWidth;
293-
const scaleY = this.stageHeight / originalHeight;
294-
const targetScale = Math.min(scaleX, scaleY);
295-
const figureSprite = new PIXI.Sprite(texture);
296-
figureSprite.scale.x = targetScale;
297-
figureSprite.scale.y = targetScale;
298-
figureSprite.anchor.set(0.5);
299-
figureSprite.position.y = this.stageHeight / 2;
300-
const targetWidth = originalWidth * targetScale;
301-
const targetHeight = originalHeight * targetScale;
302-
currentFigure.setBaseY(this.stageHeight / 2);
303-
if (targetHeight < this.stageHeight) {
304-
currentFigure.setBaseY(this.stageHeight / 2 + this.stageHeight - targetHeight / 2);
305-
}
306-
if (presetPosition === 'center') {
307-
currentFigure.setBaseX(this.stageWidth / 2);
308-
}
309-
if (presetPosition === 'left') {
310-
currentFigure.setBaseX(targetWidth / 2);
311-
}
312-
if (presetPosition === 'right') {
313-
currentFigure.setBaseX(this.stageWidth - targetWidth / 2);
314-
}
315-
currentFigure.pivot.set(0, this.stageHeight / 2);
316-
currentFigure.addChild(figureSprite);
291+
sprite.texture = texture;
317292
});
318293
}
319294

@@ -337,38 +312,11 @@ export default class PixiStage {
337312
// Load eye texture (reuse if already loaded)
338313
this.loadAsset(blinkTextureUrls[blinkState], () => {
339314
const texture = this.assetLoader.resources[blinkTextureUrls[blinkState]].texture;
340-
341-
if (!texture) {
315+
const sprite = currentFigure?.children?.[0] as PIXI.Sprite;
316+
if (!texture || !sprite) {
342317
return;
343318
}
344-
345-
const originalWidth = texture.width;
346-
const originalHeight = texture.height;
347-
const scaleX = this.stageWidth / originalWidth;
348-
const scaleY = this.stageHeight / originalHeight;
349-
const targetScale = Math.min(scaleX, scaleY);
350-
const figureSprite = new PIXI.Sprite(texture);
351-
figureSprite.scale.x = targetScale;
352-
figureSprite.scale.y = targetScale;
353-
figureSprite.anchor.set(0.5);
354-
figureSprite.position.y = this.stageHeight / 2;
355-
const targetWidth = originalWidth * targetScale;
356-
const targetHeight = originalHeight * targetScale;
357-
currentFigure.setBaseY(this.stageHeight / 2);
358-
if (targetHeight < this.stageHeight) {
359-
currentFigure.setBaseY(this.stageHeight / 2 + this.stageHeight - targetHeight / 2);
360-
}
361-
if (presetPosition === 'center') {
362-
currentFigure.setBaseX(this.stageWidth / 2);
363-
}
364-
if (presetPosition === 'left') {
365-
currentFigure.setBaseX(targetWidth / 2);
366-
}
367-
if (presetPosition === 'right') {
368-
currentFigure.setBaseX(this.stageWidth - targetWidth / 2);
369-
}
370-
currentFigure.pivot.set(0, this.stageHeight / 2);
371-
currentFigure.addChild(figureSprite);
319+
sprite.texture = texture;
372320
});
373321
}
374322

@@ -447,6 +395,84 @@ export default class PixiStage {
447395
}
448396
}
449397

398+
public addSpineBg(key: string, url: string) {
399+
const spineId = `spine-${url}`;
400+
const loader = this.assetLoader;
401+
// 准备用于存放这个背景的 Container
402+
const thisBgContainer = new WebGALPixiContainer();
403+
404+
// 是否有相同 key 的背景
405+
const setBgIndex = this.backgroundObjects.findIndex((e) => e.key === key);
406+
const isBgSet = setBgIndex >= 0;
407+
408+
// 已经有一个这个 key 的背景存在了
409+
if (isBgSet) {
410+
// 挤占
411+
this.removeStageObjectByKey(key);
412+
}
413+
414+
// 挂载
415+
this.backgroundContainer.addChild(thisBgContainer);
416+
const bgUuid = uuid();
417+
this.backgroundObjects.push({
418+
uuid: bgUuid,
419+
key: key,
420+
pixiContainer: thisBgContainer,
421+
sourceUrl: url,
422+
sourceType: 'live2d',
423+
sourceExt: this.getExtName(url),
424+
});
425+
426+
// 完成图片加载后执行的函数
427+
const setup = () => {
428+
const spineResource: any = this.assetLoader.resources?.[spineId];
429+
// TODO:找一个更好的解法,现在的解法是无论是否复用原来的资源,都设置一个延时以让动画工作正常!
430+
setTimeout(() => {
431+
if (spineResource && this.getStageObjByUuid(bgUuid)) {
432+
const bgSpine = new Spine(spineResource.spineData);
433+
const transY = spineResource?.spineData?.y ?? 0;
434+
/**
435+
* 重设大小
436+
*/
437+
const originalWidth = bgSpine.width; // TODO: 视图大小可能小于画布大小,应提供参数指定视图大小
438+
const originalHeight = bgSpine.height; // TODO: 视图大小可能小于画布大小,应提供参数指定视图大小
439+
const scaleX = this.stageWidth / originalWidth;
440+
const scaleY = this.stageHeight / originalHeight;
441+
logger.debug('bgSpine state', bgSpine.state);
442+
// TODO: 也许应该使用 setAnimation 播放初始动画
443+
if (bgSpine.spineData.animations.length > 0) {
444+
// 播放首个动画
445+
bgSpine.state.setAnimation(0, bgSpine.spineData.animations[0].name, true);
446+
}
447+
const targetScale = Math.max(scaleX, scaleY);
448+
const bgSprite = new PIXI.Sprite();
449+
bgSprite.addChild(bgSpine);
450+
bgSprite.scale.x = targetScale;
451+
bgSprite.scale.y = targetScale;
452+
bgSprite.anchor.set(0.5);
453+
bgSprite.position.y = this.stageHeight / 2;
454+
thisBgContainer.setBaseX(this.stageWidth / 2);
455+
thisBgContainer.setBaseY(this.stageHeight / 2);
456+
thisBgContainer.pivot.set(0, this.stageHeight / 2);
457+
458+
// 挂载
459+
thisBgContainer.addChild(bgSprite);
460+
}
461+
}, 0);
462+
};
463+
464+
/**
465+
* 加载器部分
466+
*/
467+
this.cacheGC();
468+
if (!loader.resources?.[url]) {
469+
this.loadAsset(url, setup, spineId);
470+
} else {
471+
// 复用
472+
setup();
473+
}
474+
}
475+
450476
/**
451477
* 添加立绘
452478
* @param key 立绘的标识,一般和立绘位置有关
@@ -566,7 +592,6 @@ export default class PixiStage {
566592

567593
// 完成图片加载后执行的函数
568594
const setup = () => {
569-
console.log(this.assetLoader.resources);
570595
const spineResource: any = this.assetLoader.resources?.[spineId];
571596
// TODO:找一个更好的解法,现在的解法是无论是否复用原来的资源,都设置一个延时以让动画工作正常!
572597
setTimeout(() => {
@@ -576,14 +601,12 @@ export default class PixiStage {
576601
/**
577602
* 重设大小
578603
*/
579-
console.log(figureSpine);
580604
const originalWidth = figureSpine.width;
581605
const originalHeight = figureSpine.height;
582606
const scaleX = this.stageWidth / originalWidth;
583607
const scaleY = this.stageHeight / originalHeight;
584608
// 我也不知道为什么啊啊啊啊
585609
figureSpine.y = -(scaleY * transY) / 2;
586-
console.log(figureSpine.state);
587610
figureSpine.state.setAnimation(0, '07', true);
588611
const targetScale = Math.min(scaleX, scaleY);
589612
const figureSprite = new PIXI.Sprite();

packages/webgal/src/Core/controller/stage/playBgm.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ let emptyBgmTimeout: ReturnType<typeof setTimeout>;
2626
* @param volume 背景音乐 音量调整(0 - 100)
2727
*/
2828
export function playBgm(url: string, enter = 0, volume = 100): void {
29-
logger.info('playing bgm' + url);
29+
logger.debug('playing bgm' + url);
3030
if (url === '') {
3131
emptyBgmTimeout = setTimeout(() => {
3232
// 淡入淡出效果结束后,将 bgm 置空

0 commit comments

Comments
 (0)