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,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');
}

View File

@ -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);
}
/**
*
*/

View File

@ -135,7 +135,7 @@ export class Damage extends Sprite {
private needUpdateBlocks: Set<number> = 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');
}
}

View File

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

View File

@ -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();
});
});

View File

@ -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');
}