Skip to content

Commit

Permalink
Merge pull request #572 from OpenWebGAL/dev
Browse files Browse the repository at this point in the history
4.5.8
  • Loading branch information
MakinoharaShoko authored Oct 28, 2024
2 parents a20255e + 70e631d commit f6586c4
Show file tree
Hide file tree
Showing 23 changed files with 384 additions and 158 deletions.
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

0 comments on commit f6586c4

Please sign in to comment.