mirror of
https://github.com/unanmed/HumanBreak.git
synced 2025-11-27 13:42:58 +08:00
fix: 设置图块的周围自动元件检测
This commit is contained in:
parent
037746999d
commit
9d4bd381e5
@ -125,12 +125,13 @@ class TrackedAssetData
|
||||
}
|
||||
const origin = this.originSourceMap.get(index);
|
||||
const prev = this.sourceList.get(index);
|
||||
if (origin) {
|
||||
if (origin && origin !== source) {
|
||||
this.skipRef.delete(origin);
|
||||
}
|
||||
if (prev) {
|
||||
this.skipRef.delete(prev);
|
||||
}
|
||||
this.originSourceMap.set(index, source);
|
||||
if (source instanceof ImageBitmap) {
|
||||
if (this.skipRef.has(source)) return;
|
||||
this.sourceList.set(index, source);
|
||||
@ -141,7 +142,6 @@ class TrackedAssetData
|
||||
this.skipRef.set(bitmap, index);
|
||||
// 要把源也加到映射中,因为这里的 bitmap 与外部源并不同引用
|
||||
this.skipRef.set(source, index);
|
||||
this.originSourceMap.set(index, source);
|
||||
}
|
||||
this.dirty(index);
|
||||
}
|
||||
|
||||
@ -5,4 +5,4 @@ import { materials } from '@user/client-base';
|
||||
/** 主地图渲染器,用于渲染游戏画面 */
|
||||
export const mainMapRenderer = new MapRenderer(materials, state.layer);
|
||||
/** 副地图渲染器,用于渲染缩略图、浏览地图等 */
|
||||
export const expandMapRenderer = new MapRenderer(materials, state.layer);
|
||||
// export const expandMapRenderer = new MapRenderer(materials, state.layer);
|
||||
|
||||
@ -158,7 +158,7 @@ export class BlockSplitter<T> implements IBlockSplitter<T> {
|
||||
const bx = Math.floor(x / this.blockWidth);
|
||||
const by = Math.floor(y / this.blockHeight);
|
||||
if (!this.checkLocRange(bx, by)) return null;
|
||||
const index = y * this.width + x;
|
||||
const index = by * this.width + bx;
|
||||
return this.blockMap.get(index) ?? null;
|
||||
}
|
||||
|
||||
|
||||
@ -1230,8 +1230,12 @@ export class MapRenderer
|
||||
|
||||
const area = this.viewport.getRenderArea();
|
||||
area.blockList.forEach(v => {
|
||||
this.vertex.updateBlockCache(v);
|
||||
v.data.render();
|
||||
if (v.data.dirty) {
|
||||
this.vertex.updateBlockCache(v);
|
||||
}
|
||||
if (v.data.renderDirty) {
|
||||
v.data.render();
|
||||
}
|
||||
});
|
||||
|
||||
if (area.dirty.length > 0) {
|
||||
|
||||
@ -470,17 +470,19 @@ export class MapVertexGenerator
|
||||
if (!block) return;
|
||||
const vertex = block.data.getLayerData(layer);
|
||||
if (!vertex) return;
|
||||
const bx = mx - block.dataX;
|
||||
const by = my - block.dataY;
|
||||
const newIndex: BlockIndex = {
|
||||
layer,
|
||||
mapX: mx,
|
||||
mapY: my,
|
||||
mapIndex: my * this.mapWidth + mx,
|
||||
blockX: block.x,
|
||||
blockY: block.y,
|
||||
blockIndex: block.y * block.width + block.x
|
||||
blockX: bx,
|
||||
blockY: by,
|
||||
blockIndex: by * block.width + bx
|
||||
};
|
||||
const tile = this.renderer.manager.getTile(mapArray[index.mapIndex]);
|
||||
if (!tile) return;
|
||||
const tile = this.renderer.manager.getTile(mapArray[newIndex.mapIndex]);
|
||||
if (!tile || tile.cls !== BlockCls.Autotile) return;
|
||||
this.updateAutotile(
|
||||
mapArray,
|
||||
vertex,
|
||||
@ -590,6 +592,7 @@ export class MapVertexGenerator
|
||||
blockY: block.y,
|
||||
blockIndex: dIndex
|
||||
};
|
||||
|
||||
// 需要检查周围一圈的自动元件
|
||||
this.checkAutotileConnectionAround(layer, array, index, -1, -1);
|
||||
this.checkAutotileConnectionAround(layer, array, index, 0, -1);
|
||||
@ -669,98 +672,100 @@ export class MapVertexGenerator
|
||||
this.checkUpdateCallPerformance('updateBlockList');
|
||||
}
|
||||
this.checkRebuild();
|
||||
if (blocks.length > 50) {
|
||||
// 对于超出50个的更新操作使用懒更新
|
||||
blocks.forEach(v => {
|
||||
const block = this.block.getBlockByDataLoc(v.x, v.y);
|
||||
if (!block) return;
|
||||
const bx = v.x - block.dataX;
|
||||
const by = v.y - block.dataY;
|
||||
block.data.markDirty(layer, bx - 1, by - 1, bx + 2, by + 2);
|
||||
block.data.markRenderDirty();
|
||||
const left = bx === 0;
|
||||
const top = by === 0;
|
||||
const right = bx === block.width - 1;
|
||||
const bottom = by === block.height - 1;
|
||||
// 需要更一圈的自动元件
|
||||
if (left) {
|
||||
// 左侧的分块需要更新
|
||||
const nextBlock = block.left();
|
||||
if (nextBlock) {
|
||||
const { width: w, data } = nextBlock;
|
||||
data.markDirty(layer, w - 1, by - 1, w, by + 1);
|
||||
data.markRenderDirty();
|
||||
}
|
||||
if (top) {
|
||||
// 左上侧的分块需要更新
|
||||
const nextBlock = block.leftUp();
|
||||
if (nextBlock) {
|
||||
const { width: w, height: h, data } = nextBlock;
|
||||
data.markDirty(layer, w - 1, h - 1, w, h);
|
||||
data.markRenderDirty();
|
||||
}
|
||||
}
|
||||
if (bottom) {
|
||||
// 左下侧的分块需要更新
|
||||
const nextBlock = block.leftDown();
|
||||
if (nextBlock) {
|
||||
const { width: w, data } = nextBlock;
|
||||
data.markDirty(layer, w - 1, 0, w, 1);
|
||||
data.markRenderDirty();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (top) {
|
||||
// 上侧的分块需要更新
|
||||
const nextBlock = block.up();
|
||||
if (nextBlock) {
|
||||
const { height: h, data } = nextBlock;
|
||||
data.markDirty(layer, bx - 1, h - 1, bx + 1, h);
|
||||
data.markRenderDirty();
|
||||
}
|
||||
}
|
||||
if (right) {
|
||||
// 右侧的分块需要更新
|
||||
const nextBlock = block.right();
|
||||
if (nextBlock) {
|
||||
const { data } = nextBlock;
|
||||
data.markDirty(layer, 0, by - 1, 1, by + 1);
|
||||
data.markRenderDirty();
|
||||
}
|
||||
if (top) {
|
||||
// 右上侧的分块需要更新
|
||||
const nextBlock = block.rightUp();
|
||||
if (nextBlock) {
|
||||
const { height: h, data } = nextBlock;
|
||||
data.markDirty(layer, 0, h - 1, 1, h);
|
||||
data.markRenderDirty();
|
||||
}
|
||||
}
|
||||
if (bottom) {
|
||||
// 右下侧的分块需要更新
|
||||
const nextBlock = block.rightDown();
|
||||
if (nextBlock) {
|
||||
const { data } = nextBlock;
|
||||
data.markDirty(layer, 0, 0, 1, 1);
|
||||
data.markRenderDirty();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (bottom) {
|
||||
// 下侧的分块需要更新
|
||||
const nextBlock = block.down();
|
||||
if (nextBlock) {
|
||||
const { data } = nextBlock;
|
||||
data.markDirty(layer, bx - 1, 0, bx + 1, 1);
|
||||
data.markRenderDirty();
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
|
||||
if (blocks.length <= 50) {
|
||||
blocks.forEach(({ block: num, x, y }) => {
|
||||
this.updateBlockVertex(layer, num, x, y);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// 对于超出50个的更新操作使用懒更新
|
||||
blocks.forEach(v => {
|
||||
const block = this.block.getBlockByDataLoc(v.x, v.y);
|
||||
if (!block) return;
|
||||
const bx = v.x - block.dataX;
|
||||
const by = v.y - block.dataY;
|
||||
block.data.markDirty(layer, bx - 1, by - 1, bx + 2, by + 2);
|
||||
block.data.markRenderDirty();
|
||||
const left = bx === 0;
|
||||
const top = by === 0;
|
||||
const right = bx === block.width - 1;
|
||||
const bottom = by === block.height - 1;
|
||||
// 需要更一圈的自动元件
|
||||
if (left) {
|
||||
// 左侧的分块需要更新
|
||||
const nextBlock = block.left();
|
||||
if (nextBlock) {
|
||||
const { width: w, data } = nextBlock;
|
||||
data.markDirty(layer, w - 1, by - 1, w, by + 1);
|
||||
data.markRenderDirty();
|
||||
}
|
||||
if (top) {
|
||||
// 左上侧的分块需要更新
|
||||
const nextBlock = block.leftUp();
|
||||
if (nextBlock) {
|
||||
const { width: w, height: h, data } = nextBlock;
|
||||
data.markDirty(layer, w - 1, h - 1, w, h);
|
||||
data.markRenderDirty();
|
||||
}
|
||||
}
|
||||
if (bottom) {
|
||||
// 左下侧的分块需要更新
|
||||
const nextBlock = block.leftDown();
|
||||
if (nextBlock) {
|
||||
const { width: w, data } = nextBlock;
|
||||
data.markDirty(layer, w - 1, 0, w, 1);
|
||||
data.markRenderDirty();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (top) {
|
||||
// 上侧的分块需要更新
|
||||
const nextBlock = block.up();
|
||||
if (nextBlock) {
|
||||
const { height: h, data } = nextBlock;
|
||||
data.markDirty(layer, bx - 1, h - 1, bx + 1, h);
|
||||
data.markRenderDirty();
|
||||
}
|
||||
}
|
||||
if (right) {
|
||||
// 右侧的分块需要更新
|
||||
const nextBlock = block.right();
|
||||
if (nextBlock) {
|
||||
const { data } = nextBlock;
|
||||
data.markDirty(layer, 0, by - 1, 1, by + 1);
|
||||
data.markRenderDirty();
|
||||
}
|
||||
if (top) {
|
||||
// 右上侧的分块需要更新
|
||||
const nextBlock = block.rightUp();
|
||||
if (nextBlock) {
|
||||
const { height: h, data } = nextBlock;
|
||||
data.markDirty(layer, 0, h - 1, 1, h);
|
||||
data.markRenderDirty();
|
||||
}
|
||||
}
|
||||
if (bottom) {
|
||||
// 右下侧的分块需要更新
|
||||
const nextBlock = block.rightDown();
|
||||
if (nextBlock) {
|
||||
const { data } = nextBlock;
|
||||
data.markDirty(layer, 0, 0, 1, 1);
|
||||
data.markRenderDirty();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (bottom) {
|
||||
// 下侧的分块需要更新
|
||||
const nextBlock = block.down();
|
||||
if (nextBlock) {
|
||||
const { data } = nextBlock;
|
||||
data.markDirty(layer, bx - 1, 0, bx + 1, 1);
|
||||
data.markRenderDirty();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
updateBlockCache(block: Readonly<IBlockData<IMapVertexBlock>>): void {
|
||||
@ -1036,6 +1041,9 @@ class MapVertexBlock implements IMapVertexBlock {
|
||||
this.dirty = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 标记为需要更新渲染缓冲区
|
||||
*/
|
||||
markRenderDirty() {
|
||||
this.renderDirty = true;
|
||||
}
|
||||
|
||||
@ -128,7 +128,7 @@ export class MapViewport implements IMapViewportController {
|
||||
return {
|
||||
render: renderArea,
|
||||
dirty: updateArea,
|
||||
blockList: blockList.filter(v => v.data.dirty)
|
||||
blockList: blockList
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -26,7 +26,7 @@ export class CoreState implements ICoreState {
|
||||
|
||||
loadState(data: IStateSaveData): void {
|
||||
this.hero.removeAllFollowers();
|
||||
data.followers.forEach(v => {
|
||||
data?.followers.forEach(v => {
|
||||
this.hero.addFollower(v.num, v.identifier);
|
||||
});
|
||||
}
|
||||
|
||||
@ -7,6 +7,8 @@ import {
|
||||
} from './types';
|
||||
import { Hookable, HookController, logger } from '@motajs/common';
|
||||
|
||||
// todo: 提供 core.setBlock 等方法的替代方法,同时添加 setBlockList,以及前景背景的接口
|
||||
|
||||
export class MapLayer
|
||||
extends Hookable<IMapLayerHooks, IMapLayerHookController>
|
||||
implements IMapLayer
|
||||
|
||||
@ -140,6 +140,7 @@ export class TextureMaxRectsStreamComposer
|
||||
|
||||
private nextCanvas() {
|
||||
this.nowCanvas = document.createElement('canvas');
|
||||
this.nowCanvas.id = `${Math.random()}`;
|
||||
this.nowCtx = this.nowCanvas.getContext('2d')!;
|
||||
this.nowCanvas.width = this.maxWidth;
|
||||
this.nowCanvas.height = this.maxHeight;
|
||||
|
||||
@ -3138,6 +3138,11 @@ maps.prototype.showBlock = function (x, y, floorId) {
|
||||
block?.id ?? 0,
|
||||
0
|
||||
);
|
||||
if (floorId === core.status.floorId) {
|
||||
const { layer } = Mota.require('@user/data-state').state;
|
||||
const event = layer.getLayerByAlias('event');
|
||||
event.setBlock(block.id, x, y);
|
||||
}
|
||||
// 在本层,添加动画
|
||||
if (floorId == core.status.floorId) {
|
||||
if (block.event.cls == 'autotile') {
|
||||
@ -3170,6 +3175,11 @@ maps.prototype.hideBlock = function (x, y, floorId) {
|
||||
0,
|
||||
block?.id ?? 0
|
||||
);
|
||||
if (floorId === core.status.floorId) {
|
||||
const { layer } = Mota.require('@user/data-state').state;
|
||||
const event = layer.getLayerByAlias('event');
|
||||
event.setBlock(0, x, y);
|
||||
}
|
||||
|
||||
// 删除动画,清除地图
|
||||
this._removeBlockFromMap(floorId, block);
|
||||
@ -3193,6 +3203,11 @@ maps.prototype.hideBlockByIndex = function (index, floorId) {
|
||||
0,
|
||||
block?.id ?? 0
|
||||
);
|
||||
if (floorId === core.status.floorId) {
|
||||
const { layer } = Mota.require('@user/data-state').state;
|
||||
const event = layer.getLayerByAlias('event');
|
||||
event.setBlock(0, x, y);
|
||||
}
|
||||
};
|
||||
|
||||
////// 一次性隐藏多个block //////
|
||||
@ -3265,6 +3280,11 @@ maps.prototype.removeBlockByIndex = function (index, floorId) {
|
||||
0,
|
||||
block?.id ?? 0
|
||||
);
|
||||
if (floorId === core.status.floorId) {
|
||||
const { layer } = Mota.require('@user/data-state').state;
|
||||
const event = layer.getLayerByAlias('event');
|
||||
event.setBlock(0, x, y);
|
||||
}
|
||||
};
|
||||
|
||||
////// 一次性删除多个block //////
|
||||
@ -3419,6 +3439,11 @@ maps.prototype.setBlock = function (number, x, y, floorId, noredraw) {
|
||||
number,
|
||||
originBlock?.id ?? 0
|
||||
);
|
||||
if (floorId === core.status.floorId) {
|
||||
const { layer } = Mota.require('@user/data-state').state;
|
||||
const event = layer.getLayerByAlias('event');
|
||||
event.setBlock(number, x, y);
|
||||
}
|
||||
};
|
||||
|
||||
maps.prototype.animateSetBlock = function (
|
||||
@ -3620,6 +3645,11 @@ maps.prototype.replaceBlock = function (fromNumber, toNumber, floorId) {
|
||||
fromNumber,
|
||||
toNumber
|
||||
);
|
||||
if (floorId === core.status.floorId) {
|
||||
const { layer } = Mota.require('@user/data-state').state;
|
||||
const event = layer.getLayerByAlias('event');
|
||||
event.setBlock(toNumber, x, y);
|
||||
}
|
||||
}
|
||||
}, this);
|
||||
if (floorId == core.status.floorId) core.redrawMap();
|
||||
@ -3669,6 +3699,11 @@ maps.prototype.setBgFgBlock = function (name, number, x, y, floorId) {
|
||||
y,
|
||||
floorId
|
||||
);
|
||||
if (floorId === core.status.floorId) {
|
||||
const { layer } = Mota.require('@user/data-state').state;
|
||||
const mapLayer = layer.getLayerByAlias(name);
|
||||
mapLayer.setBlock(block.id, x, y);
|
||||
}
|
||||
};
|
||||
|
||||
////// 重置地图 //////
|
||||
|
||||
Loading…
Reference in New Issue
Block a user