refactor: 渲染端结构

This commit is contained in:
unanmed 2026-04-19 22:52:32 +08:00
parent ebae685a4e
commit 51e9d758d8
38 changed files with 290 additions and 138 deletions

View File

@ -1,16 +1,8 @@
import { loading } from '@user/data-base'; import { createMaterial } from './material';
import { createMaterial, fallbackLoad } from './material';
import { materials } from './ins';
export function create() { export function create() {
createMaterial(); createMaterial();
loading.once('loaded', () => {
fallbackLoad(materials);
loading.emit('assetBuilt');
});
} }
export * from './load'; export * from './load';
export * from './material'; export * from './material';
export * from './ins';

View File

@ -1,47 +0,0 @@
import {
AudioType,
BGMPlayer,
MotaAudioContext,
OpusDecoder,
SoundPlayer,
VorbisDecoder
} from '@motajs/audio';
import { MotaAssetsLoader } from './load/loader';
import { AutotileProcessor, MaterialManager } from './material';
import { dataLoader, loadProgress } from '@user/data-base';
//#region 音频实例
/** 游戏全局音频上下文 */
export const audioContext = new MotaAudioContext();
/** 音效播放器 */
export const soundPlayer = new SoundPlayer(audioContext);
/** 音乐播放器 */
export const bgmPlayer = new BGMPlayer(audioContext);
audioContext.registerDecoder(AudioType.Opus, () => new OpusDecoder());
audioContext.registerDecoder(AudioType.Ogg, () => new VorbisDecoder());
//#endregion
//#region 素材实例
/** 素材管理器 */
export const materials = new MaterialManager();
/** 自动元件处理器 */
export const autotile = new AutotileProcessor(materials);
//#endregion
//#region 加载实例
/** 客户端加载实例 */
export const loader = new MotaAssetsLoader(
loadProgress,
dataLoader,
audioContext,
soundPlayer,
materials
);
//#endregion

View File

@ -1 +1,3 @@
export * from './data';
export * from './loader'; export * from './loader';
export * from './types';

View File

