HumanBreak/packages-user/client-modules/src/render/loopMap.ts

108 lines
3.3 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { Container, MotaRenderer } from '@motajs/render';
import { hook } from '@user/data-base';
import { MiscData } from '@user/data-state';
import { FloorDamageExtends } from './elements/damage';
import { FloorItemDetail } from './elements/itemDetail';
import {
LayerGroup,
FloorLayer,
LayerGroupFloorBinder,
FloorViewport
} from './elements';
const loopMaps = MiscData.loopMaps;
let loopLayer: LayerGroup;
let show: boolean = false;
/** 循环式地图中更新视角的委托ticker */
let delegation: number = -1;
export function createLoopMap() {
hook.on('changingFloor', (floorId, _heroLoc) => {
enableLoopMapElement(floorId);
});
}
function createLayer() {
const group = new LayerGroup();
['bg', 'bg2', 'event', 'fg', 'fg2'].forEach(v => {
group.addLayer(v as FloorLayer);
});
const damage = new FloorDamageExtends();
const detail = new FloorItemDetail();
group.id = 'layer-loop';
group.extends(damage);
group.extends(detail);
loopLayer = group;
group.setZIndex(20);
}
function enableLoopMapElement(floorId: FloorIds) {
if (!loopMaps.has(floorId)) {
disableLoopMapElement();
return;
}
if (!loopLayer) createLayer();
const render = MotaRenderer.get('render-main');
const draw = render?.getElementById('map-draw') as Container;
const group = render?.getElementById('layer-main') as LayerGroup;
if (!draw || !group) return;
const ex = loopLayer.getExtends('floor-binder') as LayerGroupFloorBinder;
const viewport = group.getExtends('viewport') as FloorViewport;
if (!ex || !viewport) return;
ex.bindFloor(floorId);
draw.appendChild(loopLayer);
show = true;
const floor = core.status.maps[floorId];
viewport.setAutoBound(false);
const transform = group.camera;
const width = floor.width;
const testPos = width * loopLayer.cellSize;
loopLayer.removeTicker(delegation);
delegation = loopLayer.delegateTicker(() => {
const [x1] = transform.transformed(0, 0);
const camera = loopLayer.camera;
if (x1 > 0) {
// 这个是计算循环地图应该显示在哪
const [, y2] = transform.transformed(x1 - testPos, 0);
camera.reset();
camera.translate(core._PX_ - testPos, y2);
loopLayer.pos(transform.x - core._PX_, 0);
loopLayer.show();
loopLayer.update(loopLayer);
} else {
const [x2, y2] = transform.transformed(testPos, 0);
if (x2 < core._PX_) {
// 这个不用做其他运算,可以直接显示
camera.reset();
camera.translate(0, y2);
loopLayer.pos(x2, 0);
loopLayer.show();
loopLayer.update(loopLayer);
} else {
loopLayer.hide();
}
}
});
}
function disableLoopMapElement() {
if (!show) return;
show = false;
loopLayer.remove();
const render = MotaRenderer.get('render-main');
const group = render?.getElementById('layer-main') as LayerGroup;
if (!group) return;
const viewport = group.getExtends('viewport') as FloorViewport;
if (!viewport) return;
viewport.setAutoBound(true);
loopLayer.removeTicker(delegation);
}