feat: 地图渲染缓存小优化

This commit is contained in:
unanmed 2024-08-17 23:11:20 +08:00
parent c7660e93c7
commit d73fe27680
6 changed files with 66 additions and 42 deletions

View File

@ -17,24 +17,24 @@ export class Container
canvas: MotaOffscreenCanvas2D; canvas: MotaOffscreenCanvas2D;
constructor(type: RenderItemPosition = 'static') { /** 是否启用缓存机制,对于特殊场景,内部已经包含了缓存机制,这时就不需要启用了 */
private readonly enableCache: boolean;
/**
*
* @param type absolute表示绝对位置static表示跟随摄像机移动
* @param cache
*/
constructor(type: RenderItemPosition = 'static', cache: boolean = true) {
super(); super();
this.canvas = new MotaOffscreenCanvas2D(); this.canvas = new MotaOffscreenCanvas2D();
this.type = type; this.type = type;
this.canvas.withGameScale(true); this.canvas.withGameScale(true);
this.enableCache = cache;
} }
render( private renderTo(canvas: MotaOffscreenCanvas2D, camera: Camera) {
canvas: HTMLCanvasElement, const { ctx } = canvas;
ctx: CanvasRenderingContext2D,
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 => { this.sortedChildren.forEach(v => {
if (v.hidden) return; if (v.hidden) return;
ctx.save(); ctx.save();
@ -43,10 +43,24 @@ export class Container
} else { } else {
ctx.imageSmoothingEnabled = true; ctx.imageSmoothingEnabled = true;
} }
v.render(c.canvas, c.ctx, camera); v.render(canvas, camera);
ctx.restore(); ctx.restore();
}); });
}
render(canvas: MotaOffscreenCanvas2D, camera: Camera): void {
this.emit('beforeRender');
if (this.needUpdate) {
this.cache(this.using);
this.needUpdate = false;
}
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.writing = void 0;
this.emit('afterRender'); this.emit('afterRender');
} }

View File

@ -185,14 +185,9 @@ export abstract class RenderItem
/** /**
* *
* @param canvas * @param canvas
* @param ctx
* @param camera 使 * @param camera 使
*/ */
abstract render( abstract render(canvas: MotaOffscreenCanvas2D, camera: Camera): void;
canvas: HTMLCanvasElement,
ctx: CanvasRenderingContext2D,
camera: Camera
): void;
/** /**
* *
@ -286,6 +281,14 @@ export abstract class RenderItem
this.update(this); this.update(this);
} }
/**
*
* @param parent
*/
append(parent: IRenderChildable) {
parent.appendChild(this);
}
/** /**
* *
*/ */

View File

