Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
49 changes: 2 additions & 47 deletions packages/webgal/src/Core/Modules/stage/stageInterface.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { ISentence } from '@/Core/controller/scene/sceneInterface';
import { BlinkParam, FocusParam } from '@/Core/live2DCore';
import type { Transform } from '@/types/editorPreviewProtocol';

/**
* 游戏内变量
Expand All @@ -24,49 +25,7 @@ export interface IChooseItem {
isSubScene: boolean; // 是否是子场景调用
}

export interface ITransform {
alpha?: number;
scale?: {
x?: number;
y?: number;
};
// pivot: {
// x: number;
// y: number;
// };
position?: {
x?: number;
y?: number;
};
rotation?: number;
blur?: number;
brightness?: number;
contrast?: number;
saturation?: number;
gamma?: number;
colorRed?: number;
colorGreen?: number;
colorBlue?: number;
bevel?: number;
bevelThickness?: number;
bevelRotation?: number;
bevelSoftness?: number;
bevelRed?: number;
bevelGreen?: number;
bevelBlue?: number;
bloom?: number;
bloomBrightness?: number;
bloomBlur?: number;
bloomThreshold?: number;
oldFilm?: number;
dotFilm?: number;
reflectionFilm?: number;
glitchFilm?: number;
rgbFilm?: number;
godrayFilm?: number;
shockwaveFilter?: number;
radiusAlphaFilter?: number;
}
export type ITransform = Transform;

/**
* 基本效果接口
Expand Down Expand Up @@ -104,10 +63,6 @@ export const baseTransform: ITransform = {
x: 1,
y: 1,
},
// pivot: {
// x: 0.5,
// y: 0.5,
// },
position: {
x: 0,
y: 0,
Expand Down
10 changes: 7 additions & 3 deletions packages/webgal/src/Core/controller/gamePlay/nextSentence.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { scriptExecutor } from './scriptExecutor';
import { scriptExecutor, type ScriptExecutionOptions } from './scriptExecutor';
import { logger } from '../../util/logger';
import { webgalStore } from '@/store/store';

Expand Down Expand Up @@ -45,7 +45,11 @@ export const preForward = (continueAfterSettling = false) => {
* forward 只推进 calculationStageState,并把命令返回的 perform 收集到 pending 列表;
* 它不会提交视图状态,也不会启动 perform。调用方必须在合适时机调用 commitForward。
*/
export const forward = () => {
export interface ForwardOptions {
scriptExecution?: ScriptExecutionOptions;
}

export const forward = (options: ForwardOptions = {}) => {
if (WebGAL.sceneManager.lockSceneWrite) {
logger.warn('forward 被场景切换阻塞!');
return false;
Expand All @@ -60,7 +64,7 @@ export const forward = () => {
WebGAL.gameplay.performController.clearNonHoldPerformsFromStageState();
WebGAL.gameplay.performController.beginCollectingPerforms();
try {
scriptExecutor();
scriptExecutor(0, options.scriptExecution);
} finally {
WebGAL.gameplay.performController.endCollectingPerforms();
}
Expand Down
24 changes: 19 additions & 5 deletions packages/webgal/src/Core/controller/gamePlay/scriptExecutor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,15 @@ import { WEBGAL_NONE } from '@/Core/constants';

const MAX_FORWARD_SCRIPT_EXECUTION = 1000;

export interface ScriptExecutionContext {
sceneName: string;
sentenceId: number;
}

export interface ScriptExecutionOptions {
beforeSentenceExecute?: (context: ScriptExecutionContext) => void;
}

export const whenChecker = (whenValue: string | undefined): boolean => {
if (whenValue === undefined) {
return true;
Expand All @@ -40,7 +49,7 @@ export const whenChecker = (whenValue: string | undefined): boolean => {
* 语句执行器
* 执行语句,同步场景状态,并根据情况立即执行下一句或者加入backlog
*/
export const scriptExecutor = (depth = 0) => {
export const scriptExecutor = (depth = 0, options: ScriptExecutionOptions = {}) => {
if (depth > MAX_FORWARD_SCRIPT_EXECUTION) {
logger.error('forward 中执行的语句数量超过限制,可能存在 jumpLabel 或 -next 死循环');
return;
Expand All @@ -60,8 +69,13 @@ export const scriptExecutor = (depth = 0) => {
}
return;
}
const sentenceId = WebGAL.sceneManager.sceneData.currentSentenceId;
options.beforeSentenceExecute?.({
sceneName: WebGAL.sceneManager.sceneData.currentScene.sceneName,
sentenceId,
});
const currentScript: ISentence = cloneDeep(
WebGAL.sceneManager.sceneData.currentScene.sentenceList[WebGAL.sceneManager.sceneData.currentSentenceId],
WebGAL.sceneManager.sceneData.currentScene.sentenceList[sentenceId],
);

const interpolationOneItem = (content: string): string => {
Expand Down Expand Up @@ -106,7 +120,7 @@ export const scriptExecutor = (depth = 0) => {
if (!runThis) {
logger.warn('不满足条件,跳过本句!');
WebGAL.sceneManager.sceneData.currentSentenceId++;
scriptExecutor(depth + 1);
scriptExecutor(depth + 1, options);
return;
}

Expand All @@ -117,7 +131,7 @@ export const scriptExecutor = (depth = 0) => {
logger.warn(`未找到标签 ${currentScript.content},跳过 jumpLabel`);
WebGAL.sceneManager.sceneData.currentSentenceId++;
}
scriptExecutor(depth + 1);
scriptExecutor(depth + 1, options);
return;
}

Expand Down Expand Up @@ -150,7 +164,7 @@ export const scriptExecutor = (depth = 0) => {
if (isNext && !hasPendingBlockingStateCalculationPerform && !WebGAL.sceneManager.lockSceneWrite) {
WebGAL.sceneManager.sceneData.currentSentenceId++;
saveBacklogIfNeeded();
scriptExecutor(depth + 1);
scriptExecutor(depth + 1, options);
return;
}

Expand Down
69 changes: 51 additions & 18 deletions packages/webgal/src/Core/controller/stage/pixi/PixiController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@ import { SCREEN_CONSTANTS } from '@/Core/util/constants';
import { logger } from '@/Core/util/logger';
import { v4 as uuid } from 'uuid';
import { cloneDeep, isEqual } from 'lodash';
import omitBy from 'lodash/omitBy';
import isUndefined from 'lodash/isUndefined';
import * as PIXI from 'pixi.js';
import { INSTALLED } from 'pixi.js';
import { GifResource } from './GifResource';
import { stageStateManager } from '@/Core/Modules/stage/stageStateManager';
import { queryStageObjectReferenceBox, type QueryTargetReferenceBoxResult } from './referenceBox';
import { assignPixiTransform } from './stageEffectTransform';

export interface IAnimationObject {
setStartState: Function;
Expand Down Expand Up @@ -69,21 +69,7 @@ INSTALLED.push(GifResource);

export default class PixiStage {
public static assignTransform<T extends ITransform>(target: T, source?: ITransform, convertAlpha = true) {
if (!source) return;
const targetScale = target.scale;
const targetPosition = target.position;
if (target.scale) Object.assign(targetScale!, omitBy(source.scale || {}, isUndefined));
if (target.position) Object.assign(targetPosition!, omitBy(source.position || {}, isUndefined));
Object.assign(target, omitBy(source, isUndefined));
target.scale = targetScale;
target.position = targetPosition;
if (convertAlpha) {
const sourceAlpha = source.alpha;
if (sourceAlpha !== undefined) {
target.alpha = 1;
(target as any).alphaFilterVal = sourceAlpha;
}
}
assignPixiTransform(target, source, convertAlpha);
}

/**
Expand Down Expand Up @@ -120,6 +106,7 @@ export default class PixiStage {
private isRenderPending = false;
// 更新 ticker 状态的防抖标记
private isTickerUpdatePending = false;
private referenceBoxWaiters = new Map<string, Set<() => void>>();

/**
* 暂时没用上,以后可能用
Expand Down Expand Up @@ -467,6 +454,7 @@ export default class PixiStage {

// 挂载
thisBgContainer.addChild(bgSprite);
this.notifyTargetReferenceBoxChanged(key);
this.requestRender();
}
}, 0);
Expand Down Expand Up @@ -551,6 +539,7 @@ export default class PixiStage {
thisBgContainer.setBaseY(this.stageHeight / 2);
thisBgContainer.pivot.set(0, this.stageHeight / 2);
thisBgContainer.addChild(bgSprite);
this.notifyTargetReferenceBoxChanged(key);
});
}
}, 0);
Expand Down Expand Up @@ -609,7 +598,6 @@ export default class PixiStage {
sourceType: sourceExt === 'gif' ? 'gif' : 'img',
sourceExt,
});

// 完成图片加载后执行的函数
const setup = () => {
// TODO:找一个更好的解法,现在的解法是无论是否复用原来的资源,都设置一个延时以让动画工作正常!
Expand Down Expand Up @@ -646,6 +634,7 @@ export default class PixiStage {
}
thisFigureContainer.pivot.set(0, this.stageHeight / 2);
thisFigureContainer.addChild(figureSprite);
this.notifyTargetReferenceBoxChanged(key);
this.requestRender();
}
}, 0);
Expand Down Expand Up @@ -807,6 +796,7 @@ export default class PixiStage {
Live2D.SoundManager.volume = 0; // @ts-ignore

thisFigureContainer.addChild(model);
instance.notifyTargetReferenceBoxChanged(key);
});
})();
}
Expand Down Expand Up @@ -1030,6 +1020,36 @@ export default class PixiStage {
return [...this.figureObjects, ...this.backgroundObjects, this.mainStageObject].find((e) => e.key === key);
}

public queryTargetReferenceBox(target: string): QueryTargetReferenceBoxResult {
return queryStageObjectReferenceBox(target, this.getStageObjByKey(target), {
width: this.stageWidth,
height: this.stageHeight,
});
}

public waitForTargetReferenceBox(target: string, timeoutMs: number): Promise<void> {
return new Promise((resolve) => {
const existingWaiters = this.referenceBoxWaiters.get(target);
const waiters = existingWaiters ?? new Set<() => void>();
if (!existingWaiters) {
this.referenceBoxWaiters.set(target, waiters);
}

let timeoutId = 0;
const resolveAndCleanup = () => {
window.clearTimeout(timeoutId);
waiters.delete(resolveAndCleanup);
if (waiters.size === 0) {
this.referenceBoxWaiters.delete(target);
}
resolve();
};

timeoutId = window.setTimeout(resolveAndCleanup, timeoutMs);
waiters.add(resolveAndCleanup);
});
}

public getStageObjByUuid(objUuid: string) {
return [...this.figureObjects, ...this.backgroundObjects, this.mainStageObject].find((e) => e.uuid === objUuid);
}
Expand Down Expand Up @@ -1057,6 +1077,7 @@ export default class PixiStage {
}
bgSprite.pixiContainer = null;
this.figureObjects.splice(indexFig, 1);
this.notifyTargetReferenceBoxChanged(key);
}
if (indexBg >= 0) {
const bgSprite = this.backgroundObjects[indexBg];
Expand All @@ -1070,6 +1091,7 @@ export default class PixiStage {
}
bgSprite.pixiContainer = null;
this.backgroundObjects.splice(indexBg, 1);
this.notifyTargetReferenceBoxChanged(key);
}
// /**
// * 删掉相关 Effects,因为已经移除了
Expand Down Expand Up @@ -1142,6 +1164,17 @@ export default class PixiStage {
}
}

public notifyTargetReferenceBoxChanged(target: string): void {
const waiters = this.referenceBoxWaiters.get(target);
if (!waiters) {
return;
}

for (const resolve of [...waiters]) {
resolve();
}
}

private callLoader() {
if (!this.assetLoader.loading) {
const front = this.loadQueue.shift();
Expand Down
Loading
Loading