fix: 显伤

This commit is contained in:
unanmed 2024-08-28 22:35:46 +08:00
parent 12c009dab6
commit a19656e7c1
8 changed files with 179 additions and 206 deletions

View File

@ -71,13 +71,13 @@ export class FloorDamageExtends
};
private onSetBlock = (x: number, y: number, floor: FloorIds) => {
this.sprite.enemy?.once('extract', () => {
if (floor !== this.sprite.enemy?.floorId) return;
this.sprite.updateEnemyOn(x, y);
});
if (!this.floorBinder.bindThisFloor) {
this.sprite.enemy?.extract();
}
// this.sprite.enemy?.once('extract', () => {
// if (floor !== this.sprite.enemy?.floorId) return;
// this.sprite.updateBlocks();
// });
// if (!this.floorBinder.bindThisFloor) {
// this.sprite.enemy?.extract();
// }
};
/**
@ -131,6 +131,7 @@ interface EDamageEvent extends ESpriteEvent {
setMapSize: [width: number, height: number];
beforeDamageRender: [need: Set<number>, transform: Transform];
updateBlocks: [blocks: Set<number>];
dirtyUpdate: [block: number];
}
export class Damage extends Sprite<EDamageEvent> {
@ -182,6 +183,10 @@ export class Damage extends Sprite<EDamageEvent> {
});
}
private onExtract = () => {
if (this.enemy) this.updateCollection(this.enemy);
};
/**
*
*/
@ -210,7 +215,10 @@ export class Damage extends Sprite<EDamageEvent> {
* @param enemy
*/
updateCollection(enemy: EnemyCollection) {
if (this.enemy === enemy) return;
if (this.enemy !== enemy) {
this.enemy?.off('calculated', this.onExtract);
enemy.on('calculated', this.onExtract);
}
this.enemy = enemy;
this.blockData.forEach(v => v.clear());
this.renderable.forEach(v => v.clear());
@ -297,6 +305,7 @@ export class Damage extends Sprite<EDamageEvent> {
this.block.clearCache(block, 1);
const renderable = this.renderable.get(block)!;
renderable.clear();
data.forEach(v => this.extract(v, renderable));
if (map) this.extractMapDamage(block, renderable);
@ -313,6 +322,7 @@ export class Damage extends Sprite<EDamageEvent> {
const y = enemy.y!;
const { damage } = enemy.calDamage();
const cri = enemy.calCritical(1)[0]?.atkDelta ?? Infinity;
const dam1: DamageRenderable = {
align: 'left',
baseline: 'alphabetic',
@ -449,6 +459,7 @@ export class Damage extends Sprite<EDamageEvent> {
ctx.drawImage(cache.canvas.canvas, px, py, size, size);
return;
}
this.emit('dirtyUpdate', v);
// 否则依次渲染并写入缓存
const temp = cache?.canvas ?? new MotaOffscreenCanvas2D();
@ -481,4 +492,11 @@ export class Damage extends Sprite<EDamageEvent> {
ctx.restore();
// console.timeEnd('damage');
}
destroy(): void {
super.destroy();
this.enemy?.off('extract', this.onExtract);
}
}
// const adapter = new RenderAdapter<Damage>('damage');

View File

@ -1268,7 +1268,7 @@ export class Layer extends Container {
this.movingRenderable.forEach(v => {
const { x, y, image, render, animate } = v;
const ff = frame % 4;
const ff = frame % v.frame;
const i = animate === -1 ? ff : animate;
const [sx, sy, w, h] = render[i];
const px = x * cell - w / 2 + halfCell;
@ -1350,11 +1350,12 @@ export class Layer extends Container {
y: number,
fn: TimingFn<3>,
time: number,
keep: boolean = false,
relative: boolean = true
): Promise<void> {
const block = this.renderData[index];
const fx = index % this.width;
const fy = Math.floor(index / this.width);
const fx = index % this.mapWidth;
const fy = Math.floor(index / this.mapWidth);
const moving = Layer.getMovingRenderable(block, fx, fy);
if (!moving) return Promise.reject();
@ -1385,7 +1386,7 @@ export class Layer extends Container {
},
time,
() => {
this.putRenderData([block], 1, x, y);
if (keep) this.putRenderData([block], 1, x, y);
this.moving.delete(moving);
resolve();
}

View File

@ -98,6 +98,7 @@ specialValue
interface EnemyCollectionEvent {
extract: [];
calculated: [];
}
export class EnemyCollection
@ -225,121 +226,121 @@ export class EnemyCollection
});
}
render(onMap: boolean = false, cal: boolean = false) {
if (cal) {
this.calMapDamage();
}
core.status.damage.data = [];
core.status.damage.extraData = [];
core.status.damage.dir = [];
// render(onMap: boolean = false, cal: boolean = false) {
// if (cal) {
// this.calMapDamage();
// }
// core.status.damage.data = [];
// core.status.damage.extraData = [];
// core.status.damage.dir = [];
// 怪物伤害
this.list.forEach(v => {
if (onMap && !checkV2(v.x, v.y)) return;
// // 怪物伤害
// this.list.forEach(v => {
// if (onMap && !checkV2(v.x, v.y)) return;
const { damage } = v.calDamage();
// const { damage } = v.calDamage();
// 伤害全部相等,绘制在怪物本身所在位置
const { damage: dam, color } = formatDamage(damage);
const critical = v.calCritical(1)[0];
core.status.damage.data.push({
text: dam,
px: 32 * v.x! + 1,
py: 32 * (v.y! + 1) - 1,
color: color
});
const setting = Mota.require('var', 'mainSetting');
const criGem = setting.getValue('screen.criticalGem', false);
const n = critical?.atkDelta ?? Infinity;
const ratio = core.status.maps[this.floorId].ratio;
const cri = criGem ? Math.ceil(n / ratio) : n;
// // 伤害全部相等,绘制在怪物本身所在位置
// const { damage: dam, color } = formatDamage(damage);
// const critical = v.calCritical(1)[0];
// core.status.damage.data.push({
// text: dam,
// px: 32 * v.x! + 1,
// py: 32 * (v.y! + 1) - 1,
// color: color
// });
// const setting = Mota.require('var', 'mainSetting');
// const criGem = setting.getValue('screen.criticalGem', false);
// const n = critical?.atkDelta ?? Infinity;
// const ratio = core.status.maps[this.floorId].ratio;
// const cri = criGem ? Math.ceil(n / ratio) : n;
core.status.damage.data.push({
text: isFinite(cri) ? cri.toString() : '?',
px: 32 * v.x! + 1,
py: 32 * (v.y! + 1) - 11,
color: '#fff'
});
});
// core.status.damage.data.push({
// text: isFinite(cri) ? cri.toString() : '?',
// px: 32 * v.x! + 1,
// py: 32 * (v.y! + 1) - 11,
// color: '#fff'
// });
// });
// 地图伤害
const floor = core.status.maps[this.floorId];
const width = floor.width;
const height = floor.height;
const objs = core.getMapBlocksObj(this.floorId);
// // 地图伤害
// const floor = core.status.maps[this.floorId];
// const width = floor.width;
// const height = floor.height;
// const objs = core.getMapBlocksObj(this.floorId);
const startX =
onMap && core.bigmap.v2
? Math.max(0, core.bigmap.posX - core.bigmap.extend)
: 0;
const endX =
onMap && core.bigmap.v2
? Math.min(
width,
core.bigmap.posX + core._WIDTH_ + core.bigmap.extend + 1
)
: width;
const startY =
onMap && core.bigmap.v2
? Math.max(0, core.bigmap.posY - core.bigmap.extend)
: 0;
const endY =
onMap && core.bigmap.v2
? Math.min(
height,
core.bigmap.posY + core._HEIGHT_ + core.bigmap.extend + 1
)
: height;
// const startX =
// onMap && core.bigmap.v2
// ? Math.max(0, core.bigmap.posX - core.bigmap.extend)
// : 0;
// const endX =
// onMap && core.bigmap.v2
// ? Math.min(
// width,
// core.bigmap.posX + core._WIDTH_ + core.bigmap.extend + 1
// )
// : width;
// const startY =
// onMap && core.bigmap.v2
// ? Math.max(0, core.bigmap.posY - core.bigmap.extend)
// : 0;
// const endY =
// onMap && core.bigmap.v2
// ? Math.min(
// height,
// core.bigmap.posY + core._HEIGHT_ + core.bigmap.extend + 1
// )
// : height;
for (let x = startX; x < endX; x++) {
for (let y = startY; y < endY; y++) {
const id = `${x},${y}` as LocString;
const dam = this.mapDamage[id];
if (!dam || objs[id]?.event.noPass) continue;
// for (let x = startX; x < endX; x++) {
// for (let y = startY; y < endY; y++) {
// const id = `${x},${y}` as LocString;
// const dam = this.mapDamage[id];
// if (!dam || objs[id]?.event.noPass) continue;
// 地图伤害
if (dam.damage !== 0) {
const damage = core.formatBigNumber(dam.damage, true);
const color = dam.damage < 0 ? '#6eff6a' : '#fa3';
core.status.damage.extraData.push({
text: damage,
px: 32 * x + 16,
py: 32 * y + 16,
color,
alpha: 1
});
}
// // 地图伤害
// if (dam.damage !== 0) {
// const damage = core.formatBigNumber(dam.damage, true);
// const color = dam.damage < 0 ? '#6eff6a' : '#fa3';
// core.status.damage.extraData.push({
// text: damage,
// px: 32 * x + 16,
// py: 32 * y + 16,
// color,
// alpha: 1
// });
// }
// 电摇嘲讽
if (dam.mockery) {
dam.mockery.sort((a, b) =>
a[0] === b[0] ? a[1] - b[1] : a[0] - b[0]
);
const [tx, ty] = dam.mockery[0];
const dir =
x > tx ? '←' : x < tx ? '→' : y > ty ? '↑' : '↓';
core.status.damage.extraData.push({
text: '嘲' + dir,
px: 32 * x + 16,
py: 32 * (y + 1) - 14,
color: '#fd4',
alpha: 1
});
}
// // 电摇嘲讽
// if (dam.mockery) {
// dam.mockery.sort((a, b) =>
// a[0] === b[0] ? a[1] - b[1] : a[0] - b[0]
// );
// const [tx, ty] = dam.mockery[0];
// const dir =
// x > tx ? '←' : x < tx ? '→' : y > ty ? '↑' : '↓';
// core.status.damage.extraData.push({
// text: '嘲' + dir,
// px: 32 * x + 16,
// py: 32 * (y + 1) - 14,
// color: '#fd4',
// alpha: 1
// });
// }
// 追猎
if (dam.hunt) {
core.status.damage.extraData.push({
text: '猎',
px: 32 * x + 16,
py: 32 * (y + 1) - 14,
color: '#fd4',
alpha: 1
});
}
}
}
}
// // 追猎
// if (dam.hunt) {
// core.status.damage.extraData.push({
// text: '猎',
// px: 32 * x + 16,
// py: 32 * (y + 1) - 14,
// color: '#fd4',
// alpha: 1
// });
// }
// }
// }
// }
}
export class DamageEnemy<T extends EnemyIds = EnemyIds> {

View File

@ -62,14 +62,12 @@ export class FloorItemDetail implements ILayerGroupRenderExtends {
static listened: Set<FloorItemDetail> = new Set();
private onBeforeDamageRender = (need: Set<number>) => {
private onBeforeDamageRender = (block: number) => {
if (!mainSetting.getValue('screen.itemDetail')) return;
need.forEach(v => {
if (this.dirtyBlock.has(v)) {
this.sprite.block.clearCache(v, 1);
}
});
this.render(need);
if (this.dirtyBlock.has(block)) {
this.sprite.block.clearCache(block, 1);
this.render(block);
}
};
private onUpdateMapSize = (width: number, height: number) => {
@ -87,7 +85,7 @@ export class FloorItemDetail implements ILayerGroupRenderExtends {
};
private listen() {
this.sprite.on('beforeDamageRender', this.onBeforeDamageRender);
this.sprite.on('dirtyUpdate', this.onBeforeDamageRender);
this.sprite.on('setMapSize', this.onUpdateMapSize);
this.sprite.on('updateBlocks', this.onUpdateBlocks);
this.damage.on('update', this.onUpdate);
@ -215,32 +213,32 @@ export class FloorItemDetail implements ILayerGroupRenderExtends {
*
* @param block
*/
render(block: Set<number>) {
this.calAllItems(block);
render(block: number) {
this.calAllItems(new Set([block]));
const data = this.detailData;
block.forEach(v => {
if (!this.dirtyBlock.has(v)) return;
this.dirtyBlock.delete(v);
const info = data.get(v);
if (!info) return;
info.forEach(({ x, y, diff }) => {
let n = 0;
for (const [key, value] of Object.entries(diff)) {
if (!value) continue;
const color = FloorItemDetail.detailColor[key] ?? '#fff';
const text = value.toString();
const renderable: DamageRenderable = {
x: x * this.sprite.cellSize + 2,
y: y * this.sprite.cellSize + 31 - n * 10,
text,
color,
align: 'left',
baseline: 'alphabetic'
};
this.sprite.renderable.get(v)?.add(renderable);
n++;
}
});
if (!this.dirtyBlock.has(block)) return;
this.dirtyBlock.delete(block);
const info = data.get(block);
if (!info) return;
info.forEach(({ x, y, diff }) => {
let n = 0;
for (const [key, value] of Object.entries(diff)) {
if (!value) continue;
const color = FloorItemDetail.detailColor[key] ?? '#fff';
const text = value.toString();
const renderable: DamageRenderable = {
x: x * this.sprite.cellSize + 2,
y: y * this.sprite.cellSize + 31 - n * 10,
text,
color,
align: 'left',
baseline: 'alphabetic'
};
this.sprite.renderable.get(block)?.add(renderable);
n++;
}
});
}

View File

@ -100,7 +100,9 @@ export class Portal extends Sprite {
this.particleSetting = mainSetting.getSetting('fx.portalParticle')!;
this.delegation = this.delegateTicker(() => {
if (this.particleSetting.value) this.update(this);
if (this.particleSetting.value && this.renderable.size > 0) {
this.update(this);
}
});
this.setRenderFn((canvas, transform) => {

View File

@ -37,56 +37,6 @@ export function init() {
checkMockery(loc, forceMockery);
checkHunt(loc);
};
control.prototype._drawDamage_draw = function (
ctx: CanvasRenderingContext2D,
onMap: boolean,
floorId: FloorIds
) {
if (!core.hasItem('book')) return;
drawHalo(ctx, onMap, floorId);
core.setFont(ctx, "14px 'normal'");
core.setTextAlign(ctx, 'center');
core.setTextBaseline(ctx, 'middle');
core.status.damage.extraData.forEach(function (one) {
var px = one.px,
py = one.py;
if (onMap && core.bigmap.v2) {
px -= core.bigmap.posX * 32;
py -= core.bigmap.posY * 32;
if (
px < -32 ||
px > core._PX_ + 32 ||
py < -32 ||
py > core._PY_ + 32
)
return;
}
var alpha = core.setAlpha(ctx, one.alpha);
core.fillBoldText(ctx, one.text, px, py, one.color as string);
core.setAlpha(ctx, alpha);
});
core.setTextAlign(ctx, 'left');
core.setTextBaseline(ctx, 'alphabetic');
core.status.damage.data.forEach(function (one) {
var px = one.px,
py = one.py;
if (onMap && core.bigmap.v2) {
px -= core.bigmap.posX * 32;
py -= core.bigmap.posY * 32;
if (
px < -32 * 2 ||
px > core._PX_ + 32 ||
py < -32 ||
py > core._PY_ + 32
)
return;
}
core.fillBoldText(ctx, one.text, px, py, one.color as string);
});
};
}
function checkMockery(loc: string, force: boolean = false) {

View File

@ -420,11 +420,11 @@ export function init() {
function generateJumpFn(dx: number, dy: number): TimingFn<3> {
const distance = Math.hypot(dx, dy);
const peak = 3 + distance;
const k = dy / dx;
return (progress: number) => {
const x = dx * progress;
const y = k * x + (progress ** 2 - progress) * peak;
const y = progress * dy + (progress ** 2 - progress) * peak;
return [x, y, Math.ceil(y)];
};
}
@ -766,15 +766,17 @@ export function init() {
const promise = Promise.all(
items.map(v => {
return v.moveAs(index, ex, ey, fn, time);
return v.moveAs(index, ex, ey, fn, time, keep);
})
);
core.updateStatusBar();
core.removeBlock(sx, sy);
await promise;
if (keep) {
core.setBlock(block.id, ex, ey);
}
core.updateStatusBar();
callback?.();
};

View File

@ -22,12 +22,13 @@ export function init() {
floor.enemy.extract();
floor.enemy.calRealAttribute();
floor.enemy.calMapDamage();
floor.enemy.emit('calculated');
core.status.damage.data = [];
floor.enemy.render(true);
// floor.enemy.render(true);
getItemDetail(floorId, onMap); // 宝石血瓶详细信息
this.drawDamage(ctx, floorId);
// this.drawDamage(ctx, floorId);
};
}