Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

4.5.8 #572

Merged
merged 21 commits into from
Oct 28, 2024
Merged

4.5.8 #572

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
f76b6d1
feat:使得文本拓展语法对角色名称有效
None-44 Aug 22, 2024
08bf353
fix: fig and bg live animation key
MakinoharaShoko Aug 22, 2024
64c6898
feat: add simulate vocal animation
MakinoharaShoko Aug 31, 2024
77e20d8
update simulate argo
MakinoharaShoko Aug 31, 2024
664168e
fix: simulation algo
MakinoharaShoko Aug 31, 2024
9b85b7c
fix:修复姓名框错误显示并改正角色名称默认样式
None-44 Sep 3, 2024
e38ab42
feat: can override bounds
MakinoharaShoko Sep 6, 2024
3fd1b19
fix: enhance value do not effect when at first of line
MakinoharaShoko Sep 8, 2024
33a841e
Merge pull request #533 from None-44/dev
MakinoharaShoko Sep 8, 2024
3e80091
fix: check stage obj exist when update effects
MakinoharaShoko Sep 19, 2024
5ca0555
Merge pull request #547 from OpenWebGAL/add-simulate-vocal-ani
MakinoharaShoko Oct 1, 2024
a5a9d0f
Merge pull request #548 from OpenWebGAL/fix-bounds-l2d
MakinoharaShoko Oct 1, 2024
9318e70
Merge pull request #537 from OpenWebGAL/fix-stage-obj-exit-animation
MakinoharaShoko Oct 15, 2024
04c7aee
Merge branch 'main' into dev
MakinoharaShoko Oct 15, 2024
6eea82f
feat: set figure z-index use argument `zIndex`
MakinoharaShoko Oct 15, 2024
d5f5d0a
优化富文本显示排版
RinPV2 Oct 17, 2024
5181a3d
fix: remove line height limit of single segment of line
MakinoharaShoko Oct 22, 2024
fe03456
fix: basic style of .TextBox_textElement should be same.
MakinoharaShoko Oct 22, 2024
51cb753
Merge pull request #568 from RinPV2/dev
MakinoharaShoko Oct 22, 2024
29a685a
fix: temporary disable source map
MakinoharaShoko Oct 25, 2024
71a7e85
update version
MakinoharaShoko Oct 28, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions packages/webgal/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "webgal",
"private": true,
"version": "4.5.7",
"version": "4.5.8",
"scripts": {
"dev": "vite --host --port 3000",
"build": "cross-env NODE_ENV=production tsc && vite build --base=./",
Expand All @@ -21,7 +21,7 @@
"mitt": "^3.0.0",
"modern-css-reset": "^1.4.0",
"pixi-filters": "^4.2.0",
"pixi-live2d-display-webgal": "^0.5.2",
"pixi-live2d-display-webgal": "^0.5.8",
"pixi-spine": "^3.1.2",
"pixi.js": "^6.3.0",
"popmotion": "^11.0.5",
Expand Down
2 changes: 1 addition & 1 deletion packages/webgal/public/game/template/template.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"name":"Default Template",
"webgal-version":"4.5.7"
"webgal-version":"4.5.8"
}
10 changes: 6 additions & 4 deletions packages/webgal/src/Core/Modules/animationFunctions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,12 @@ export function getAnimateDuration(animationName: string) {
return 0;
}