@ -6,7 +6,6 @@ export function createMaterial() {
export * from './autotile'; export * from './autotile';
export * from './builder'; export * from './builder';
export * from './fallback';
export * from './manager'; export * from './manager';
export * from './types'; export * from './types';
export * from './utils'; export * from './utils';

View File

@ -0,0 +1,151 @@
import { ICoreState } from '@user/data-state';
import { IClientCore } from './types';
import {
IMotaAudioContext,
ISoundPlayer,
IBGMPlayer,
MotaAudioContext,
SoundPlayer,
BGMPlayer
} from '@motajs/audio';
import { IRenderTreeRoot, MotaRenderer } from '@motajs/render';
import {
IMotaAssetsLoader,
IMaterialManager,
IAutotileProcessor,
MotaAssetsLoader,
MaterialManager,
AutotileProcessor
} from '@user/client-base';
import {
IMapRenderer,
IMapExtensionManager,
MapRenderer,
MapExtensionManager
} from './render/map';
import {
ExcitationDivider,
ExcitationVariator,
IExcitation,
IExcitationDivider,
RafExcitation
} from '@motajs/animate';
import {
DEBUG_DIVIDER,
DEBUG_VARIATOR,
DIVIDER_DEBUG_DIVIDER,
MAIN_HEIGHT,
MAIN_WIDTH,
VARIATOR_DEBUG_SPEED
} from './shared';
import { loading } from '@user/data-base';
import { fallbackLoad } from './fallback/load';
export class ClientCore implements IClientCore {
readonly loader: IMotaAssetsLoader;
readonly materials: IMaterialManager;
readonly autotile: IAutotileProcessor;
readonly rafExcitation: IExcitation<number>;
readonly excitationDivider: IExcitationDivider<number>;
readonly renderer: IRenderTreeRoot;
readonly mainMapRenderer: IMapRenderer;
readonly mainMapExtension: IMapExtensionManager;
readonly audioContext: IMotaAudioContext;
readonly soundPlayer: ISoundPlayer<SoundIds>;
readonly bgmPlayer: IBGMPlayer<BgmIds>;
constructor(public data: ICoreState) {
//#region 音频系统
this.audioContext = new MotaAudioContext();
this.soundPlayer = new SoundPlayer(this.audioContext);
this.bgmPlayer = new BGMPlayer(this.audioContext);
//#endregion
//#region 素材系统
this.materials = new MaterialManager();
this.autotile = new AutotileProcessor(this.materials);
//#endregion
this.loader = new MotaAssetsLoader(
data.loadProgress,
data.dataLoader,
this.audioContext,
this.soundPlayer,
this.materials
);
// 兼容层
loading.once('loaded', () => {
fallbackLoad(this.materials);
loading.emit('assetBuilt');
});
//#region 渲染系统
const rafExcitation = new RafExcitation();
const excitationDivider = new ExcitationDivider<number>();
if (DEBUG_VARIATOR) {
const variator = new ExcitationVariator();
variator.bindExcitation(rafExcitation);
variator.setSpeed(VARIATOR_DEBUG_SPEED);
excitationDivider.bindExcitation(variator);
} else {
excitationDivider.bindExcitation(rafExcitation);
}
if (DEBUG_DIVIDER) {
excitationDivider.setDivider(DIVIDER_DEBUG_DIVIDER);
}
this.rafExcitation = rafExcitation;
this.excitationDivider = excitationDivider;
this.renderer = new MotaRenderer({
canvas: '#render-main',
width: MAIN_WIDTH,
height: MAIN_HEIGHT,
// 使用分频器,用户可以在设置中调整,如果设备性能较差调高分频有助于提高性能表现
excitaion: excitationDivider
});
this.mainMapRenderer = new MapRenderer(this.materials, data.layer);
this.mainMapExtension = new MapExtensionManager(this.mainMapRenderer);
// 兼容层
loading.once('assetBuilt', () => {
this.createMainExtension();
});
//#endregion
}
/**
*
*/
private async createMainExtension() {
// 算是一种妥协吧,等之后加载系统重构之后应该会清晰很多
await this.materials.trackedAsset.then();
this.mainMapRenderer.useAsset(this.materials.trackedAsset);
const layer = this.data.layer.getLayerByAlias('event');
if (layer) {
this.mainMapExtension.addHero(this.data.hero.mover, layer);
this.mainMapExtension.addDoor(layer);
}
this.mainMapExtension.addText();
}
bindDataState(state: ICoreState): void {
this.data = state;
}
getDataState(): ICoreState {
return this.data;
}
}

View File

@ -0,0 +1,5 @@
import { state } from '@user/data-state';
import { ClientCore } from './client';
/** 客户端实例 */
export const client = new ClientCore(state);

View File

@ -1,13 +1,14 @@
import { Patch, PatchClass } from '@motajs/legacy-common'; import { Patch, PatchClass } from '@motajs/legacy-common';
import { audioContext, bgmPlayer, soundPlayer } from '@user/client-base';
import { mainSetting } from '@motajs/legacy-ui'; import { mainSetting } from '@motajs/legacy-ui';
import { sleep } from '@motajs/common'; import { sleep } from '@motajs/common';
import { isNil } from 'lodash-es'; import { isNil } from 'lodash-es';
import { client } from '../core';
// todo: 添加弃用警告 logger.warn(56) // todo: 添加弃用警告 logger.warn(56)
export function patchAudio() { export function patchAudio() {
const patch = new Patch(PatchClass.Control); const patch = new Patch(PatchClass.Control);
const { bgmPlayer, soundPlayer, audioContext } = client;
const play = (bgm: BgmIds, when?: number) => { const play = (bgm: BgmIds, when?: number) => {
bgmPlayer.play(bgm, when); bgmPlayer.play(bgm, when);
@ -28,8 +29,8 @@ export function patchAudio() {
patch.add('checkBgm', function () { patch.add('checkBgm', function () {
if (bgmPlayer.playing) return; if (bgmPlayer.playing) return;
if (mainSetting.getValue('audio.bgmEnabled')) { if (mainSetting.getValue('audio.bgmEnabled')) {
if (bgmPlayer.playingBgm) { if (bgmPlayer.playingBGM) {
bgmPlayer.play(bgmPlayer.playingBgm); bgmPlayer.play(bgmPlayer.playingBGM);
} else { } else {
play(main.startBgm, 0); play(main.startBgm, 0);
} }

View File

@ -1,9 +1,9 @@
import { ITexture } from '@motajs/render'; import { ITexture } from '@motajs/render';
import { import {
IBlockIdentifier, IBlockIdentifier,
IIndexedIdentifier, IMaterialManager,
IMaterialManager IIndexedIdentifier
} from './types'; } from '@user/client-base';
import { isNil } from 'lodash-es'; import { isNil } from 'lodash-es';
function extractClsBlocks<C extends Exclude<Cls, 'tileset'>>( function extractClsBlocks<C extends Exclude<Cls, 'tileset'>>(

View File

@ -13,3 +13,8 @@ export function create() {
export * from './action'; export * from './action';
export * from './fallback'; export * from './fallback';
export * from './render'; export * from './render';
export * from './client';
export * from './core';
export * from './shared';
export * from './types';

View File

@ -1,5 +1,5 @@
import { gameKey } from '@motajs/system'; import { gameKey } from '@motajs/system';
import { POP_BOX_WIDTH, CENTER_LOC, FULL_LOC } from './shared'; import { POP_BOX_WIDTH, CENTER_LOC, FULL_LOC } from '../shared';
import { import {
saveSave, saveSave,
mainUIController, mainUIController,

View File

@ -1,23 +0,0 @@
import { state } from '@user/data-state';
import { materials } from '@user/client-base';
import { MapRenderer, MapExtensionManager } from './map';
/** 主地图渲染器,用于渲染游戏画面 */
export const mainMapRenderer = new MapRenderer(materials, state.layer);
/** 主地图渲染器拓展 */
export const mainMapExtension = new MapExtensionManager(mainMapRenderer);
/** 副地图渲染器,用于渲染缩略图、浏览地图等 */
// export const expandMapRenderer = new MapRenderer(materials, state.layer);
export async function createMainExtension() {
// 算是一种妥协吧,等之后加载系统重构之后应该会清晰很多
await materials.trackedAsset.then();
mainMapRenderer.useAsset(materials.trackedAsset);
const layer = state.layer.getLayerByAlias('event');
if (layer) {
mainMapExtension.addHero(state.hero.mover, layer);
mainMapExtension.addDoor(layer);
}
mainMapExtension.addText();
}

View File

@ -8,7 +8,7 @@ import {
HALF_STATUS_WIDTH, HALF_STATUS_WIDTH,
STATUS_BAR_HEIGHT, STATUS_BAR_HEIGHT,
STATUS_BAR_WIDTH STATUS_BAR_WIDTH
} from '../shared'; } from '../../shared';
const SCROLL_HEIGHT = STATUS_BAR_HEIGHT - 280; const SCROLL_HEIGHT = STATUS_BAR_HEIGHT - 280;
const HALF_HEIGHT = SCROLL_HEIGHT / 2; const HALF_HEIGHT = SCROLL_HEIGHT / 2;

View File

@ -1,7 +1,7 @@
import { Font } from '@motajs/render'; import { Font } from '@motajs/render';
import { defineComponent } from 'vue'; import { defineComponent } from 'vue';
import { DEFAULT_FONT, MAIN_HEIGHT, MAIN_WIDTH } from './shared'; import { DEFAULT_FONT, MAIN_HEIGHT, MAIN_WIDTH } from '../shared';
import { hook, loading } from '@user/data-base'; import { hook } from '@user/data-base';
import { createElements } from './elements'; import { createElements } from './elements';
import { mainRenderer } from './renderer'; import { mainRenderer } from './renderer';
import { createUI } from './ui'; import { createUI } from './ui';
@ -9,7 +9,6 @@ import { createAction } from './action';
import { sceneController } from './scene'; import { sceneController } from './scene';
import { GameTitleUI } from './ui/title'; import { GameTitleUI } from './ui/title';
import { createWeather } from './weather'; import { createWeather } from './weather';
import { createMainExtension } from './commonIns';
import { createApp } from './renderer'; import { createApp } from './renderer';
import { LoadSceneUI } from './ui/load'; import { LoadSceneUI } from './ui/load';
@ -35,10 +34,6 @@ export function createRender() {
createAction(); createAction();
createWeather(); createWeather();
loading.once('assetBuilt', () => {
createMainExtension();
});
hook.on('restart', () => { hook.on('restart', () => {
sceneController.closeAll(); sceneController.closeAll();
sceneController.open(GameTitleUI, {}); sceneController.open(GameTitleUI, {});
@ -47,7 +42,6 @@ export function createRender() {
Font.setDefaults(DEFAULT_FONT); Font.setDefaults(DEFAULT_FONT);
} }
export * from './commonIns';
export * from './components'; export * from './components';
export * from './elements'; export * from './elements';
export * from './fx'; export * from './fx';
@ -56,5 +50,5 @@ export * from './utils';
export * from './weather'; export * from './weather';
export * from './renderer'; export * from './renderer';
export * from './scene'; export * from './scene';
export * from './shared'; export * from '../shared';
export * from './use'; export * from './use';

View File

@ -2,7 +2,7 @@ import { MotaOffscreenCanvas2D, RenderItem } from '@motajs/render';
import { ILayerState } from '@user/data-state'; import { ILayerState } from '@user/data-state';
import { IMapRenderer } from './types'; import { IMapRenderer } from './types';
import { ElementNamespace, ComponentInternalInstance } from 'vue'; import { ElementNamespace, ComponentInternalInstance } from 'vue';
import { CELL_HEIGHT, CELL_WIDTH, MAP_HEIGHT, MAP_WIDTH } from '../shared'; import { CELL_HEIGHT, CELL_WIDTH, MAP_HEIGHT, MAP_WIDTH } from '../../shared';
import { IMapExtensionManager } from './extension'; import { IMapExtensionManager } from './extension';
export class MapRenderItem extends RenderItem { export class MapRenderItem extends RenderItem {

View File

@ -6,7 +6,7 @@ import {
import { IMapDoorRenderer } from './types'; import { IMapDoorRenderer } from './types';
import { IMapRenderer } from '../types'; import { IMapRenderer } from '../types';
import { sleep } from 'mutate-animate'; import { sleep } from 'mutate-animate';
import { DOOR_ANIMATE_INTERVAL } from '../../shared'; import { DOOR_ANIMATE_INTERVAL } from '../../../shared';
export class MapDoorRenderer implements IMapDoorRenderer { export class MapDoorRenderer implements IMapDoorRenderer {
/** 钩子控制器 */ /** 钩子控制器 */

View File

@ -45,7 +45,7 @@ import {
CELL_WIDTH, CELL_WIDTH,
DYNAMIC_RESERVE, DYNAMIC_RESERVE,
MOVING_TOLERANCE MOVING_TOLERANCE
} from '../shared'; } from '../../shared';
import { MapViewport } from './viewport'; import { MapViewport } from './viewport';
import { INSTANCED_COUNT } from './constant'; import { INSTANCED_COUNT } from './constant';
import { StaticBlockStatus } from './status'; import { StaticBlockStatus } from './status';

View File

@ -17,7 +17,11 @@ import {
MapTileSizeTestMode MapTileSizeTestMode
} from './types'; } from './types';
import { logger, PrivateBooleanDirtyTracker } from '@motajs/common'; import { logger, PrivateBooleanDirtyTracker } from '@motajs/common';
import { DYNAMIC_RESERVE, MAP_BLOCK_HEIGHT, MAP_BLOCK_WIDTH } from '../shared'; import {
DYNAMIC_RESERVE,
MAP_BLOCK_HEIGHT,
MAP_BLOCK_WIDTH
} from '../../shared';
import { BlockSplitter } from './block'; import { BlockSplitter } from './block';
import { clamp, isNil } from 'lodash-es'; import { clamp, isNil } from 'lodash-es';
import { BlockCls, IMaterialFramedData } from '@user/client-base'; import { BlockCls, IMaterialFramedData } from '@user/client-base';

View File

@ -6,7 +6,7 @@ import {
VARIATOR_DEBUG_SPEED, VARIATOR_DEBUG_SPEED,
DEBUG_DIVIDER, DEBUG_DIVIDER,
DIVIDER_DEBUG_DIVIDER DIVIDER_DEBUG_DIVIDER
} from './shared'; } from '../shared';
import { createRendererFor, RendererUsing } from '@motajs/render-vue'; import { createRendererFor, RendererUsing } from '@motajs/render-vue';
import { import {
ExcitationDivider, ExcitationDivider,

View File

@ -6,7 +6,7 @@ import {
UIController UIController
} from '@motajs/system'; } from '@motajs/system';
import { defineComponent } from 'vue'; import { defineComponent } from 'vue';
import { MAIN_HEIGHT, MAIN_WIDTH } from '../shared'; import { MAIN_HEIGHT, MAIN_WIDTH } from '../../shared';
export const mainUIController = new UIController('main-ui'); export const mainUIController = new UIController('main-ui');

View File

@ -17,15 +17,15 @@ import {
LOAD_TASK_RADIUS, LOAD_TASK_RADIUS,
LOAD_UNLOADED_COLOR, LOAD_UNLOADED_COLOR,
MAIN_WIDTH MAIN_WIDTH
} from '../shared'; } from '../../shared';
import { ElementLocator, Font, MotaOffscreenCanvas2D } from '@motajs/render'; import { ElementLocator, Font, MotaOffscreenCanvas2D } from '@motajs/render';
import { transitioned } from '../use'; import { transitioned } from '../use';
import { cosh, CurveMode, linear } from '@motajs/animate'; import { cosh, CurveMode, linear } from '@motajs/animate';
import { loader } from '@user/client-base';
import { clamp } from 'lodash-es'; import { clamp } from 'lodash-es';
import { sleep } from '@motajs/common'; import { sleep } from '@motajs/common';
import { loading } from '@user/data-base'; import { loading } from '@user/data-base';
import { GameTitleUI } from './title'; import { GameTitleUI } from './title';
import { client } from '../../core';
export interface ILoadProps extends UIComponentProps, DefaultProps {} export interface ILoadProps extends UIComponentProps, DefaultProps {}
@ -34,6 +34,7 @@ const loadSceneProps = {
} satisfies SetupComponentOptions<ILoadProps>; } satisfies SetupComponentOptions<ILoadProps>;
export const LoadScene = defineComponent<ILoadProps>(props => { export const LoadScene = defineComponent<ILoadProps>(props => {
const loader = client.loader;
const taskFont = new Font('Verdana', 24); const taskFont = new Font('Verdana', 24);
const byteFont = new Font('Verdana', 12); const byteFont = new Font('Verdana', 12);

View File

@ -17,7 +17,7 @@ import {
RIGHT_STATUS_POS, RIGHT_STATUS_POS,
STATUS_BAR_HEIGHT, STATUS_BAR_HEIGHT,
STATUS_BAR_WIDTH STATUS_BAR_WIDTH
} from '../shared'; } from '../../shared';
import { import {
ILeftHeroStatus, ILeftHeroStatus,
IRightHeroStatus, IRightHeroStatus,
@ -29,11 +29,14 @@ import { getHeroStatusOn, state } from '@user/data-state';
import { hook } from '@user/data-base'; import { hook } from '@user/data-base';
import { mainUIController } from './controller'; import { mainUIController } from './controller';
import { isNil } from 'lodash-es'; import { isNil } from 'lodash-es';
import { mainMapExtension, mainMapRenderer } from '../commonIns';
import { using } from '../renderer'; import { using } from '../renderer';
import { client } from '../../core';
const MainScene = defineComponent(() => { const MainScene = defineComponent(() => {
const { mainMapRenderer, mainMapExtension } = client;
//#region 基本定义 //#region 基本定义
const mainTextboxProps: TextboxProps = { const mainTextboxProps: TextboxProps = {
text: '', text: '',
hidden: true, hidden: true,

View File

@ -27,7 +27,7 @@ import {
SAVE_ITEM_SIZE, SAVE_ITEM_SIZE,
SAVE_ITEM_TOP, SAVE_ITEM_TOP,
SAVE_PAGES SAVE_PAGES
} from '../shared'; } from '../../shared';
import { getSave, SaveData, adjustGrid, IGridLayoutData } from '../utils'; import { getSave, SaveData, adjustGrid, IGridLayoutData } from '../utils';
export const enum SaveMode { export const enum SaveMode {

View File

@ -23,7 +23,7 @@ import { openStatistics } from './statistics';
import { saveWithExist } from './save'; import { saveWithExist } from './save';
import { compressToBase64 } from 'lz-string'; import { compressToBase64 } from 'lz-string';
import { ViewMapUI } from './viewmap'; import { ViewMapUI } from './viewmap';
import { CENTER_LOC, FULL_LOC, MAIN_HEIGHT, POP_BOX_WIDTH } from '../shared'; import { CENTER_LOC, FULL_LOC, MAIN_HEIGHT, POP_BOX_WIDTH } from '../../shared';
import { useKey } from '../use'; import { useKey } from '../use';
export interface MainSettingsProps export interface MainSettingsProps

View File

@ -10,9 +10,9 @@ import {
MAIN_WIDTH, MAIN_WIDTH,
STATUS_BAR_HEIGHT, STATUS_BAR_HEIGHT,
STATUS_BAR_WIDTH STATUS_BAR_WIDTH
} from '../shared'; } from '../../shared';
import { DefaultProps } from '@motajs/render-vue'; import { DefaultProps } from '@motajs/render-vue';
import { materials } from '@user/client-base'; import { client } from '../../core';
export interface ILeftHeroStatus { export interface ILeftHeroStatus {
/** 楼层 id */ /** 楼层 id */
@ -116,6 +116,8 @@ export const LeftStatusBar = defineComponent<StatusBarProps<ILeftHeroStatus>>(
/** 状态属性的开始纵坐标 */ /** 状态属性的开始纵坐标 */
const STATUS_Y = TITLE_HEIGHT + STATUS_PAD; const STATUS_Y = TITLE_HEIGHT + STATUS_PAD;
const materials = client.materials;
// 可以换成 materials.getImageByAlias('xxx.png') 来使用全塔属性注册的图片 // 可以换成 materials.getImageByAlias('xxx.png') 来使用全塔属性注册的图片
const hpIcon = materials.getImageByAlias('icon-hp'); const hpIcon = materials.getImageByAlias('icon-hp');
const atkIcon = materials.getImageByAlias('icon-atk'); const atkIcon = materials.getImageByAlias('icon-atk');

View File

@ -20,7 +20,7 @@ import {
TITLE_STROKE_WIDTH, TITLE_STROKE_WIDTH,
TITLE_X, TITLE_X,
TITLE_Y TITLE_Y
} from '../shared'; } from '../../shared';
import { ElementLocator, Font } from '@motajs/render'; import { ElementLocator, Font } from '@motajs/render';
import { import {
ITransitionedController, ITransitionedController,
@ -35,7 +35,7 @@ import { MainSceneUI } from './main';
import { adjustCover } from '../utils'; import { adjustCover } from '../utils';
import { cosh, CurveMode, linear } from '@motajs/animate'; import { cosh, CurveMode, linear } from '@motajs/animate';
import { sleep } from '@motajs/common'; import { sleep } from '@motajs/common';
import { materials } from '@user/client-base'; import { client } from '../../core';
const enum TitleButton { const enum TitleButton {
StartGame, StartGame,
@ -64,6 +64,7 @@ const gameTitleProps = {
} satisfies SetupComponentOptions<GameTitleProps>; } satisfies SetupComponentOptions<GameTitleProps>;
export const GameTitle = defineComponent<GameTitleProps>(props => { export const GameTitle = defineComponent<GameTitleProps>(props => {
const materials = client.materials;
const bg = materials.getImageByAlias(TITLE_BACKGROUND_IMAGE); const bg = materials.getImageByAlias(TITLE_BACKGROUND_IMAGE);
//#region 计算背景图 //#region 计算背景图

View File

@ -21,11 +21,11 @@ import { generateBinary } from '@motajs/legacy-common';
import { SetupComponentOptions } from '@motajs/system'; import { SetupComponentOptions } from '@motajs/system';
import { saveSave, saveLoad } from './save'; import { saveSave, saveLoad } from './save';
import { mainUIController } from './controller'; import { mainUIController } from './controller';
import { MAIN_HEIGHT, FULL_LOC, POP_BOX_WIDTH, CENTER_LOC } from '../shared'; import { MAIN_HEIGHT, FULL_LOC, POP_BOX_WIDTH, CENTER_LOC } from '../../shared';
import { openReplay, openSettings } from './settings'; import { openReplay, openSettings } from './settings';
import { openViewMap } from './viewmap'; import { openViewMap } from './viewmap';
import { DefaultProps } from '@motajs/render-vue'; import { DefaultProps } from '@motajs/render-vue';
import { materials } from '@user/client-base'; import { client } from '../../core';
interface ToolbarProps extends DefaultProps { interface ToolbarProps extends DefaultProps {
loc?: ElementLocator; loc?: ElementLocator;
@ -74,6 +74,7 @@ export const PlayingToolbar = defineComponent<
ToolbarEmits, ToolbarEmits,
keyof ToolbarEmits keyof ToolbarEmits
>((props, { emit }) => { >((props, { emit }) => {
const materials = client.materials;
const bookIcon = materials.getImageByAlias('icon-book'); const bookIcon = materials.getImageByAlias('icon-book');
const flyIcon = materials.getImageByAlias('icon-fly'); const flyIcon = materials.getImageByAlias('icon-fly');
const toolIcon = materials.getImageByAlias('icon-toolbox'); const toolIcon = materials.getImageByAlias('icon-toolbox');
@ -171,6 +172,7 @@ const replayingProps = {
export const ReplayingToolbar = defineComponent<ReplayingProps>(props => { export const ReplayingToolbar = defineComponent<ReplayingProps>(props => {
const status = props.status; const status = props.status;
const materials = client.materials;
const bookIcon = materials.getImageByAlias('icon-book'); const bookIcon = materials.getImageByAlias('icon-book');
const saveIcon = materials.getImageByAlias('icon-save'); const saveIcon = materials.getImageByAlias('icon-save');
const font1 = Font.defaults({ size: 16 }); const font1 = Font.defaults({ size: 16 });

View File

@ -39,7 +39,7 @@ import {
RIGHT_STATUS_POS, RIGHT_STATUS_POS,
STATUS_BAR_HEIGHT, STATUS_BAR_HEIGHT,
STATUS_BAR_WIDTH STATUS_BAR_WIDTH
} from '../shared'; } from '../../shared';
export interface ViewMapProps extends UIComponentProps, BaseProps { export interface ViewMapProps extends UIComponentProps, BaseProps {
loc: ElementLocator; loc: ElementLocator;

View File

@ -2,7 +2,7 @@ import { compressToBase64, decompressFromBase64 } from 'lz-string';
import { getConfirm, waitbox } from '../components'; import { getConfirm, waitbox } from '../components';
import { IUIMountable } from '@motajs/system'; import { IUIMountable } from '@motajs/system';
import { SyncSaveFromServerResponse } from '@motajs/client-base'; import { SyncSaveFromServerResponse } from '@motajs/client-base';
import { CENTER_LOC, POP_BOX_WIDTH } from '../shared'; import { CENTER_LOC, POP_BOX_WIDTH } from '../../shared';
export interface SaveData { export interface SaveData {
name: string; name: string;

View File

@ -16,7 +16,7 @@ export const VARIATOR_DEBUG_SPEED = 0.2;
* 便 * 便
*/ */
export const DEBUG_DIVIDER = false; export const DEBUG_DIVIDER = false;
/** 当使用分频器调试时,分比例 */ /** 当使用分频器调试时,分比例 */
export const DIVIDER_DEBUG_DIVIDER = 60; export const DIVIDER_DEBUG_DIVIDER = 60;
//#endregion //#endregion

View File

@ -0,0 +1,53 @@
import { IRenderTreeRoot } from '@motajs/render';
import { ICoreState } from '@user/data-state';
import { IMapExtensionManager, IMapRenderer } from './render/map';
import { IBGMPlayer, IMotaAudioContext, ISoundPlayer } from '@motajs/audio';
import {
IAutotileProcessor,
IMaterialManager,
IMotaAssetsLoader
} from '@user/client-base';
import { IExcitation, IExcitationDivider } from '@motajs/animate';
export interface IClientCore {
/** 数据端状态对象 */
readonly data: ICoreState;
readonly loader: IMotaAssetsLoader;
/** 素材管理器 */
readonly materials: IMaterialManager;
/** 自动元件处理器 */
readonly autotile: IAutotileProcessor;
/** 用于渲染系统的 Raf 激励源 */
readonly rafExcitation: IExcitation<number>;
/** 用于渲染系统的激励源分频器 */
readonly excitationDivider: IExcitationDivider<number>;
/** 渲染画面的根元素 */
readonly renderer: IRenderTreeRoot;
/** 主地图渲染器,主要用于渲染游戏画面中的地图 */
readonly mainMapRenderer: IMapRenderer;
/** 副地图渲染器,主要用于渲染缩略图、浏览地图等内容 */
// readonly expandMapRenderer: IMapRenderer;
/** 主地图渲染器的拓展管理对象 */
readonly mainMapExtension: IMapExtensionManager;
/** 音频上下文 */
readonly audioContext: IMotaAudioContext;
/** 音效播放器 */
readonly soundPlayer: ISoundPlayer<SoundIds>;
/** BGM 播放器 */
readonly bgmPlayer: IBGMPlayer<BgmIds>;
/**
*
* @param state
*/
bindDataState(state: ICoreState): void;
/**
*
*/
getDataState(): ICoreState;
}

View File

@ -5,4 +5,3 @@ export * from './hero';
export * from './load'; export * from './load';
export * from './game'; export * from './game';
export * from './ins';

View File

@ -1,11 +0,0 @@
import { LoadProgressTotal } from '@motajs/loader';
import { MotaDataLoader } from './load';
//#region 加载实例
/** 加载进度 */
export const loadProgress = new LoadProgressTotal();
/** 数据端加载对象 */
export const dataLoader = new MotaDataLoader(loadProgress);
//#endregion

View File

@ -13,7 +13,9 @@ import {
HeroState, HeroState,
IHeroState, IHeroState,
IFlagSystem, IFlagSystem,
FlagSystem FlagSystem,
IMotaDataLoader,
MotaDataLoader
} from '@user/data-base'; } from '@user/data-base';
import { IEnemyAttr } from './enemy/types'; import { IEnemyAttr } from './enemy/types';
import { import {
@ -28,12 +30,16 @@ import {
} from './enemy'; } from './enemy';
import { HERO_DEFAULT_ATTRIBUTE, TILE_HEIGHT, TILE_WIDTH } from './shared'; import { HERO_DEFAULT_ATTRIBUTE, TILE_HEIGHT, TILE_WIDTH } from './shared';
import { IHeroAttr } from './hero'; import { IHeroAttr } from './hero';
import { ILoadProgressTotal, LoadProgressTotal } from '@motajs/loader';
export class CoreState implements ICoreState { export class CoreState implements ICoreState {
readonly roleFace: IRoleFaceBinder; readonly roleFace: IRoleFaceBinder;
readonly idNumberMap: Map<string, number>; readonly idNumberMap: Map<string, number>;
readonly numberIdMap: Map<number, string>; readonly numberIdMap: Map<number, string>;
readonly loadProgress: ILoadProgressTotal;
readonly dataLoader: IMotaDataLoader;
readonly layer: ILayerState; readonly layer: ILayerState;
readonly hero: IHeroState<IHeroAttr>; readonly hero: IHeroState<IHeroAttr>;
@ -48,6 +54,9 @@ export class CoreState implements ICoreState {
this.idNumberMap = new Map(); this.idNumberMap = new Map();
this.numberIdMap = new Map(); this.numberIdMap = new Map();
this.loadProgress = new LoadProgressTotal();
this.dataLoader = new MotaDataLoader(this.loadProgress);
//#region 勇士初始化 //#region 勇士初始化
const heroMover = new HeroMover(); const heroMover = new HeroMover();
@ -74,8 +83,8 @@ export class CoreState implements ICoreState {
const damageSystem = new DamageSystem(enemyContext); const damageSystem = new DamageSystem(enemyContext);
const mapDamage = new MapDamage(enemyContext); const mapDamage = new MapDamage(enemyContext);
damageSystem.useCalculator(new MainDamageCalculator()); damageSystem.useCalculator(new MainDamageCalculator());
mapDamage.useConverter(new MainMapDamageConverter());
mapDamage.useReducer(new MainMapDamageReducer()); mapDamage.useReducer(new MainMapDamageReducer());
mapDamage.useConverter(new MainMapDamageConverter());
enemyContext.attachDamageSystem(damageSystem); enemyContext.attachDamageSystem(damageSystem);
enemyContext.attachMapDamage(mapDamage); enemyContext.attachMapDamage(mapDamage);
enemyContext.registerAuraConverter(new CommonAuraConverter()); enemyContext.registerAuraConverter(new CommonAuraConverter());

View File

@ -4,11 +4,13 @@ import {
IEnemyContext, IEnemyContext,
IEnemyManager, IEnemyManager,
IHeroFollower, IHeroFollower,
IHeroState IHeroState,
IMotaDataLoader
} from '@user/data-base'; } from '@user/data-base';
import { IEnemyAttr } from './enemy/types'; import { IEnemyAttr } from './enemy/types';
import { IHeroAttr } from './hero'; import { IHeroAttr } from './hero';
import { IFlagSystem } from '../../data-base/src/flag/types'; import { IFlagSystem } from '../../data-base/src/flag/types';
import { ILoadProgressTotal } from '@motajs/loader';
export interface IGameDataState { export interface IGameDataState {
/** 怪物管理器 */ /** 怪物管理器 */
@ -28,6 +30,11 @@ export interface ICoreState {
/** 图块数字到 id 的映射 */ /** 图块数字到 id 的映射 */
readonly numberIdMap: Map<number, string>; readonly numberIdMap: Map<number, string>;
/** 加载进度对象 */
readonly loadProgress: ILoadProgressTotal;
/** 数据端加载对象 */
readonly dataLoader: IMotaDataLoader;
/** 地图状态 */ /** 地图状态 */
readonly layer: ILayerState; readonly layer: ILayerState;
/** 勇士状态 */ /** 勇士状态 */

View File

@ -4,10 +4,11 @@ import { patchAll } from '@user/data-fallback';
import { loading } from '@user/data-base'; import { loading } from '@user/data-base';
import { Patch } from '@motajs/legacy-common'; import { Patch } from '@motajs/legacy-common';
import { logger } from '@motajs/common'; import { logger } from '@motajs/common';
import { state } from '@user/data-state';
export function createData() { export function createData() {
createMota(); createMota();
patchAll(); patchAll(state);
create(); create();
if (main.replayChecking) { if (main.replayChecking) {

View File

@ -519,9 +519,8 @@ export function initFallback() {
const fn = generateJumpFn(dx, dy); const fn = generateJumpFn(dx, dy);
// 先使用 mainMapRenderer 妥协 // 先使用 mainMapRenderer 妥协
const { mainMapRenderer: renderer } = Mota.require( const { client } = Mota.require('@user/client-modules');
'@user/client-modules' const renderer = client.mainMapRenderer;
);
if (renderer.layerState !== state.layer) { if (renderer.layerState !== state.layer) {
callback?.(); callback?.();
return; return;

View File

@ -588,6 +588,8 @@ export interface ISoundPlayer<T extends string> {
readonly ac: IMotaAudioContext; readonly ac: IMotaAudioContext;
/** 当前是否启用此音效播放器 */ /** 当前是否启用此音效播放器 */
readonly enabled: boolean; readonly enabled: boolean;
/** 当前正在播放的音频 */
readonly playing: Set<number>;
/** /**
* *

View File

@ -102,7 +102,8 @@ function handleAudioSetting<T extends number | boolean>(
n: T, n: T,
_o: T _o: T
) { ) {
const { bgmPlayer, soundPlayer } = Mota.require('@user/client-base'); const { client } = Mota.require('@user/client-modules');
const { bgmPlayer, soundPlayer } = client;
if (key === 'bgmEnabled') { if (key === 'bgmEnabled') {
bgmPlayer.setEnabled(n as boolean); bgmPlayer.setEnabled(n as boolean);
core.checkBgm(); core.checkBgm();