diff --git a/src/core/render/container.ts b/src/core/render/container.ts index 1a02c7b..1000ac2 100644 --- a/src/core/render/container.ts +++ b/src/core/render/container.ts @@ -6,13 +6,15 @@ export class Container extends RenderItem implements IRenderChildable { children: RenderItem[] = []; sortedChildren: RenderItem[] = []; + private needSort: boolean = false; + /** * 创建一个容器,容器中可以包含其他渲染对象 * @param type 渲染模式,absolute表示绝对位置,static表示跟随摄像机移动 * @param cache 是否启用缓存机制 */ constructor(type: RenderItemPosition = 'static', cache: boolean = true) { - super(cache); + super(type, cache); this.type = type; } @@ -21,14 +23,11 @@ export class Container extends RenderItem implements IRenderChildable { transform: Transform ): void { const { ctx } = canvas; + // console.log(ctx.getTransform()); + this.sortedChildren.forEach(v => { if (v.hidden) return; ctx.save(); - if (v.antiAliasing) { - ctx.imageSmoothingEnabled = true; - } else { - ctx.imageSmoothingEnabled = false; - } v.renderContent(canvas, transform); ctx.restore(); }); @@ -41,7 +40,13 @@ export class Container extends RenderItem implements IRenderChildable { appendChild(...children: RenderItem[]) { children.forEach(v => (v.parent = this)); this.children.push(...children); - this.sortChildren(); + if (!this.needSort) { + this.needSort = true; + this.requestBeforeFrame(() => { + this.needSort = false; + this.sortChildren(); + }); + } this.update(this); } diff --git a/src/core/render/item.ts b/src/core/render/item.ts index 105f18d..edd62e2 100644 --- a/src/core/render/item.ts +++ b/src/core/render/item.ts @@ -178,10 +178,11 @@ export abstract class RenderItem /** 是否启用缓存机制 */ readonly enableCache: boolean = true; - constructor(enableCache: boolean = true) { + constructor(type: RenderItemPosition, enableCache: boolean = true) { super(); this.enableCache = enableCache; + this.type = type; this.cache.withGameScale(true); } @@ -218,27 +219,31 @@ export abstract class RenderItem if (this.hidden) return; this.emit('beforeRender', transform); this.needUpdate = false; - const tran = transform.multiply(this.transform); + const tran = this.transform; + const ax = -this.anchorX * this.width; const ay = -this.anchorY * this.height; + + canvas.ctx.save(); + canvas.setAntiAliasing(this.antiAliasing); + if (this.type === 'static') transformCanvas(canvas, tran); if (this.enableCache) { + const { width, height, ctx } = this.cache; if (this.cacheDirty) { - const cache = this.cache; - this.render(cache, tran); - this.cache = cache; + const { canvas } = this.cache; + ctx.clearRect(0, 0, canvas.width, canvas.height); + ctx.save(); + this.render(this.cache, tran); + ctx.restore(); this.cacheDirty = false; } - canvas.ctx.save(); - if (this.type === 'static') transformCanvas(canvas, tran); - canvas.ctx.drawImage(this.cache.canvas, ax, ay); - canvas.ctx.restore(); + canvas.ctx.drawImage(this.cache.canvas, ax, ay, width, height); } else { - canvas.ctx.save(); - if (this.type === 'static') transformCanvas(canvas, tran); + canvas.ctx.translate(ax, ay); this.render(canvas, tran); - canvas.ctx.restore(); } + canvas.ctx.restore(); this.emit('afterRender', transform); } @@ -430,20 +435,10 @@ Mota.require('var', 'hook').once('reset', () => { export function transformCanvas( canvas: MotaOffscreenCanvas2D, - transform: Transform, - clear: boolean = false + transform: Transform ) { - const { canvas: ca, ctx, scale } = canvas; + const { ctx } = canvas; const mat = transform.mat; - const a = mat[0] * scale; - const b = mat[1] * scale; - const c = mat[3] * scale; - const d = mat[4] * scale; - const e = mat[6] * scale; - const f = mat[7] * scale; - ctx.setTransform(1, 0, 0, 1, 0, 0); - if (clear) { - ctx.clearRect(0, 0, ca.width, ca.height); - } + const [a, b, , c, d, , e, f] = mat; ctx.transform(a, b, c, d, e, f); } diff --git a/src/core/render/preset/damage.ts b/src/core/render/preset/damage.ts index 76ce1e4..1911062 100644 --- a/src/core/render/preset/damage.ts +++ b/src/core/render/preset/damage.ts @@ -62,6 +62,10 @@ export class FloorDamageExtends private onUpdate = (floor: FloorIds) => { this.sprite.requestBeforeFrame(() => { + if (!this.floorBinder.bindThisFloor) { + ensureFloorDamage(floor); + core.status.maps[floor].enemy.calRealAttribute(); + } this.update(floor); }); }; @@ -71,6 +75,9 @@ export class FloorDamageExtends if (floor !== this.sprite.enemy?.floorId) return; this.sprite.updateEnemyOn(x, y); }); + if (!this.floorBinder.bindThisFloor) { + this.sprite.enemy?.extract(); + } }; /** @@ -169,10 +176,9 @@ export class Damage extends Sprite { this.setRenderFn((canvas, camera) => { const { ctx } = canvas; - const { width, height } = canvas.canvas; + const { width, height } = canvas; ctx.imageSmoothingEnabled = false; this.renderDamage(camera); - ctx.setTransform(1, 0, 0, 1, 0, 0); ctx.drawImage(this.damageMap.canvas, 0, 0, width, height); }); } @@ -415,7 +421,8 @@ export class Damage extends Sprite { // console.time('damage'); const { ctx } = this.damageMap; ctx.save(); - transformCanvas(this.damageMap, transform, true); + this.damageMap.clear(); + transformCanvas(this.damageMap, transform); const { res: render } = this.calNeedRender(transform); const block = this.block; diff --git a/src/core/render/preset/floor.ts b/src/core/render/preset/floor.ts index 95f2f18..4d8f44a 100644 --- a/src/core/render/preset/floor.ts +++ b/src/core/render/preset/floor.ts @@ -70,6 +70,7 @@ export class LayerGroupFloorBinder bindThis() { this.floor = void 0; this.bindThisFloor = true; + this.layerBinders.forEach(v => v.bindThis()); this.updateBind(); } @@ -80,6 +81,7 @@ export class LayerGroupFloorBinder bindFloor(floorId: FloorIds) { this.bindThisFloor = false; this.floor = floorId; + this.layerBinders.forEach(v => v.bindFloor(floorId)); this.updateBind(); } @@ -103,7 +105,7 @@ export class LayerGroupFloorBinder v.updateBindData(); }); - const floor = this.bindThisFloor ? core.status.floorId : this.floor!; + const floor = this.getFloor(); this.emit('update', floor); } @@ -121,8 +123,6 @@ export class LayerGroupFloorBinder if (!ex) return; ex.setBlock(block, x, y); - console.log(block, x, y); - const floor = this.bindThisFloor ? core.status.floorId : this.floor!; this.emit('setBlock', x, y, floor, block); } @@ -202,6 +202,10 @@ export class LayerFloorBinder implements ILayerRenderExtends { this.updateBind(); } + getFloor() { + return this.bindThisFloor ? core.status.floorId : this.floor!; + } + /** * 设置这个拓展附属至的父拓展(LayerGroupFloorBinder拓展) * @param parent 父拓展 @@ -239,7 +243,7 @@ export class LayerFloorBinder implements ILayerRenderExtends { * 立刻更新绑定数据,而非下一帧 */ updateBindData() { - const floor = this.bindThisFloor ? core.status.floorId : this.floor; + const floor = this.getFloor(); if (!floor) return; core.extractBlocks(floor); const map = core.status.maps[floor]; @@ -276,3 +280,13 @@ export class LayerFloorBinder implements ILayerRenderExtends { this.parent?.layerBinders.delete(this); } } + +export class LayerOpenDoorAnimate implements ILayerRenderExtends { + id: string = 'open-door-animate'; + + layer!: Layer; + + awake(layer: Layer) { + this.layer = layer; + } +} diff --git a/src/core/render/preset/layer.ts b/src/core/render/preset/layer.ts index 4f835d2..259cd75 100644 --- a/src/core/render/preset/layer.ts +++ b/src/core/render/preset/layer.ts @@ -668,11 +668,9 @@ export class Layer extends Container { this.appendChild(this.main); this.main.setRenderFn((canvas, transform) => { const { ctx } = canvas; - const { width, height } = canvas.canvas; - ctx.imageSmoothingEnabled = false; + const { width, height } = canvas; const need = this.calNeedRender(transform); this.renderMap(transform, need); - ctx.setTransform(1, 0, 0, 1, 0, 0); ctx.drawImage(this.backMap.canvas, 0, 0, width, height); ctx.drawImage(this.staticMap.canvas, 0, 0, width, height); ctx.drawImage(this.movingMap.canvas, 0, 0, width, height); @@ -1096,6 +1094,7 @@ export class Layer extends Container { for (const ex of this.extend.values()) { ex.onBeforeRender?.(this, transform, need); } + this.renderBack(transform, need); this.renderStatic(transform, need); this.renderMoving(transform); @@ -1118,8 +1117,7 @@ export class Layer extends Container { const mat = transform.mat; const [a, b, , c, d, , e, f] = mat; - ctx.setTransform(1, 0, 0, 1, 0, 0); - ctx.transform(a, b, c, d, e, f); + ctx.setTransform(a, b, c, d, e, f); if (this.background !== 0) { // 画背景图 @@ -1153,8 +1151,7 @@ export class Layer extends Container { const { res: render } = need; const [a, b, , c, d, , e, f] = transform.mat; - ctx.setTransform(1, 0, 0, 1, 0, 0); - ctx.transform(a, b, c, d, e, f); + ctx.setTransform(a, b, c, d, e, f); render.forEach(v => { const x = v % width; @@ -1235,8 +1232,7 @@ export class Layer extends Container { ctx.save(); const mat = transform.mat; const [a, b, , c, d, , e, f] = mat; - ctx.setTransform(1, 0, 0, 1, 0, 0); - ctx.transform(a, b, c, d, e, f); + ctx.setTransform(a, b, c, d, e, f); const max1 = Math.max(a, b, c, d) ** 2; const max2 = Math.max(core._PX_, core._PY_) * 2; const r = (max1 * max2) ** 2; diff --git a/src/core/render/preset/misc.ts b/src/core/render/preset/misc.ts index 447ba08..cc723d1 100644 --- a/src/core/render/preset/misc.ts +++ b/src/core/render/preset/misc.ts @@ -17,7 +17,7 @@ export class Text extends Sprite { private static measureCanvas = new MotaOffscreenCanvas2D(); constructor(text: string = '') { - super(); + super('static', false); this.text = text; if (text.length > 0) this.calBox(); diff --git a/src/core/render/render.ts b/src/core/render/render.ts index 6253dfe..33bcaae 100644 --- a/src/core/render/render.ts +++ b/src/core/render/render.ts @@ -1,4 +1,4 @@ -import { Animation, hyper, sleep } from 'mutate-animate'; +import { Animation, hyper, linear, sleep } from 'mutate-animate'; import { MotaCanvas2D, MotaOffscreenCanvas2D } from '../fx/canvas2d'; import { Container } from './container'; import { RenderItem, transformCanvas } from './item'; @@ -6,6 +6,8 @@ import { FloorLayer, Layer, LayerGroup } from './preset/layer'; import { LayerGroupFloorBinder } from './preset/floor'; import { FloorDamageExtends } from './preset/damage'; import { HeroRenderer } from './preset/hero'; +import { Transform } from './transform'; +import { Text } from './preset/misc'; export class MotaRenderer extends Container { static list: Set = new Set(); @@ -27,66 +29,12 @@ export class MotaRenderer extends Container { this.target.size(core._PX_, core._PY_); this.target.css(`z-index: 100`); + this.setAnchor(0.5, 0.5); + this.transform.move(240, 240); + MotaRenderer.list.add(this); } - /** - * 使用某个摄像机 - * @param camera 要使用的摄像机 - * @param noCache 是否不使用缓存,当切换至的目标摄像机相比切走时发生了例如位置的变化时,一般需要设置为true, - * 否则会使用上一次被切换走时的缓存 - */ - // useCamera(camera: Camera, noCache: boolean = false) { - // const cache = MotaOffscreenCanvas2D.clone(this.canvas); - // this.cameraCache.set(this.camera, cache); - // this.camera = camera; - // const nowCache = this.cameraCache.get(camera); - // if (!nowCache || !noCache) this.render(); - // else this.renderCache(nowCache); - // } - - /** - * 删除某个摄像机的画面缓存 - * @param camera 要删除的缓存对应的摄像机 - */ - // freeCameraCache(camera: Camera) { - // this.cameraCache.delete(camera); - // } - - /** - * 渲染游戏画面 - */ - // protected render(canvas: MotaOffscreenCanvas2D, transform: Transform) { - // console.time(); - // const { canvas, ctx } = this.target; - // const camera = this.camera; - // this.emit('beforeRender', camera); - // ctx.clearRect(0, 0, canvas.width, canvas.height); - // withCacheRender(this, canvas, ctx, camera, canvas => { - // const { canvas: ca, ctx: ct, scale } = canvas; - // this.sortedChildren.forEach(v => { - // if (v.hidden) return; - // if (v.type === 'absolute') { - // ct.setTransform(scale, 0, 0, scale, 0, 0); - // } else { - // transformCanvas(canvas, camera, false); - // } - // ct.save(); - // if (!v.antiAliasing) { - // ctx.imageSmoothingEnabled = false; - // ct.imageSmoothingEnabled = false; - // } else { - // ctx.imageSmoothingEnabled = true; - // ct.imageSmoothingEnabled = true; - // } - // v.renderContent(this.target, camera); - // ct.restore(); - // }); - // }); - // this.emit('afterRender', camera); - // console.timeEnd(); - // } - update(item?: RenderItem) { if (this.needUpdate) return; this.needUpdate = true; @@ -99,7 +47,8 @@ export class MotaRenderer extends Container { protected refresh(item?: RenderItem): void { this.emit('beforeUpdate', item); // console.time(); - this.render(this.target, this.transform); + this.target.clear(); + this.renderContent(this.target, Transform.identity); // console.timeEnd(); this.emit('afterUpdate', item); } @@ -143,19 +92,6 @@ Mota.require('var', 'hook').once('reset', () => { layer.requestAfterFrame(() => { hero.setImage(core.material.images.images['hero2.png']); }); - // hero.readyMove(); - // layer.delegateTicker( - // () => { - // hero.move('right'); - // }, - // 10000, - // () => { - // hero.endMove(); - // } - // ); - - transform.move(240, 240); - render.update(); console.log(render); }); diff --git a/src/core/render/sprite.ts b/src/core/render/sprite.ts index f1defda..e7b0936 100644 --- a/src/core/render/sprite.ts +++ b/src/core/render/sprite.ts @@ -20,7 +20,7 @@ export class Sprite extends RenderItem< * @param cache 是否启用缓存机制 */ constructor(type: RenderItemPosition = 'static', cache: boolean = true) { - super(cache); + super(type, cache); this.type = type; this.renderFn = () => {}; } diff --git a/src/core/render/transform.ts b/src/core/render/transform.ts index 7e7cbd9..e5efab8 100644 --- a/src/core/render/transform.ts +++ b/src/core/render/transform.ts @@ -39,7 +39,7 @@ export class Transform { * 移动,叠加关系 */ move(x: number, y: number) { - mat3.translate(this.mat, this.mat, [-x, -y]); + mat3.translate(this.mat, this.mat, [x, y]); this.x += x; this.y += y; this.modified = true; @@ -72,7 +72,7 @@ export class Transform { * 设置位置,非叠加关系 */ setTranslate(x: number, y: number) { - mat3.translate(this.mat, this.mat, [this.x - x, this.y - y]); + mat3.translate(this.mat, this.mat, [x - this.x, y - this.y]); this.x = x; this.y = y; this.modified = true;