// eslint-disable-next-line max-params
export function getEnterExitAnimation(
target: string,
type: 'enter' | 'exit',
isBg = false,
realTarget?: string, // 用于立绘和背景移除时,以当前时间打上特殊标记
): {
duration: number;
animation: {
Expand All @@ -57,11 +59,11 @@ export function getEnterExitAnimation(
setStartState: () => void;
tickerFunc: (delta: number) => void;
setEndState: () => void;
} | null = generateUniversalSoftInAnimationObj(target, duration);
} | null = generateUniversalSoftInAnimationObj(realTarget ?? target, duration);
const animarionName = WebGAL.animationManager.nextEnterAnimationName.get(target);
if (animarionName) {
logger.debug('取代默认进入动画', target);
animation = getAnimationObject(animarionName, target, getAnimateDuration(animarionName));
animation = getAnimationObject(animarionName, realTarget ?? target, getAnimateDuration(animarionName));
duration = getAnimateDuration(animarionName);
// 用后重置
WebGAL.animationManager.nextEnterAnimationName.delete(target);
Expand All @@ -77,11 +79,11 @@ export function getEnterExitAnimation(
setStartState: () => void;
tickerFunc: (delta: number) => void;
setEndState: () => void;
} | null = generateUniversalSoftOffAnimationObj(target, duration);
} | null = generateUniversalSoftOffAnimationObj(realTarget ?? target, duration);
const animarionName = WebGAL.animationManager.nextExitAnimationName.get(target);
if (animarionName) {
logger.debug('取代默认退出动画', target);
animation = getAnimationObject(animarionName, target, getAnimateDuration(animarionName));
animation = getAnimationObject(animarionName, realTarget ?? target, getAnimateDuration(animarionName));
duration = getAnimateDuration(animarionName);
// 用后重置
WebGAL.animationManager.nextExitAnimationName.delete(target);
Expand Down
6 changes: 6 additions & 0 deletions packages/webgal/src/Core/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export const STAGE_KEYS = {
BGMAIN: 'bg-main',
FIG_C: 'fig-center',
FIG_L: 'fig-left',
FIG_R: 'fig-right',
};
46 changes: 43 additions & 3 deletions packages/webgal/src/Core/controller/stage/pixi/PixiController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { v4 as uuid } from 'uuid';
import { webgalStore } from '@/store/store';
import { setStage, stageActions } from '@/store/stageReducer';
import cloneDeep from 'lodash/cloneDeep';
import { IEffect, IFigureAssociatedAnimation } from '@/store/stageInterface';
import { IEffect, IFigureAssociatedAnimation, IFigureMetadata } from '@/store/stageInterface';
import { logger } from '@/Core/util/logger';
import { isIOS } from '@/Core/initializeScript';
import { WebGALPixiContainer } from '@/Core/controller/stage/pixi/WebGALPixiContainer';
Expand All @@ -12,7 +12,7 @@ import 'pixi-spine'; // Do this once at the very start of your code. This regist
import { Spine } from 'pixi-spine';
import { SCREEN_CONSTANTS } from '@/Core/util/constants';
// import { figureCash } from '@/Core/gameScripts/vocal/conentsCash'; // 如果要使用 Live2D,取消这里的注释
// import { Live2DModel, SoundManager } from 'pixi-live2d-display'; // 如果要使用 Live2D,取消这里的注释
// import { Live2DModel, SoundManager } from 'pixi-live2d-display-webgal'; // 如果要使用 Live2D,取消这里的注释

export interface IAnimationObject {
setStartState: Function;
Expand Down Expand Up @@ -125,6 +125,7 @@ export default class PixiStage {
this.effectsContainer = new PIXI.Container();
this.effectsContainer.zIndex = 3;
this.figureContainer = new PIXI.Container();
this.figureContainer.sortableChildren = true; // 允许立绘启用 z-index
this.figureContainer.zIndex = 2;
this.backgroundContainer = new PIXI.Container();
this.backgroundContainer.zIndex = 0;
Expand Down Expand Up @@ -493,6 +494,12 @@ export default class PixiStage {
this.removeStageObjectByKey(key);
}

const metadata = this.getFigureMetadataByKey(key);
if (metadata) {
if (metadata.zIndex) {
thisFigureContainer.zIndex = metadata.zIndex;
}
}
// 挂载
this.figureContainer.addChild(thisFigureContainer);
const figureUuid = uuid();
Expand Down Expand Up @@ -578,6 +585,12 @@ export default class PixiStage {
this.removeStageObjectByKey(key);
}

const metadata = this.getFigureMetadataByKey(key);
if (metadata) {
if (metadata.zIndex) {
thisFigureContainer.zIndex = metadata.zIndex;
}
}
// 挂载
this.figureContainer.addChild(thisFigureContainer);
const figureUuid = uuid();
Expand Down Expand Up @@ -673,6 +686,12 @@ export default class PixiStage {
// this.removeStageObjectByKey(key);
// }
//
// const metadata = this.getFigureMetadataByKey(key);
// if (metadata) {
// if (metadata.zIndex) {
// thisFigureContainer.zIndex = metadata.zIndex;
// }
// }
// // 挂载
// this.figureContainer.addChild(thisFigureContainer);
// this.figureObjects.push({
Expand All @@ -689,7 +708,23 @@ export default class PixiStage {
// const setup = () => {
// if (thisFigureContainer) {
// (async function () {
// const models = await Promise.all([Live2DModel.from(jsonPath, { autoInteract: false })]);
// let overrideBounds: [number, number, number, number] = [0, 0, 0, 0];
// const mot = webgalStore.getState().stage.live2dMotion.find((e) => e.target === key);
// if (mot?.overrideBounds) {
// overrideBounds = mot.overrideBounds;
// }
// console.log(overrideBounds);
// const models = await Promise.all([
// Live2DModel.from(jsonPath, {
// autoInteract: false,
// overWriteBounds: {
// x0: overrideBounds[0],
// y0: overrideBounds[1],
// x1: overrideBounds[2],
// y1: overrideBounds[3],
// },
// }),
// ]);
//
// models.forEach((model) => {
// const scaleX = stageWidth / model.width;
Expand Down Expand Up @@ -962,6 +997,11 @@ export default class PixiStage {
private getExtName(url: string) {
return url.split('.').pop() ?? 'png';
}

private getFigureMetadataByKey(key: string): IFigureMetadata | undefined {
console.log(key, webgalStore.getState().stage.figureMetaData);
return webgalStore.getState().stage.figureMetaData[key];
}
}

function updateCurrentBacklogEffects(newEffects: IEffect[]) {
Expand Down
49 changes: 42 additions & 7 deletions packages/webgal/src/Core/gameScripts/changeFigure.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ export function changeFigure(sentence: ISentence): IPerform {
let animationFlag: any = '';
let mouthAnimationKey: any = 'mouthAnimation';
let eyesAnimationKey: any = 'blinkAnimation';
let overrideBounds = '';
let zIndex = -1;
const dispatch = webgalStore.dispatch;

for (const e of sentence.args) {
Expand Down Expand Up @@ -63,6 +65,9 @@ export function changeFigure(sentence: ISentence): IPerform {
case 'motion':
motion = e.value.toString();
break;
case 'bounds':
overrideBounds = String(e.value);
break;
case 'expression':
expression = e.value.toString();
break;
Expand Down Expand Up @@ -92,6 +97,9 @@ export function changeFigure(sentence: ISentence): IPerform {
case 'none':
content = '';
break;
case 'zIndex':
zIndex = Number(e.value);
break;
default:
break;
}
Expand Down Expand Up @@ -153,6 +161,9 @@ export function changeFigure(sentence: ISentence): IPerform {
const deleteKey2 = `${key}`;
webgalStore.dispatch(stageActions.removeEffectByTargetId(deleteKey));
webgalStore.dispatch(stageActions.removeEffectByTargetId(deleteKey2));
// 重设 figureMetaData,这里是 zIndex,实际上任何键都可以,因为整体是移除那条记录
dispatch(stageActions.setFigureMetaData([deleteKey, 'zIndex', 0, true]));
dispatch(stageActions.setFigureMetaData([deleteKey2, 'zIndex', 0, true]));
}
const setAnimationNames = (key: string, sentence: ISentence) => {
// 处理 transform 和 默认 transform
Expand Down Expand Up @@ -208,21 +219,27 @@ export function changeFigure(sentence: ISentence): IPerform {
}
};
if (isFreeFigure) {
const currentFreeFigures = webgalStore.getState().stage.freeFigure;

/**
* 重设
* 下面的代码是设置自由立绘的
*/
const freeFigureItem: IFreeFigure = { key, name: content, basePosition: pos };
setAnimationNames(key, sentence);
if (motion) {
dispatch(stageActions.setLive2dMotion({ target: key, motion }));
if (motion || overrideBounds) {
dispatch(
stageActions.setLive2dMotion({ target: key, motion, overrideBounds: getOverrideBoundsArr(overrideBounds) }),
);
}
if (expression) {
dispatch(stageActions.setLive2dExpression({ target: key, expression }));
}
if (zIndex > 0) {
dispatch(stageActions.setFigureMetaData([key, 'zIndex', zIndex, false]));
}
dispatch(stageActions.setFreeFigureByKey(freeFigureItem));
} else {
/**
* 下面的代码是设置与位置关联的立绘的
*/
const positionMap = {
center: 'fig-center',
left: 'fig-left',
Expand All @@ -236,12 +253,17 @@ export function changeFigure(sentence: ISentence): IPerform {

key = positionMap[pos];
setAnimationNames(key, sentence);
if (motion) {
dispatch(stageActions.setLive2dMotion({ target: key, motion }));
if (motion || overrideBounds) {
dispatch(
stageActions.setLive2dMotion({ target: key, motion, overrideBounds: getOverrideBoundsArr(overrideBounds) }),
);
}
if (expression) {
dispatch(stageActions.setLive2dExpression({ target: key, expression }));
}
if (zIndex > 0) {
dispatch(stageActions.setFigureMetaData([key, 'zIndex', zIndex, false]));
}
dispatch(setStage({ key: dispatchMap[pos], value: content }));
}

Expand All @@ -255,3 +277,16 @@ export function changeFigure(sentence: ISentence): IPerform {
stopTimeout: undefined, // 暂时不用,后面会交给自动清除
};
}

function getOverrideBoundsArr(raw: string): undefined | [number, number, number, number] {
const parseOverrideBoundsResult = raw.split(',').map((e) => Number(e));
let isPass = true;
parseOverrideBoundsResult.forEach((e) => {
if (isNaN(e)) {
isPass = false;
}
});
isPass = isPass && parseOverrideBoundsResult.length === 4;
if (isPass) return parseOverrideBoundsResult as [number, number, number, number];
else return undefined;
}
61 changes: 60 additions & 1 deletion packages/webgal/src/Core/gameScripts/say.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import { getSentenceArgByKey } from '@/Core/util/getSentenceArg';
import { textSize, voiceOption } from '@/store/userDataInterface';
import { WebGAL } from '@/Core/WebGAL';
import { compileSentence } from '@/Stage/TextBox/TextBox';
import { performMouthAnimation } from '@/Core/gameScripts/vocal/vocalAnimation';
import { match } from '@/Core/util/match';

/**
* 进行普通对话的显示
Expand Down Expand Up @@ -84,9 +86,62 @@ export const say = (sentence: ISentence): IPerform => {
}
dispatch(setStage({ key: 'showName', value: showName }));

// 模拟说话
let performSimulateVocalTimeout: ReturnType<typeof setTimeout> | null = null;
let performSimulateVocalDelay = 0;
let pos = '';
let key = '';
for (const e of sentence.args) {
if (e.value === true) {
match(e.key)
.with('left', () => {
pos = 'left';
})
.with('right', () => {
pos = 'right';
})
.endsWith('center', () => {
pos = 'center';
});
}
if (e.key === 'figureId') {
key = `${e.value.toString()}`;
}
}
let audioLevel = 80;
const performSimulateVocal = (end = false) => {
let nextAudioLevel = audioLevel + (Math.random() * 60 - 30); // 在 -30 到 +30 之间波动
// 确保波动幅度不小于 5
if (Math.abs(nextAudioLevel - audioLevel) < 5) {
nextAudioLevel = audioLevel + Math.sign(nextAudioLevel - audioLevel) * 5;
}
// 确保结果在 25 到 100 之间
audioLevel = Math.max(15, Math.min(nextAudioLevel, 100));
const currentStageState = webgalStore.getState().stage;
const figureAssociatedAnimation = currentStageState.figureAssociatedAnimation;
const animationItem = figureAssociatedAnimation.find((tid) => tid.targetId === key);
const targetKey = key ? key : `fig-${pos}`;
if (end) {
audioLevel = 0;
}
performMouthAnimation({
audioLevel,
OPEN_THRESHOLD: 50,
HALF_OPEN_THRESHOLD: 25,
currentMouthValue: 0,
lerpSpeed: 1,
key: targetKey,
animationItem,
pos,
});
if (!end) performSimulateVocalTimeout = setTimeout(performSimulateVocal, 50);
};
// 播放一段语音
if (vocal) {
playVocal(sentence);
} else if (key || pos) {
performSimulateVocalDelay = len * 250;
performSimulateVocal();
}

const performInitName: string = getRandomPerformName();
Expand All @@ -98,10 +153,14 @@ export const say = (sentence: ISentence): IPerform => {

return {
performName: performInitName,
duration: sentenceDelay + endDelay,
duration: sentenceDelay + endDelay + performSimulateVocalDelay,
isHoldOn: false,
stopFunction: () => {
WebGAL.events.textSettle.emit();
if (performSimulateVocalTimeout) {
performSimulateVocal(true);
clearTimeout(performSimulateVocalTimeout);
}
},
blockingNext: () => false,
blockingAuto: () => true,
Expand Down
12 changes: 7 additions & 5 deletions packages/webgal/src/Stage/MainStage/useSetBg.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,15 @@ export function useSetBg(stageState: IStageState) {
function removeBg(bgObject: IStageObject) {
WebGAL.gameplay.pixiStage?.removeAnimationWithSetEffects('bg-main-softin');
const oldBgKey = bgObject.key;
bgObject.key = 'bg-main-off';
bgObject.key = 'bg-main-off' + String(new Date().getTime());
const bgKey = bgObject.key;
const bgAniKey = bgObject.key + '-softoff';
WebGAL.gameplay.pixiStage?.removeStageObjectByKey(oldBgKey);
const { duration, animation } = getEnterExitAnimation('bg-main-off', 'exit', true);
WebGAL.gameplay.pixiStage!.registerAnimation(animation, 'bg-main-softoff', 'bg-main-off');
const { duration, animation } = getEnterExitAnimation('bg-main-off', 'exit', true, bgKey);
WebGAL.gameplay.pixiStage!.registerAnimation(animation, bgAniKey, bgKey);
setTimeout(() => {
WebGAL.gameplay.pixiStage?.removeAnimation('bg-main-softoff');
WebGAL.gameplay.pixiStage?.removeStageObjectByKey('bg-main-off');
WebGAL.gameplay.pixiStage?.removeAnimation(bgAniKey);
WebGAL.gameplay.pixiStage?.removeStageObjectByKey(bgKey);
}, duration);
}

Expand Down
Loading
Loading