@ -135,7 +135,7 @@ export class Damage extends Sprite {
private needUpdateBlocks: Set<number> = new Set(); private needUpdateBlocks: Set<number> = new Set();
constructor() { constructor() {
super(); super('absolute', false);
this.block = new BlockCacher(0, 0, core._WIDTH_, 1); this.block = new BlockCacher(0, 0, core._WIDTH_, 1);
this.type = 'absolute'; this.type = 'absolute';
@ -386,6 +386,7 @@ export class Damage extends Sprite {
* @param camera * @param camera
*/ */
renderDamage(camera: Camera) { renderDamage(camera: Camera) {
console.time('damage');
const { ctx } = this.damageMap; const { ctx } = this.damageMap;
ctx.save(); ctx.save();
transformCanvas(this.damageMap, camera, true); transformCanvas(this.damageMap, camera, true);
@ -401,6 +402,7 @@ export class Damage extends Sprite {
const px = bx * cell; const px = bx * cell;
const py = by * cell; const py = by * cell;
// todo: 是否真的需要缓存
// 检查有没有缓存 // 检查有没有缓存
const cache = block.cache.get(v * block.cacheDepth); const cache = block.cache.get(v * block.cacheDepth);
if (cache) { if (cache) {
@ -408,7 +410,6 @@ export class Damage extends Sprite {
return; return;
} }
console.time('damage1');
// 否则依次渲染并写入缓存 // 否则依次渲染并写入缓存
const temp = new MotaOffscreenCanvas2D(); const temp = new MotaOffscreenCanvas2D();
temp.setHD(true); temp.setHD(true);
@ -416,9 +417,7 @@ export class Damage extends Sprite {
temp.withGameScale(true); temp.withGameScale(true);
temp.size(size, size); temp.size(size, size);
const { ctx: ct } = temp; const { ctx: ct } = temp;
console.timeEnd('damage1');
console.time('damage2');
const render = this.renderable.get(v); const render = this.renderable.get(v);
render?.forEach(v => { render?.forEach(v => {
if (!v) return; if (!v) return;
@ -431,13 +430,11 @@ export class Damage extends Sprite {
ct.strokeText(v.text, v.x, v.y); ct.strokeText(v.text, v.x, v.y);
ct.fillText(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); ctx.drawImage(temp.canvas, px, py, size, size);
block.cache.set(v, temp.canvas); block.cache.set(v, temp.canvas);
console.timeEnd('damage3');
}); });
ctx.restore(); ctx.restore();
console.timeEnd('damage');
} }
} }

View File

@ -103,7 +103,7 @@ export class LayerGroup extends Container {
private extend: Map<string, ILayerGroupRenderExtends> = new Map(); private extend: Map<string, ILayerGroupRenderExtends> = new Map();
constructor() { constructor() {
super(); super('static', false);
this.setHD(true); this.setHD(true);
this.setAntiAliasing(false); this.setAntiAliasing(false);
@ -831,7 +831,7 @@ export class Layer extends Container {
private extend: Map<string, ILayerRenderExtends> = new Map(); private extend: Map<string, ILayerRenderExtends> = new Map();
constructor() { constructor() {
super('absolute'); super('absolute', false);
// this.setHD(false); // this.setHD(false);
this.setAntiAliasing(false); this.setAntiAliasing(false);

View File

@ -89,7 +89,7 @@ export class MotaRenderer extends Container {
ctx.imageSmoothingEnabled = true; ctx.imageSmoothingEnabled = true;
ct.imageSmoothingEnabled = true; ct.imageSmoothingEnabled = true;
} }
v.render(ca, ct, camera); v.render(this.target, camera);
ct.restore(); ct.restore();
}); });
}); });

View File

@ -3,6 +3,7 @@ import {
ICanvasCachedRenderItem, ICanvasCachedRenderItem,
RenderFunction, RenderFunction,
RenderItem, RenderItem,
RenderItemPosition,
withCacheRender withCacheRender
} from './item'; } from './item';
import { MotaOffscreenCanvas2D } from '../fx/canvas2d'; import { MotaOffscreenCanvas2D } from '../fx/canvas2d';
@ -12,26 +13,35 @@ export class Sprite extends RenderItem implements ICanvasCachedRenderItem {
canvas: MotaOffscreenCanvas2D; canvas: MotaOffscreenCanvas2D;
constructor() { private readonly enableCache: boolean;
/**
*
* @param type absolute表示绝对位置static表示跟随摄像机移动
* @param cache
*/
constructor(type: RenderItemPosition = 'static', cache: boolean = true) {
super(); super();
this.type = type;
this.enableCache = cache;
this.renderFn = () => {}; this.renderFn = () => {};
this.canvas = new MotaOffscreenCanvas2D(); this.canvas = new MotaOffscreenCanvas2D();
this.canvas.withGameScale(true); this.canvas.withGameScale(true);
} }
render( render(canvas: MotaOffscreenCanvas2D, camera: Camera): void {
canvas: HTMLCanvasElement,
ctx: CanvasRenderingContext2D,
camera: Camera
): void {
this.emit('beforeRender'); this.emit('beforeRender');
if (this.needUpdate) { if (this.needUpdate) {
this.cache(this.using); this.cache(this.using);
this.needUpdate = false; this.needUpdate = false;
} }
withCacheRender(this, canvas, ctx, camera, canvas => { if (this.enableCache) {
withCacheRender(this, canvas.canvas, canvas.ctx, camera, canvas => {
this.renderFn(canvas, camera); this.renderFn(canvas, camera);
}); });
} else {
this.renderFn(canvas, camera);
}
this.writing = void 0; this.writing = void 0;
this.emit('afterRender'); this.emit('afterRender');
} }