fix: 模型变换

This commit is contained in:
unanmed 2024-08-23 20:58:23 +08:00
parent 4835b0b367
commit d7dcbe9d04
9 changed files with 77 additions and 124 deletions

View File

@ -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<any>[]) {
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);
}

View File

@ -178,10 +178,11 @@ export abstract class RenderItem<E extends ERenderItemEvent = ERenderItemEvent>
/** 是否启用缓存机制 */
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<E extends ERenderItemEvent = ERenderItemEvent>
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);
}

View File

@ -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<EDamageEvent> {
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<EDamageEvent> {
// 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;

View File

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

View File

@ -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;

View File

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

View File

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

View File

@ -20,7 +20,7 @@ export class Sprite<E extends ESpriteEvent = ESpriteEvent> extends RenderItem<
* @param cache
*/
constructor(type: RenderItemPosition = 'static', cache: boolean = true) {
super(cache);
super(type, cache);
this.type = type;
this.renderFn = () => {};
}

View File

@ -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;