From fe57adf6af62c3e5a1b23e5143878dfbaa29e118 Mon Sep 17 00:00:00 2001 From: unanmed <1319491857@qq.com> Date: Sat, 18 May 2024 23:21:06 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E8=87=AA=E5=8A=A8=E5=85=83=E4=BB=B6?= =?UTF-8?q?=E8=BF=9E=E6=8E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/_server/table/comment.js | 6 +++ public/project/maps.js | 2 +- src/core/common/logger.ts | 2 +- src/core/render/cache.ts | 42 +++++++++++++++++++- src/core/render/preset/layer.ts | 70 +++++++++++++++++---------------- src/core/render/render.ts | 52 ++++++++++++------------ src/types/core.d.ts | 3 +- 7 files changed, 112 insertions(+), 65 deletions(-) diff --git a/public/_server/table/comment.js b/public/_server/table/comment.js index 7193067..e868123 100644 --- a/public/_server/table/comment.js +++ b/public/_server/table/comment.js @@ -528,6 +528,12 @@ var comment_c456ea59_6018_45ef_8bcc_211a24c627dc = { }).toString(), "_docs": "绑定贴图", "_data": "该图块绑定的贴图,用法详见文档" + }, + "autotileConnection": { + "_leaf": true, + "_type": "textarea", + "_docs": "自动元件连接", + "_data": "此属性对自动元件有效,是一个数组,可以填写一些图块id,从而让自动元件可以与这些图块连接,从而做到自动元件能连门等操作" } } }, diff --git a/public/project/maps.js b/public/project/maps.js index f7d88f5..9d1f14e 100644 --- a/public/project/maps.js +++ b/public/project/maps.js @@ -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"}}, "141": {"cls":"autotile","id":"autotile4","script":1}, "142": {"cls":"autotile","id":"autotile5"}, - "143": {"cls":"autotile","id":"autotile6"}, + "143": {"cls":"autotile","id":"autotile6","autotileConnection":["A492"]}, "144": {"cls":"autotile","id":"autotile7"}, "145": {"cls":"autotile","id":"autotile8"}, "146": {"cls":"autotile","id":"autotile9","canPass":true}, diff --git a/src/core/common/logger.ts b/src/core/common/logger.ts index 05c248d..f639ba0 100644 --- a/src/core/common/logger.ts +++ b/src/core/common/logger.ts @@ -78,13 +78,13 @@ export class Logger { }); } if (this.level <= LogLevel.ERROR && this.enabled) { - console.error(`[ERROR Code ${code}] ${text}`); if (!main.replayChecking) { logTip.style.color = 'lightcoral'; logTip.style.display = 'block'; logTip.textContent = `Error thrown, please check in console.`; hideTipText(); } + throw `[ERROR Code ${code}] ${text}`; } } diff --git a/src/core/render/cache.ts b/src/core/render/cache.ts index fb88fa6..4b31f1d 100644 --- a/src/core/render/cache.ts +++ b/src/core/render/cache.ts @@ -74,6 +74,8 @@ class TextureCache extends EventEmitter { /** 渲染信息 */ renderable: Map = new Map(); + /** 自动元件额外连接信息,用于对非自身图块进行连接 */ + autoConn: Map> = new Map(); constructor() { super(); @@ -91,6 +93,7 @@ class TextureCache extends EventEmitter { this.autotile = splitAutotiles(this.idNumberMap); this.images = core.material.images.images; this.calRenderable(); + this.calAutotileConnections(); }); } @@ -109,13 +112,17 @@ class TextureCache extends EventEmitter { /** * 计算每个图块的可渲染信息 */ - calRenderable() { + private calRenderable() { const map = maps_90f36752_8815_4be8_b32b_d7fad1d0542e; for (const [key, data] of Object.entries(map)) { this.calRenderableByNum(parseInt(key)); } } + /** + * 根据图块数字计算出它的渲染信息 + * @param num 图块数字 + */ calRenderableByNum( num: number ): RenderableData | AutotileRenderable | null { @@ -290,6 +297,38 @@ class TextureCache extends EventEmitter { getRenderable(num: number) { 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(); + 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(); @@ -302,7 +341,6 @@ const smallAutotile: Record = {}; function getAutotileIndices() { // 应当从 0 - 255 进行枚举 // 二进制从高位到低位依次是 左上 上 右上 右 右下 下 左下 左 - // 首先是3x4的 // 有兴趣可以研究下这个算法 const get = ( target: Record, diff --git a/src/core/render/preset/layer.ts b/src/core/render/preset/layer.ts index dcb00c2..f76ffaf 100644 --- a/src/core/render/preset/layer.ts +++ b/src/core/render/preset/layer.ts @@ -314,6 +314,11 @@ export class Layer extends Container implements IRenderDestroyable { const tile = texture.autotile; const map = maps_90f36752_8815_4be8_b32b_d7fad1d0542e; + const w = this.mapWidth; + const h = this.mapHeight; + + this.autotiles = {}; + /** * 检查连接信息 * @param id 比较对象的id(就是正在检查周围的那个自动元件,九宫格中心的) @@ -323,42 +328,49 @@ export class Layer extends Container implements IRenderDestroyable { * @param replace2 比较对象相对被比较对象应该处理的位数 */ const check = ( - index1: number, - index2: number, + x1: number, + y1: number, + x2: number, + y2: 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 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]; - if (info.cls !== 'autotile') { + if (!info || info.cls !== 'autotile') { // 被比较对象不是自动元件 - this.autotiles[num1] ??= 0; - this.autotiles[num1] &= ~replace1; + this.autotiles[index1] &= ~replace1; } else { - const parent1 = tile[num1].parent; const parent2 = tile[num2].parent; if (num2 === num1) { // 二者一样,视为连接 this.autotiles[index1] |= replace1; - this.autotiles[index2] |= replace2; } else if (parent2?.has(num1)) { // 被比较对象是比较对象的父元件,那么比较对象视为连接 this.autotiles[index1] |= replace1; - } else if (parent1?.has(num2)) { - // 比较对象是被比较对象的父元件,那么被比较对象视为连接 - this.autotiles[index2] |= replace2; } else { // 上述条件都不满足,那么不连接 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 ny = y; ny < ey; ny++) { if (nx > w || ny > h) continue; @@ -371,26 +383,18 @@ export class Layer extends Container implements IRenderDestroyable { const { cls } = info; if (cls !== 'autotile') continue; - // 只有最左一列和最上一列需要计算一周,其他的只计算右 右下 下即可 // 太地狱了这个,看看就好 - if (nx === x) { - // 左上 左 左下 - check(index, index - w - 1, 0b10000000, 0b00001000); - check(index, index - 1, 0b00000001, 0b00010000); - check(index, index + w - 1, 0b00000010, 0b00100000); - } - if (ny === y) { - if (nx !== x) { - check(index, index - w - 1, 0b10000000, 0b00001000); - } - // 上 右上 - check(index, index - w, 0b01000000, 0b00000100); - check(index, index - w + 1, 0b00100000, 0b00000010); - } + // 左上 左 左下 + check(nx, ny, nx - 1, ny - 1, 0b10000000, 0b00001000); + check(nx, ny, nx - 1, ny, 0b00000001, 0b00010000); + check(nx, ny, nx - 1, ny + 1, 0b00000010, 0b00100000); + // 上 右上 + check(nx, ny, nx, ny - 1, 0b01000000, 0b00000100); + check(nx, ny, nx + 1, ny - 1, 0b00100000, 0b00000010); // 右 右下 下 - check(index, index + 1, 0b00010000, 0b00000001); - check(index, index + w + 1, 0b00001000, 0b10000000); - check(index, index + w, 0b00000100, 0b01000000); + check(nx, ny, nx + 1, ny, 0b00010000, 0b00000001); + check(nx, ny, nx + 1, ny + 1, 0b00001000, 0b10000000); + check(nx, ny, nx, ny + 1, 0b00000100, 0b01000000); } } } diff --git a/src/core/render/render.ts b/src/core/render/render.ts index e2ff14c..8559cc5 100644 --- a/src/core/render/render.ts +++ b/src/core/render/render.ts @@ -154,21 +154,21 @@ Mota.require('var', 'hook').once('reset', () => { render.appendChild([layer, bgLayer]); layer.bindThis('event'); bgLayer.bindThis('bg'); - bgLayer.setBackground(650); + bgLayer.setBackground(305); const ani = new Animation(); - ani.ticker.add(() => { - camera.reset(); - camera.rotate((ani.angle / 180) * Math.PI); - camera.move(ani.x, ani.y); - camera.scale(ani.size); - render.update(render); - }); + // ani.ticker.add(() => { + // camera.reset(); + // camera.rotate((ani.angle / 180) * Math.PI); + // camera.move(ani.x, ani.y); + // camera.scale(ani.size); + // render.update(render); + // }); - camera.rotate(Math.PI * 1.23); - camera.move(230, 380); - camera.scale(0.7); + // camera.rotate(Math.PI * 1.23); + camera.move(240, 240); + // camera.scale(0.7); render.update(); // sleep(2000).then(() => { @@ -176,21 +176,21 @@ Mota.require('var', 'hook').once('reset', () => { // }); sleep(1000).then(() => { - ani.mode(hyper('sin', 'out')) - .time(100) - .absolute() - .rotate(30) - .move(240, 240); - sleep(100).then(() => { - ani.time(3000).rotate(0); - }); - sleep(3100).then(() => { - ani.time(5000) - .mode(hyper('sin', 'in-out')) - .rotate(360) - .move(200, 480) - .scale(0.5); - }); + // ani.mode(hyper('sin', 'out')) + // .time(100) + // .absolute() + // .rotate(30) + // .move(240, 240); + // sleep(100).then(() => { + // ani.time(3000).rotate(0); + // }); + // sleep(3100).then(() => { + // ani.time(5000) + // .mode(hyper('sin', 'in-out')) + // .rotate(360) + // .move(200, 480) + // .scale(0.5); + // }); // ani.mode(shake2(5, hyper('sin', 'in-out')), true) // .time(5000) // .shake(1, 0); diff --git a/src/types/core.d.ts b/src/types/core.d.ts index ccb75a5..e5eba13 100644 --- a/src/types/core.d.ts +++ b/src/types/core.d.ts @@ -1417,10 +1417,9 @@ interface MapDataOf { cls: ClsOf; bigImage?: ImageIds; - faceIds?: Record; - animate?: number; + autotileConnection?: (AllIds | AllNumbers)[]; } /**