refactor: 存档系统挪至渲染端

This commit is contained in:
AncTe committed 2026-09-17 13:29:34 +08:00
1 parent 89434537c8
commit 94ceb50cfe
12 files changed
+212 -215

No files matched your search

+27 -23
View File
@@ -1,4 +1,4 @@
import { ICoreState } from '@user/data-state';
import { CoreState } from '@user/data-state';
import { IClientCore } from './types';
import {
IMotaAudioContext,
@@ -15,7 +15,9 @@ import {
IAutotileProcessor,
MotaAssetsLoader,
MaterialManager,
AutotileProcessor
AutotileProcessor,
ISaveSystem,
SaveSystem
} from '@user/client-base';
import {
IMapRenderer,
@@ -41,9 +43,12 @@ import {
import { loading } from '@user/data-base';
import { fallbackLoad } from './fallback/load';
export class ClientCore implements IClientCore {
readonly loader: IMotaAssetsLoader;
export class ClientCore extends CoreState implements IClientCore {
// Layer 4 渲染基础层
readonly save: ISaveSystem;
// Layer 5 渲染顶层
readonly loader: IMotaAssetsLoader;
readonly materials: IMaterialManager;
readonly autotile: IAutotileProcessor;
@@ -57,7 +62,14 @@ export class ClientCore implements IClientCore {
readonly soundPlayer: ISoundPlayer<SoundIds>;
readonly bgmPlayer: IBGMPlayer<BgmIds>;
constructor(public data: ICoreState) {
constructor() {
super();
//#region Layer 4
this.save = new SaveSystem();
this.save.init(`@game/${core.firstData.name}`);
//#region 音频系统
this.audioContext = new MotaAudioContext();
@@ -74,8 +86,8 @@ export class ClientCore implements IClientCore {
//#endregion
this.loader = new MotaAssetsLoader(
data.loadProgress,
data.dataLoader,
this.loadProgress,
this.dataLoader,
this.audioContext,
this.soundPlayer,
this.materials
@@ -114,12 +126,12 @@ export class ClientCore implements IClientCore {
// 使用分频器,用户可以在设置中调整,如果设备性能较差调高分频有助于提高性能表现
excitaion: excitationDivider
});
this.mainMapRenderer = new MapRenderer(this.materials, data.maps);
this.mainMapRenderer = new MapRenderer(this.materials);
this.mainMapExtension = new MapExtensionManager(this.mainMapRenderer);
// 兼容层
loading.once('assetBuilt', () => {
this.createMainExtension();
this.initMapExtensions();
});
//#endregion
@@ -128,24 +140,16 @@ export class ClientCore implements IClientCore {
/**
* 进行地图渲染拓展初始化
*/
private async createMainExtension() {
private async initMapExtensions() {
// 算是一种妥协吧,等之后加载系统重构之后应该会清晰很多
await this.materials.trackedAsset.then();
this.mainMapRenderer.useAsset(this.materials.trackedAsset);
const layer = this.data.maps.getLayerByAlias('event');
if (layer) {
this.mainMapExtension.addHero(this.data.hero.mover, layer);
this.mainMapExtension.addDoor(layer);
}
// const layer = this.maps.getLayerByAlias('event');
// if (layer) {
// this.mainMapExtension.addHero(this.hero.mover, layer);
// this.mainMapExtension.addDoor(layer);
// }
this.mainMapExtension.addText();
}
bindDataState(state: ICoreState): void {
this.data = state;
}
getDataState(): ICoreState {
return this.data;
}
}
+1 -2
View File
@@ -1,7 +1,6 @@
import { state } from '@user/data-state';
import { ClientCore } from './client';
// TODO: 逐渐弱化 ClientCore 的单例概念,每个接口都通过参数传入 IClientCore 对象
/** 客户端实例 */
export const client = new ClientCore(state);
export const client = new ClientCore();
@@ -78,9 +78,9 @@ export class MapRenderer
assetWidth: number = 4096;
assetHeight: number = 4096;
layerState: IGameMap;
map: IGameMap | null = null;
/** 地图状态钩子控制器 */
private layerStateHook: IHookController<IGameMapHooks>;
private mapHook: IHookController<IGameMapHooks> | null = null;
/** 排序后的图层 */
private sortedLayers: IMapLayer[] = [];
@@ -205,13 +205,8 @@ export class MapRenderer
/**
* 创建地图渲染器
* @param manager 素材管理器
* @param gl 画布 WebGL2 上下文
* @param transform 视角变换矩阵
*/
constructor(
readonly manager: IMaterialManager,
layerState: IGameMap
) {
constructor(readonly manager: IMaterialManager) {
this.movingIndexPool.push(
...Array.from({ length: this.movingCount }, (_, i) => i).reverse()
);
@@ -219,11 +214,6 @@ export class MapRenderer
this.gl = this.canvas.getContext('webgl2')!;
this.transform = new Transform();
this.transform.bind(this);
this.layerState = layerState;
this.layerStateHook = layerState.addHook(
new RendererLayerStateHook(this)
);
this.layerStateHook.load();
// 上下文初始化要依赖于 offsetPool,因此提前调用
const offsetPool = this.getOffsetPool();
this.offsetPool = offsetPool;
@@ -414,40 +404,42 @@ export class MapRenderer
* 图层排序
*/
private sortLayer() {
this.sortedLayers = [...this.layerState.layerList].sort((a, b) => {
if (!this.map) return;
this.sortedLayers = [...this.map.layerList].sort((a, b) => {
return a.zIndex - b.zIndex;
});
this.sortedLayers.forEach((v, i) => this.layerIndexMap.set(v, i));
}
updateLayerList() {
if (!this.map) return;
this.sortLayer();
this.resizeLayer();
this.layerCount = this.layerState.layerList.size;
this.layerCount = this.map.layerList.size;
this.vertex.updateLayerArray();
}
setLayerState(layerState: IGameMap): void {
if (layerState === this.layerState) return;
this.layerStateHook.unload();
this.layerState = layerState;
this.layerStateHook = layerState.addHook(
new RendererLayerStateHook(this)
);
this.layerStateHook.load();
setLayerState(map: IGameMap): void {
if (map === this.map) return;
this.mapHook?.unload();
this.map = map;
this.mapHook = map.addHook(new RendererLayerStateHook(this));
this.mapHook.load();
this.sortLayer();
this.resizeLayer();
this.layerCount = layerState.layerList.size;
this.layerCount = map.layerList.size;
this.vertex.updateLayerArray();
this.vertex.resizeMap();
}
getLayer(identifier: string): IMapLayer | null {
return this.layerState.getLayerByAlias(identifier) ?? null;
if (!this.map) return null;
return this.map.getLayerByAlias(identifier) ?? null;
}
hasLayer(layer: IMapLayer): boolean {
return this.layerState.hasLayer(layer);
if (!this.map) return false;
return this.map.hasLayer(layer);
}
getSortedLayer(): IMapLayer[] {
@@ -339,7 +339,7 @@ export interface IMapRenderer {
/** 顶点数组生成器 */
readonly vertex: IMapVertexGenerator;
/** 使用的地图状态对象 */
readonly layerState: IGameMap;
readonly map: IGameMap | null;
/** 地图宽度 */
readonly mapWidth: number;
+4 -17
View File
@@ -1,18 +1,16 @@
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
IMotaAssetsLoader,
IClientBase
} from '@user/client-base';
import { IExcitation, IExcitationDivider } from '@motajs/animate';
export interface IClientCore {
/** 数据端状态对象 */
readonly data: ICoreState;
export interface IClientCore extends IClientBase {
/** 渲染端加载对象 */
readonly loader: IMotaAssetsLoader;
/** 素材管理器 */
@@ -39,15 +37,4 @@ export interface IClientCore {
readonly soundPlayer: ISoundPlayer<SoundIds>;
/** BGM 播放器 */
readonly bgmPlayer: IBGMPlayer<BgmIds>;
/**
* 绑定数据端状态
* @param state 数据端状态
*/
bindDataState(state: ICoreState): void;
/**
* 获取当前绑定的数据端状态对象
*/
getDataState(): ICoreState;
}