From d73fe27680c658a8f1b0da84e402f08a3406df8b Mon Sep 17 00:00:00 2001 From: unanmed <1319491857@qq.com> Date: Sat, 17 Aug 2024 23:11:20 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=9C=B0=E5=9B=BE=E6=B8=B2=E6=9F=93?= =?UTF-8?q?=E7=BC=93=E5=AD=98=E5=B0=8F=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/core/render/container.ts | 50 ++++++++++++++++++++------------ src/core/render/item.ts | 15 ++++++---- src/core/render/preset/damage.ts | 11 +++---- src/core/render/preset/layer.ts | 4 +-- src/core/render/render.ts | 2 +- src/core/render/sprite.ts | 26 ++++++++++++----- 6 files changed, 66 insertions(+), 42 deletions(-) diff --git a/src/core/render/container.ts b/src/core/render/container.ts index bfb588d..386cee0 100644 --- a/src/core/render/container.ts +++ b/src/core/render/container.ts @@ -17,36 +17,50 @@ export class Container canvas: MotaOffscreenCanvas2D; - constructor(type: RenderItemPosition = 'static') { + /** 是否启用缓存机制,对于特殊场景,内部已经包含了缓存机制,这时就不需要启用了 */ + private readonly enableCache: boolean; + + /** + * 创建一个容器,容器中可以包含其他渲染对象 + * @param type 渲染模式,absolute表示绝对位置,static表示跟随摄像机移动,只对顶层元素有效 + * @param cache 是否启用缓存机制 + */ + constructor(type: RenderItemPosition = 'static', cache: boolean = true) { super(); this.canvas = new MotaOffscreenCanvas2D(); this.type = type; this.canvas.withGameScale(true); + this.enableCache = cache; } - render( - canvas: HTMLCanvasElement, - ctx: CanvasRenderingContext2D, - camera: Camera - ): void { + private renderTo(canvas: MotaOffscreenCanvas2D, camera: Camera) { + const { ctx } = canvas; + this.sortedChildren.forEach(v => { + if (v.hidden) return; + ctx.save(); + if (!v.antiAliasing) { + ctx.imageSmoothingEnabled = false; + } else { + ctx.imageSmoothingEnabled = true; + } + v.render(canvas, camera); + ctx.restore(); + }); + } + + render(canvas: MotaOffscreenCanvas2D, camera: Camera): void { this.emit('beforeRender'); if (this.needUpdate) { this.cache(this.using); this.needUpdate = false; } - withCacheRender(this, canvas, ctx, camera, c => { - this.sortedChildren.forEach(v => { - if (v.hidden) return; - ctx.save(); - if (!v.antiAliasing) { - ctx.imageSmoothingEnabled = false; - } else { - ctx.imageSmoothingEnabled = true; - } - v.render(c.canvas, c.ctx, camera); - ctx.restore(); + if (this.enableCache) { + withCacheRender(this, canvas.canvas, canvas.ctx, camera, c => { + this.renderTo(c, camera); }); - }); + } else { + this.renderTo(canvas, camera); + } this.writing = void 0; this.emit('afterRender'); } diff --git a/src/core/render/item.ts b/src/core/render/item.ts index 56338a5..8647659 100644 --- a/src/core/render/item.ts +++ b/src/core/render/item.ts @@ -185,14 +185,9 @@ export abstract class RenderItem /** * 渲染这个对象 * @param canvas 渲染至的画布 - * @param ctx 渲染至的画布的渲染上下文 * @param camera 渲染时使用的摄像机 */ - abstract render( - canvas: HTMLCanvasElement, - ctx: CanvasRenderingContext2D, - camera: Camera - ): void; + abstract render(canvas: MotaOffscreenCanvas2D, camera: Camera): void; /** * 修改这个对象的大小 @@ -286,6 +281,14 @@ export abstract class RenderItem this.update(this); } + /** + * 将这个渲染元素添加到其他父元素上 + * @param parent 父元素 + */ + append(parent: IRenderChildable) { + parent.appendChild(this); + } + /** * 从渲染树中移除这个节点 */ diff --git a/src/core/render/preset/damage.ts b/src/core/render/preset/damage.ts index b4c965a..cbc428f 100644 --- a/src/core/render/preset/damage.ts +++ b/src/core/render/preset/damage.ts @@ -135,7 +135,7 @@ export class Damage extends Sprite { private needUpdateBlocks: Set = new Set(); constructor() { - super(); + super('absolute', false); this.block = new BlockCacher(0, 0, core._WIDTH_, 1); this.type = 'absolute'; @@ -386,6 +386,7 @@ export class Damage extends Sprite { * @param camera 摄像机 */ renderDamage(camera: Camera) { + console.time('damage'); const { ctx } = this.damageMap; ctx.save(); transformCanvas(this.damageMap, camera, true); @@ -401,6 +402,7 @@ export class Damage extends Sprite { const px = bx * cell; const py = by * cell; + // todo: 是否真的需要缓存 // 检查有没有缓存 const cache = block.cache.get(v * block.cacheDepth); if (cache) { @@ -408,7 +410,6 @@ export class Damage extends Sprite { return; } - console.time('damage1'); // 否则依次渲染并写入缓存 const temp = new MotaOffscreenCanvas2D(); temp.setHD(true); @@ -416,9 +417,7 @@ export class Damage extends Sprite { temp.withGameScale(true); temp.size(size, size); const { ctx: ct } = temp; - console.timeEnd('damage1'); - console.time('damage2'); const render = this.renderable.get(v); render?.forEach(v => { if (!v) return; @@ -431,13 +430,11 @@ export class Damage extends Sprite { ct.strokeText(v.text, v.x, v.y); ct.fillText(v.text, v.x, v.y); }); - console.timeEnd('damage2'); - console.time('damage3'); ctx.drawImage(temp.canvas, px, py, size, size); block.cache.set(v, temp.canvas); - console.timeEnd('damage3'); }); ctx.restore(); + console.timeEnd('damage'); } } diff --git a/src/core/render/preset/layer.ts b/src/core/render/preset/layer.ts index 817d4aa..e12df2a 100644 --- a/src/core/render/preset/layer.ts +++ b/src/core/render/preset/layer.ts @@ -103,7 +103,7 @@ export class LayerGroup extends Container { private extend: Map = new Map(); constructor() { - super(); + super('static', false); this.setHD(true); this.setAntiAliasing(false); @@ -831,7 +831,7 @@ export class Layer extends Container { private extend: Map = new Map(); constructor() { - super('absolute'); + super('absolute', false); // this.setHD(false); this.setAntiAliasing(false); diff --git a/src/core/render/render.ts b/src/core/render/render.ts index 5d7849a..93f95a6 100644 --- a/src/core/render/render.ts +++ b/src/core/render/render.ts @@ -89,7 +89,7 @@ export class MotaRenderer extends Container { ctx.imageSmoothingEnabled = true; ct.imageSmoothingEnabled = true; } - v.render(ca, ct, camera); + v.render(this.target, camera); ct.restore(); }); }); diff --git a/src/core/render/sprite.ts b/src/core/render/sprite.ts index 4b3007a..89e2ec3 100644 --- a/src/core/render/sprite.ts +++ b/src/core/render/sprite.ts @@ -3,6 +3,7 @@ import { ICanvasCachedRenderItem, RenderFunction, RenderItem, + RenderItemPosition, withCacheRender } from './item'; import { MotaOffscreenCanvas2D } from '../fx/canvas2d'; @@ -12,26 +13,35 @@ export class Sprite extends RenderItem implements ICanvasCachedRenderItem { canvas: MotaOffscreenCanvas2D; - constructor() { + private readonly enableCache: boolean; + + /** + * 创建一个精灵,可以自由在上面渲染内容 + * @param type 渲染模式,absolute表示绝对位置,static表示跟随摄像机移动,只对顶层元素有效 + * @param cache 是否启用缓存机制 + */ + constructor(type: RenderItemPosition = 'static', cache: boolean = true) { super(); + this.type = type; + this.enableCache = cache; this.renderFn = () => {}; this.canvas = new MotaOffscreenCanvas2D(); this.canvas.withGameScale(true); } - render( - canvas: HTMLCanvasElement, - ctx: CanvasRenderingContext2D, - camera: Camera - ): void { + render(canvas: MotaOffscreenCanvas2D, camera: Camera): void { this.emit('beforeRender'); if (this.needUpdate) { this.cache(this.using); this.needUpdate = false; } - withCacheRender(this, canvas, ctx, camera, canvas => { + if (this.enableCache) { + withCacheRender(this, canvas.canvas, canvas.ctx, camera, canvas => { + this.renderFn(canvas, camera); + }); + } else { this.renderFn(canvas, camera); - }); + } this.writing = void 0; this.emit('afterRender'); }