mirror of
https://github.com/unanmed/HumanBreak.git
synced 2025-01-19 20:59:37 +08:00
feat: 自动元件连接
This commit is contained in:
parent
78efe81423
commit
fe57adf6af
@ -528,6 +528,12 @@ var comment_c456ea59_6018_45ef_8bcc_211a24c627dc = {
|
|||||||
}).toString(),
|
}).toString(),
|
||||||
"_docs": "绑定贴图",
|
"_docs": "绑定贴图",
|
||||||
"_data": "该图块绑定的贴图,用法详见文档"
|
"_data": "该图块绑定的贴图,用法详见文档"
|
||||||
|
},
|
||||||
|
"autotileConnection": {
|
||||||
|
"_leaf": true,
|
||||||
|
"_type": "textarea",
|
||||||
|
"_docs": "自动元件连接",
|
||||||
|
"_data": "此属性对自动元件有效,是一个数组,可以填写一些图块id,从而让自动元件可以与这些图块连接,从而做到自动元件能连门等操作"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -113,7 +113,7 @@ var maps_90f36752_8815_4be8_b32b_d7fad1d0542e =
|
|||||||
"140": {"cls":"npcs","id":"blackTrader","faceIds":{"down":"blueTrader","left":"redMSNpc","right":"blackTrader","up":"N532"}},
|
"140": {"cls":"npcs","id":"blackTrader","faceIds":{"down":"blueTrader","left":"redMSNpc","right":"blackTrader","up":"N532"}},
|
||||||
"141": {"cls":"autotile","id":"autotile4","script":1},
|
"141": {"cls":"autotile","id":"autotile4","script":1},
|
||||||
"142": {"cls":"autotile","id":"autotile5"},
|
"142": {"cls":"autotile","id":"autotile5"},
|
||||||
"143": {"cls":"autotile","id":"autotile6"},
|
"143": {"cls":"autotile","id":"autotile6","autotileConnection":["A492"]},
|
||||||
"144": {"cls":"autotile","id":"autotile7"},
|
"144": {"cls":"autotile","id":"autotile7"},
|
||||||
"145": {"cls":"autotile","id":"autotile8"},
|
"145": {"cls":"autotile","id":"autotile8"},
|
||||||
"146": {"cls":"autotile","id":"autotile9","canPass":true},
|
"146": {"cls":"autotile","id":"autotile9","canPass":true},
|
||||||
|
@ -78,13 +78,13 @@ export class Logger {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (this.level <= LogLevel.ERROR && this.enabled) {
|
if (this.level <= LogLevel.ERROR && this.enabled) {
|
||||||
console.error(`[ERROR Code ${code}] ${text}`);
|
|
||||||
if (!main.replayChecking) {
|
if (!main.replayChecking) {
|
||||||
logTip.style.color = 'lightcoral';
|
logTip.style.color = 'lightcoral';
|
||||||
logTip.style.display = 'block';
|
logTip.style.display = 'block';
|
||||||
logTip.textContent = `Error thrown, please check in console.`;
|
logTip.textContent = `Error thrown, please check in console.`;
|
||||||
hideTipText();
|
hideTipText();
|
||||||
}
|
}
|
||||||
|
throw `[ERROR Code ${code}] ${text}`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,6 +74,8 @@ class TextureCache extends EventEmitter<TextureCacheEvent> {
|
|||||||
|
|
||||||
/** 渲染信息 */
|
/** 渲染信息 */
|
||||||
renderable: Map<number, RenderableData | AutotileRenderable> = new Map();
|
renderable: Map<number, RenderableData | AutotileRenderable> = new Map();
|
||||||
|
/** 自动元件额外连接信息,用于对非自身图块进行连接 */
|
||||||
|
autoConn: Map<number, Set<number>> = new Map();
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
@ -91,6 +93,7 @@ class TextureCache extends EventEmitter<TextureCacheEvent> {
|
|||||||
this.autotile = splitAutotiles(this.idNumberMap);
|
this.autotile = splitAutotiles(this.idNumberMap);
|
||||||
this.images = core.material.images.images;
|
this.images = core.material.images.images;
|
||||||
this.calRenderable();
|
this.calRenderable();
|
||||||
|
this.calAutotileConnections();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -109,13 +112,17 @@ class TextureCache extends EventEmitter<TextureCacheEvent> {
|
|||||||
/**
|
/**
|
||||||
* 计算每个图块的可渲染信息
|
* 计算每个图块的可渲染信息
|
||||||
*/
|
*/
|
||||||
calRenderable() {
|
private calRenderable() {
|
||||||
const map = maps_90f36752_8815_4be8_b32b_d7fad1d0542e;
|
const map = maps_90f36752_8815_4be8_b32b_d7fad1d0542e;
|
||||||
for (const [key, data] of Object.entries(map)) {
|
for (const [key, data] of Object.entries(map)) {
|
||||||
this.calRenderableByNum(parseInt(key));
|
this.calRenderableByNum(parseInt(key));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据图块数字计算出它的渲染信息
|
||||||
|
* @param num 图块数字
|
||||||
|
*/
|
||||||
calRenderableByNum(
|
calRenderableByNum(
|
||||||
num: number
|
num: number
|
||||||
): RenderableData | AutotileRenderable | null {
|
): RenderableData | AutotileRenderable | null {
|
||||||
@ -290,6 +297,38 @@ class TextureCache extends EventEmitter<TextureCacheEvent> {
|
|||||||
getRenderable(num: number) {
|
getRenderable(num: number) {
|
||||||
return this.renderable.get(num) ?? this.calRenderableByNum(num);
|
return this.renderable.get(num) ?? this.calRenderableByNum(num);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 计算自动元件的额外连接
|
||||||
|
*/
|
||||||
|
private calAutotileConnections() {
|
||||||
|
const icons = icons_4665ee12_3a1f_44a4_bea3_0fccba634dc1;
|
||||||
|
const maps = maps_90f36752_8815_4be8_b32b_d7fad1d0542e;
|
||||||
|
|
||||||
|
Object.keys(icons.autotile).forEach(v => {
|
||||||
|
const num = this.idNumberMap[v as AllIdsOf<'autotile'>];
|
||||||
|
const data = maps[num];
|
||||||
|
const { autotileConnection } = data;
|
||||||
|
if (!autotileConnection) return;
|
||||||
|
const list = new Set<AllNumbers>();
|
||||||
|
autotileConnection.forEach(v => {
|
||||||
|
if (typeof v === 'number') {
|
||||||
|
list.add(v);
|
||||||
|
} else {
|
||||||
|
list.add(this.idNumberMap[v]);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.autoConn.set(num, list);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取自动元件的额外连接情况
|
||||||
|
* @param num 自动元件的图块数字
|
||||||
|
*/
|
||||||
|
getAutotileConnections(num: number) {
|
||||||
|
return this.autoConn.get(num);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const texture = new TextureCache();
|
export const texture = new TextureCache();
|
||||||
@ -302,7 +341,6 @@ const smallAutotile: Record<number, [number, number, number, number]> = {};
|
|||||||
function getAutotileIndices() {
|
function getAutotileIndices() {
|
||||||
// 应当从 0 - 255 进行枚举
|
// 应当从 0 - 255 进行枚举
|
||||||
// 二进制从高位到低位依次是 左上 上 右上 右 右下 下 左下 左
|
// 二进制从高位到低位依次是 左上 上 右上 右 右下 下 左下 左
|
||||||
// 首先是3x4的
|
|
||||||
// 有兴趣可以研究下这个算法
|
// 有兴趣可以研究下这个算法
|
||||||
const get = (
|
const get = (
|
||||||
target: Record<number, [number, number, number, number]>,
|
target: Record<number, [number, number, number, number]>,
|
||||||
|
@ -314,6 +314,11 @@ export class Layer extends Container implements IRenderDestroyable {
|
|||||||
const tile = texture.autotile;
|
const tile = texture.autotile;
|
||||||
const map = maps_90f36752_8815_4be8_b32b_d7fad1d0542e;
|
const map = maps_90f36752_8815_4be8_b32b_d7fad1d0542e;
|
||||||
|
|
||||||
|
const w = this.mapWidth;
|
||||||
|
const h = this.mapHeight;
|
||||||
|
|
||||||
|
this.autotiles = {};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 检查连接信息
|
* 检查连接信息
|
||||||
* @param id 比较对象的id(就是正在检查周围的那个自动元件,九宫格中心的)
|
* @param id 比较对象的id(就是正在检查周围的那个自动元件,九宫格中心的)
|
||||||
@ -323,42 +328,49 @@ export class Layer extends Container implements IRenderDestroyable {
|
|||||||
* @param replace2 比较对象相对被比较对象应该处理的位数
|
* @param replace2 比较对象相对被比较对象应该处理的位数
|
||||||
*/
|
*/
|
||||||
const check = (
|
const check = (
|
||||||
index1: number,
|
x1: number,
|
||||||
index2: number,
|
y1: number,
|
||||||
|
x2: number,
|
||||||
|
y2: number,
|
||||||
replace1: number,
|
replace1: number,
|
||||||
replace2: number
|
_replace2: number
|
||||||
) => {
|
) => {
|
||||||
|
const index1 = x1 + y1 * w;
|
||||||
|
const index2 = x2 + y2 * w;
|
||||||
|
this.autotiles[index1] ??= 0;
|
||||||
|
this.autotiles[index2] ??= 0;
|
||||||
|
// 与地图边缘,视为连接
|
||||||
|
if (x2 < 0 || y2 < 0 || x2 >= w || y2 >= h) {
|
||||||
|
this.autotiles[index1] |= replace1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
const num1 = data[index1] as AllNumbersOf<'autotile'>; // 这个一定是自动元件
|
const num1 = data[index1] as AllNumbersOf<'autotile'>; // 这个一定是自动元件
|
||||||
const num2 = data[index2] as AllNumbersOf<'autotile'>;
|
const num2 = data[index2] as AllNumbersOf<'autotile'>;
|
||||||
|
// 对于额外连接的情况
|
||||||
|
const autoConn = texture.getAutotileConnections(num1);
|
||||||
|
if (autoConn?.has(num2)) {
|
||||||
|
this.autotiles[index1] |= replace1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
const info = map[num2 as Exclude<AllNumbers, 0>];
|
const info = map[num2 as Exclude<AllNumbers, 0>];
|
||||||
if (info.cls !== 'autotile') {
|
if (!info || info.cls !== 'autotile') {
|
||||||
// 被比较对象不是自动元件
|
// 被比较对象不是自动元件
|
||||||
this.autotiles[num1] ??= 0;
|
this.autotiles[index1] &= ~replace1;
|
||||||
this.autotiles[num1] &= ~replace1;
|
|
||||||
} else {
|
} else {
|
||||||
const parent1 = tile[num1].parent;
|
|
||||||
const parent2 = tile[num2].parent;
|
const parent2 = tile[num2].parent;
|
||||||
if (num2 === num1) {
|
if (num2 === num1) {
|
||||||
// 二者一样,视为连接
|
// 二者一样,视为连接
|
||||||
this.autotiles[index1] |= replace1;
|
this.autotiles[index1] |= replace1;
|
||||||
this.autotiles[index2] |= replace2;
|
|
||||||
} else if (parent2?.has(num1)) {
|
} else if (parent2?.has(num1)) {
|
||||||
// 被比较对象是比较对象的父元件,那么比较对象视为连接
|
// 被比较对象是比较对象的父元件,那么比较对象视为连接
|
||||||
this.autotiles[index1] |= replace1;
|
this.autotiles[index1] |= replace1;
|
||||||
} else if (parent1?.has(num2)) {
|
|
||||||
// 比较对象是被比较对象的父元件,那么被比较对象视为连接
|
|
||||||
this.autotiles[index2] |= replace2;
|
|
||||||
} else {
|
} else {
|
||||||
// 上述条件都不满足,那么不连接
|
// 上述条件都不满足,那么不连接
|
||||||
this.autotiles[index1] &= ~replace1;
|
this.autotiles[index1] &= ~replace1;
|
||||||
this.autotiles[index2] &= ~replace2;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const w = this.mapWidth;
|
|
||||||
const h = this.mapHeight;
|
|
||||||
|
|
||||||
for (let nx = x; nx < ex; nx++) {
|
for (let nx = x; nx < ex; nx++) {
|
||||||
for (let ny = y; ny < ey; ny++) {
|
for (let ny = y; ny < ey; ny++) {
|
||||||
if (nx > w || ny > h) continue;
|
if (nx > w || ny > h) continue;
|
||||||
@ -371,26 +383,18 @@ export class Layer extends Container implements IRenderDestroyable {
|
|||||||
const { cls } = info;
|
const { cls } = info;
|
||||||
if (cls !== 'autotile') continue;
|
if (cls !== 'autotile') continue;
|
||||||
|
|
||||||
// 只有最左一列和最上一列需要计算一周,其他的只计算右 右下 下即可
|
|
||||||
// 太地狱了这个,看看就好
|
// 太地狱了这个,看看就好
|
||||||
if (nx === x) {
|
// 左上 左 左下
|
||||||
// 左上 左 左下
|
check(nx, ny, nx - 1, ny - 1, 0b10000000, 0b00001000);
|
||||||
check(index, index - w - 1, 0b10000000, 0b00001000);
|
check(nx, ny, nx - 1, ny, 0b00000001, 0b00010000);
|
||||||
check(index, index - 1, 0b00000001, 0b00010000);
|
check(nx, ny, nx - 1, ny + 1, 0b00000010, 0b00100000);
|
||||||
check(index, index + w - 1, 0b00000010, 0b00100000);
|
// 上 右上
|
||||||
}
|
check(nx, ny, nx, ny - 1, 0b01000000, 0b00000100);
|
||||||
if (ny === y) {
|
check(nx, ny, nx + 1, ny - 1, 0b00100000, 0b00000010);
|
||||||
if (nx !== x) {
|
|
||||||
check(index, index - w - 1, 0b10000000, 0b00001000);
|
|
||||||
}
|
|
||||||
// 上 右上
|
|
||||||
check(index, index - w, 0b01000000, 0b00000100);
|
|
||||||
check(index, index - w + 1, 0b00100000, 0b00000010);
|
|
||||||
}
|
|
||||||
// 右 右下 下
|
// 右 右下 下
|
||||||
check(index, index + 1, 0b00010000, 0b00000001);
|
check(nx, ny, nx + 1, ny, 0b00010000, 0b00000001);
|
||||||
check(index, index + w + 1, 0b00001000, 0b10000000);
|
check(nx, ny, nx + 1, ny + 1, 0b00001000, 0b10000000);
|
||||||
check(index, index + w, 0b00000100, 0b01000000);
|
check(nx, ny, nx, ny + 1, 0b00000100, 0b01000000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -154,21 +154,21 @@ Mota.require('var', 'hook').once('reset', () => {
|
|||||||
render.appendChild([layer, bgLayer]);
|
render.appendChild([layer, bgLayer]);
|
||||||
layer.bindThis('event');
|
layer.bindThis('event');
|
||||||
bgLayer.bindThis('bg');
|
bgLayer.bindThis('bg');
|
||||||
bgLayer.setBackground(650);
|
bgLayer.setBackground(305);
|
||||||
|
|
||||||
const ani = new Animation();
|
const ani = new Animation();
|
||||||
|
|
||||||
ani.ticker.add(() => {
|
// ani.ticker.add(() => {
|
||||||
camera.reset();
|
// camera.reset();
|
||||||
camera.rotate((ani.angle / 180) * Math.PI);
|
// camera.rotate((ani.angle / 180) * Math.PI);
|
||||||
camera.move(ani.x, ani.y);
|
// camera.move(ani.x, ani.y);
|
||||||
camera.scale(ani.size);
|
// camera.scale(ani.size);
|
||||||
render.update(render);
|
// render.update(render);
|
||||||
});
|
// });
|
||||||
|
|
||||||
camera.rotate(Math.PI * 1.23);
|
// camera.rotate(Math.PI * 1.23);
|
||||||
camera.move(230, 380);
|
camera.move(240, 240);
|
||||||
camera.scale(0.7);
|
// camera.scale(0.7);
|
||||||
render.update();
|
render.update();
|
||||||
|
|
||||||
// sleep(2000).then(() => {
|
// sleep(2000).then(() => {
|
||||||
@ -176,21 +176,21 @@ Mota.require('var', 'hook').once('reset', () => {
|
|||||||
// });
|
// });
|
||||||
|
|
||||||
sleep(1000).then(() => {
|
sleep(1000).then(() => {
|
||||||
ani.mode(hyper('sin', 'out'))
|
// ani.mode(hyper('sin', 'out'))
|
||||||
.time(100)
|
// .time(100)
|
||||||
.absolute()
|
// .absolute()
|
||||||
.rotate(30)
|
// .rotate(30)
|
||||||
.move(240, 240);
|
// .move(240, 240);
|
||||||
sleep(100).then(() => {
|
// sleep(100).then(() => {
|
||||||
ani.time(3000).rotate(0);
|
// ani.time(3000).rotate(0);
|
||||||
});
|
// });
|
||||||
sleep(3100).then(() => {
|
// sleep(3100).then(() => {
|
||||||
ani.time(5000)
|
// ani.time(5000)
|
||||||
.mode(hyper('sin', 'in-out'))
|
// .mode(hyper('sin', 'in-out'))
|
||||||
.rotate(360)
|
// .rotate(360)
|
||||||
.move(200, 480)
|
// .move(200, 480)
|
||||||
.scale(0.5);
|
// .scale(0.5);
|
||||||
});
|
// });
|
||||||
// ani.mode(shake2(5, hyper('sin', 'in-out')), true)
|
// ani.mode(shake2(5, hyper('sin', 'in-out')), true)
|
||||||
// .time(5000)
|
// .time(5000)
|
||||||
// .shake(1, 0);
|
// .shake(1, 0);
|
||||||
|
3
src/types/core.d.ts
vendored
3
src/types/core.d.ts
vendored
@ -1417,10 +1417,9 @@ interface MapDataOf<T extends keyof NumberToId> {
|
|||||||
cls: ClsOf<NumberToId[T]>;
|
cls: ClsOf<NumberToId[T]>;
|
||||||
|
|
||||||
bigImage?: ImageIds;
|
bigImage?: ImageIds;
|
||||||
|
|
||||||
faceIds?: Record<Dir, AllIds>;
|
faceIds?: Record<Dir, AllIds>;
|
||||||
|
|
||||||
animate?: number;
|
animate?: number;
|
||||||
|
autotileConnection?: (AllIds | AllNumbers)[];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
Reference in New Issue
Block a user