Skip to content

Commit

Permalink
Merge pull request #394 from MakinoharaShoko/dev
Browse files Browse the repository at this point in the history
4.4.6
  • Loading branch information
MakinoharaShoko committed Nov 5, 2023
2 parents 374c538 + f020e0d commit a5f039e
Show file tree
Hide file tree
Showing 45 changed files with 1,175 additions and 309 deletions.
4 changes: 2 additions & 2 deletions packages/webgal/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -199,8 +199,8 @@
</script>
<script type="module" src="/src/main.tsx"></script>
<!--<script type="module" src="/src/Core/util/resize.ts"></script>-->
<!--<script src="/src/assets/lib/l2d.js"></script>-->
<!--<script src="/src/assets/lib/live2dcubismcore.min.js"></script>-->
<!--<script src="lib/live2d.min.js"></script>-->
<!--<script src="lib/live2dcubismcore.min.js"></script>-->
<script>
let enterPromise = new Promise(res => window.enterPromise = res);
let renderPromise = new Promise(res => window.renderPromise = res);
Expand Down
2 changes: 1 addition & 1 deletion packages/webgal/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "webgal",
"private": true,
"version": "4.4.5",
"version": "4.4.6",
"scripts": {
"dev": "vite --host --port 3000",
"build": "cross-env NODE_ENV=production tsc && vite build --base=./",
Expand Down
1 change: 1 addition & 0 deletions packages/webgal/public/game/config.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ Game_key:0f86dstRf;
Title_img:WebGAL_New_Enter_Image.png;
Title_bgm:s_Title.mp3;
Game_Logo:WebGalEnter.png;
Textbox_theme:imss;
11 changes: 11 additions & 0 deletions packages/webgal/public/game/scene/demo_var.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
setVar:bg=bg.png;
changeBg:{bg} -next;
setVar:speaker=WebGAL;
{speaker}:Background now is {bg}.;
{speaker}:\{bg\} is not use interpolation.;
setVar:a=3;
setVar:bg=bg1.png -when=a>2;
changeBg:{bg} -next;
setVar:func=variable interpolation;
{speaker}:Bg changed! Welcome to {speaker} {func}!;
end;
34 changes: 17 additions & 17 deletions packages/webgal/public/game/scene/demo_zh_cn.txt
Original file line number Diff line number Diff line change
@@ -1,48 +1,48 @@
bgm:s_Title.mp3 -volume=80 -enter=3000;
unlockBgm:s_Title.mp3 -name=雲を追いかけて;
intro:你好|欢迎来到 WebGAL 的世界;
intro:你好|欢迎来到 {egine} 的世界;
changeBg:bg.png -next;
unlockCg:bg.png -name=良夜; // 解锁CG并赋予名称
changeFigure:stand.png -left -enter=enter-from-left -next;
:你好|欢迎来到 WebGAL 的世界;
:你好|欢迎来到 {egine} 的世界;
miniAvatar:miniavatar.png;
WebGAL:欢迎使用 WebGAL!这是一款全新的网页端视觉小说引擎。 -v1.wav;
{heroine}:欢迎使用 {egine}!这是一款全新的网页端视觉小说引擎。 -v1.wav;
changeFigure:stand2.png -right -next;
WebGAL 是使用 Web 技术开发的引擎,因此在网页端有良好的表现。 -v2.wav;
由于这个特性,如果你将 WebGAL 部署到服务器或网页托管平台上,玩家只需要一串链接就可以开始游玩! -v3.wav;
{egine} 是使用 Web 技术开发的引擎,因此在网页端有良好的表现。 -v2.wav;
由于这个特性,如果你将 {egine} 部署到服务器或网页托管平台上,玩家只需要一串链接就可以开始游玩! -v3.wav;
setAnimation:move-front-and-back -target=fig-left -next;
听起来是不是非常吸引人? -v4.wav;
changeFigure:none -right -next;
setTransform:{"position": {"x": 500,"y": 0}} -target=fig-left -next;
WebGAL 引擎也具有动画系统和特效系统,使用 WebGAL 开发的游戏可以拥有很好的表现效果。 -v5.wav;
{egine} 引擎也具有动画系统和特效系统,使用 {egine} 开发的游戏可以拥有很好的表现效果。 -v5.wav;
pixiInit;
pixiPerform:snow;
比如,这个下起小雪的特效。 -v6.wav;
除此以外,分支选择的功能也必不可少。 -v7.wav;
你可以通过以下两个分支了解 WebGAL 的更多故事。 -v8.wav;
你可以通过以下两个分支了解 {egine} 的更多故事。 -v8.wav;
pixiInit;
choose:WebGAL 发展历程:choose1|WebGAL 冷知识:choose2;
choose:{egine} 发展历程:choose1|{egine} 冷知识:choose2;

;分支1
label:choose1;
WebGAL 的开发初衷是能够让更多人可以更方便地制作属于自己的视觉小说。 -v9.wav;
在一开始,WebGAL 只具备很少的功能,仅仅能支持立绘和背景的显示、语音播放和分支选择。 -v10.wav;
{egine} 的开发初衷是能够让更多人可以更方便地制作属于自己的视觉小说。 -v9.wav;
在一开始,{egine} 只具备很少的功能,仅仅能支持立绘和背景的显示、语音播放和分支选择。 -v10.wav;
setAnimation:move-front-and-back -target=fig-left -next;
在经历一年的发展后,现在已经是支持了很多优秀的表现效果的引擎了! -v11.wav;
除此以外,WebGAL 编辑器的加入也使得制作和导出一个游戏更加方便快捷。 -v12.wav;
除此以外,{egine} 编辑器的加入也使得制作和导出一个游戏更加方便快捷。 -v12.wav;
jumpLabel:end;

;分支2
label:choose2;
这个演示游戏使用的素材是 AI 生成的。 -v13.wav;
WebGAL 项目只用了一年不到就在 GitHub 获得了 1000 星标! -v14.wav;
WebGAL 的开发历程,是一个在开发中学习开发的过程。因此她经历了3次重构,并且每次几乎都是推倒重来式的。 -v15.wav;
WebGAL 的脚本语言是为了简化制作难度而全新设计的! -v16.wav;
{egine} 项目只用了一年不到就在 GitHub 获得了 1000 星标! -v14.wav;
{egine} 的开发历程,是一个在开发中学习开发的过程。因此她经历了3次重构,并且每次几乎都是推倒重来式的。 -v15.wav;
{egine} 的脚本语言是为了简化制作难度而全新设计的! -v16.wav;
;
;l2d
;label:l2d;
;changeFigure:hiyori/hiyori_pro_t11.model3.json -left -motion=Idle -next;
;WebGAL 项目现在也开始尝试实验性支持 live2D!今后可能会成为一个正式功能!
;{egine} 项目现在也开始尝试实验性支持 live2D!今后可能会成为一个正式功能!
;
;结束分支
label:end;
Expand All @@ -54,6 +54,6 @@ label:end;
setTempAnimation:[{"position": {"x": 500,"y": 0},"duration": 0},{"position": {"x": 400,"y": 0},"duration": 250},{"position": {"x": 600,"y": 0},"duration": 500},{"position": {"x": 500,"y": 0},"duration": 250}] -target=fig-left -next;
当然,这不算什么,因为大多数成熟的引擎都有这些功能。但是在 Web 端,这却是很少见的。 -v20.wav;
我们为可能初次开发游戏的开发者提供了美观的通用 UI 和丰富的预设功能与动画。所以你可以没有顾虑地快速开始制作游戏。 -v21.wav;
WebGAL 项目组期待你的作品能够在 WebGAL 上呈现!只需要一个链接就可以让万千用户立刻开始享受你的作品。 -v22.wav;
感谢你关注 WebGAL 项目! -v23.wav;
{egine} 项目组期待你的作品能够在 {egine} 上呈现!只需要一个链接就可以让万千用户立刻开始享受你的作品。 -v22.wav;
感谢你关注 {egine} 项目! -v23.wav;
end;
4 changes: 3 additions & 1 deletion packages/webgal/public/game/scene/start.txt
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
choose:简体中文:demo_zh_cn.txt|日本語:demo_ja.txt|English:demo_en.txt|Lip Sync Animation Test:demo_animation.txt;
setVar:heroine=WebGAL;
setVar:egine=WebGAL;
choose:简体中文:demo_zh_cn.txt|日本語:demo_ja.txt|English:demo_en.txt|Lip Sync Animation Test:demo_animation.txt | Variable interpolation test:demo_var.txt;
22 changes: 20 additions & 2 deletions packages/webgal/src/Components/Stage/MainStage/useSetFigure.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,25 @@ import { getEnterExitAnimation } from '@/Core/Modules/animationFunctions';
import { WebGAL } from '@/Core/WebGAL';

export function useSetFigure(stageState: IStageState) {
const { figNameLeft, figName, figNameRight, freeFigure, live2dMotion } = stageState;
const { figNameLeft, figName, figNameRight, freeFigure, live2dMotion, live2dExpression } = stageState;

/**
* 同步 motion
*/
useEffect(() => {
for (const motion of live2dMotion) {
WebGAL.gameplay.pixiStage?.changeModelMotionByKey(motion.target, motion.motion);
}
}, [live2dMotion]);

/**
* 同步 expression
*/
useEffect(() => {
for (const expression of live2dExpression) {
WebGAL.gameplay.pixiStage?.changeModelExpressionByKey(expression.target, expression.expression);
}
}, [live2dExpression]);

/**
* 设置立绘
Expand Down Expand Up @@ -222,5 +240,5 @@ function removeFig(figObj: IStageObject, enterTikerKey: string, effects: IEffect
* @param args
*/
function addLive2dFigure(...args: any[]) {
// return WebGAL.gameplay.pixiStage?.addLive2dFigure.apply(args);
// return WebGAL.gameplay.pixiStage?.addLive2dFigure(...args);
}
4 changes: 4 additions & 0 deletions packages/webgal/src/Components/Stage/Stage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { useHotkey } from '@/hooks/useHotkey';
import { MainStage } from '@/Components/Stage/MainStage/MainStage';
import IntroContainer from '@/Components/Stage/introContainer/IntroContainer';
import { isIOS } from '@/Core/initializeScript';
import { WebGAL } from '@/Core/WebGAL';
// import OldStage from '@/Components/Stage/OldStage/OldStage';

export const Stage: FC = () => {
Expand Down Expand Up @@ -42,6 +43,9 @@ export const Stage: FC = () => {
stopAll();
nextSentence();
}}
onDoubleClick={() => {
WebGAL.eventBus.emit('fullscreen-dbclick');
}}
id="FullScreenClick"
style={{ width: '100%', height: '100%', position: 'absolute', zIndex: '12', top: '0' }}
/>
Expand Down
128 changes: 39 additions & 89 deletions packages/webgal/src/Components/Stage/TextBox/TextBox.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,27 @@
import styles from './textbox.module.scss';
import { useEffect } from 'react';
import { FC, useEffect } from 'react';
import { useSelector } from 'react-redux';
import { RootState } from '@/store/store';
import { useFontFamily } from '@/hooks/useFontFamily';
import { useTextAnimationDuration, useTextDelay } from '@/hooks/useTextOptions';
import { getTextSize } from '@/Components/UI/getTextSize';
import StandardTextbox, { ITextboxProps } from '@/Components/Stage/TextBox/themes/standard/StandardTextbox';
import IMSSTextbox from '@/Components/Stage/TextBox/themes/imss/IMSSTextbox';
import { IWebGalTextBoxTheme } from '@/Components/themeInterface';
import { textSize } from '@/store/userDataInterface';

const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);

function getTextboxByTheme(theme: IWebGalTextBoxTheme): FC<ITextboxProps> {
switch (theme) {
case 'standard':
return StandardTextbox;
case 'imss':
return IMSSTextbox;
default:
return StandardTextbox;
}
}

export const TextBox = () => {
const stageState = useSelector((state: RootState) => state.stage);
const userDataState = useSelector((state: RootState) => state.userData);
Expand All @@ -17,103 +31,39 @@ export const TextBox = () => {
let size = getTextSize(userDataState.optionData.textSize) + '%';
const font = useFontFamily();
const isText = stageState.showText !== '' || stageState.showName !== '';
let textSizeState = userDataState.optionData.textSize;
if (isText && stageState.showTextSize !== -1) {
size = getTextSize(stageState.showTextSize) + '%';
textSizeState = stageState.showTextSize;
}
// 拆字
const textArray: Array<string> = splitChars(stageState.showText);
const textElementList = textArray.map((e, index) => {
if (e === '<br />') {
return <br key={`br${index}`} />;
}
let delay = index * textDelay;
let prevLength = stageState.currentConcatDialogPrev.length;
if (stageState.currentConcatDialogPrev !== '' && index >= prevLength) {
delay = delay - prevLength * textDelay;
}
if (index < prevLength) {
return (
<span
data-text={e}
id={`${delay}`}
className={styles.TextBox_textElement_Settled}
key={stageState.currentDialogKey + index}
style={{ animationDelay: `${delay}ms`, animationDuration: `${textDuration}ms` }}
>
<span className={styles.zhanwei}>
{e}
<span className={styles.outer}>{e}</span>
<span className={styles.inner}>{e}</span>
</span>
</span>
);
}
return (
<span
data-text={e}
id={`${delay}`}
className={styles.TextBox_textElement_start}
key={stageState.currentDialogKey + index}
style={{ animationDelay: `${delay}ms`, position: 'relative' }}
>
<span className={styles.zhanwei}>
{e}
<span className={styles.outer}>{e}</span>
<span className={styles.inner}>{e}</span>
</span>
</span>
);
});
const showName = stageState.showName;
const currentConcatDialogPrev = stageState.currentConcatDialogPrev;
const currentDialogKey = stageState.currentDialogKey;
const miniAvatar = stageState.miniAvatar;
const theme = useSelector((state: RootState) => state.GUI.theme);
const Textbox = getTextboxByTheme(theme.textbox);
return (
<>
{isText && (
<div
id="textBoxMain"
className={styles.TextBox_main}
style={{ fontFamily: font, left: stageState.miniAvatar === '' ? 25 : undefined }}
>
{/* <div className={styles.nameContainer}>{stageState.showName !== ''}</div> */}
<div id="miniAvatar" className={styles.miniAvatarContainer}>
{stageState.miniAvatar !== '' && (
<img className={styles.miniAvatarImg} alt="miniAvatar" src={stageState.miniAvatar} />
)}
</div>
{stageState.showName !== '' && (
<div key={stageState.showName} className={styles.TextBox_showName} style={{ fontSize: '200%' }}>
{stageState.showName.split('').map((e, i) => {
return (
<span key={e + i} style={{ position: 'relative' }}>
<span className={styles.zhanwei}>
{e}
<span className={styles.outerName}>{e}</span>
<span className={styles.innerName}>{e}</span>
</span>
</span>
);
})}
</div>
)}
<div
className={styles.text}
style={{
fontSize: size,
wordBreak: isSafari ? 'break-word' : undefined,
overflow: 'hidden',
paddingLeft: '0.1em',
}}
>
{textElementList}
</div>
</div>
)}
</>
<Textbox
textArray={textArray}
isText={isText}
textDelay={textDelay}
showName={showName}
currentConcatDialogPrev={currentConcatDialogPrev}
fontSize={size}
currentDialogKey={currentDialogKey}
isSafari={isSafari}
miniAvatar={miniAvatar}
textDuration={textDuration}
font={font}
textSizeState={textSizeState}
/>
);
};

function isCJK(character: string) {
if (character.match(/[\u4e00-\u9fa5]|[\u0800-\u4e00]|[\uac00-\ud7ff]/)) {
return true;
} else return false;
return !!character.match(/[\u4e00-\u9fa5]|[\u0800-\u4e00]|[\uac00-\ud7ff]/);
}

export function splitChars(sentence: string) {
Expand Down
Loading

0 comments on commit a5f039e

Please sign in to comment.