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) => { private onSetBlock = (x: number, y: number, floor: FloorIds) => {
this.sprite.enemy?.once('extract', () => { // this.sprite.enemy?.once('extract', () => {
if (floor !== this.sprite.enemy?.floorId) return; // if (floor !== this.sprite.enemy?.floorId) return;
this.sprite.updateEnemyOn(x, y); // this.sprite.updateBlocks();
}); // });
if (!this.floorBinder.bindThisFloor) { // if (!this.floorBinder.bindThisFloor) {
this.sprite.enemy?.extract(); // this.sprite.enemy?.extract();
} // }
}; };
/** /**
@ -131,6 +131,7 @@ interface EDamageEvent extends ESpriteEvent {
setMapSize: [width: number, height: number]; setMapSize: [width: number, height: number];
beforeDamageRender: [need: Set<number>, transform: Transform]; beforeDamageRender: [need: Set<number>, transform: Transform];
updateBlocks: [blocks: Set<number>]; updateBlocks: [blocks: Set<number>];
dirtyUpdate: [block: number];
} }
export class Damage extends Sprite<EDamageEvent> { 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 * @param enemy
*/ */
updateCollection(enemy: EnemyCollection) { 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.enemy = enemy;
this.blockData.forEach(v => v.clear()); this.blockData.forEach(v => v.clear());
this.renderable.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); this.block.clearCache(block, 1);
const renderable = this.renderable.get(block)!; const renderable = this.renderable.get(block)!;
renderable.clear(); renderable.clear();
data.forEach(v => this.extract(v, renderable)); data.forEach(v => this.extract(v, renderable));
if (map) this.extractMapDamage(block, renderable); if (map) this.extractMapDamage(block, renderable);
@ -313,6 +322,7 @@ export class Damage extends Sprite<EDamageEvent> {
const y = enemy.y!; const y = enemy.y!;
const { damage } = enemy.calDamage(); const { damage } = enemy.calDamage();
const cri = enemy.calCritical(1)[0]?.atkDelta ?? Infinity; const cri = enemy.calCritical(1)[0]?.atkDelta ?? Infinity;
const dam1: DamageRenderable = { const dam1: DamageRenderable = {
align: 'left', align: 'left',
baseline: 'alphabetic', baseline: 'alphabetic',
@ -449,6 +459,7 @@ export class Damage extends Sprite<EDamageEvent> {
ctx.drawImage(cache.canvas.canvas, px, py, size, size); ctx.drawImage(cache.canvas.canvas, px, py, size, size);
return; return;
} }
this.emit('dirtyUpdate', v);
// 否则依次渲染并写入缓存 // 否则依次渲染并写入缓存
const temp = cache?.canvas ?? new MotaOffscreenCanvas2D(); const temp = cache?.canvas ?? new MotaOffscreenCanvas2D();
@ -481,4 +492,11 @@ export class Damage extends Sprite<EDamageEvent> {
ctx.restore(); ctx.restore();
// console.timeEnd('damage'); // 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 => { this.movingRenderable.forEach(v => {
const { x, y, image, render, animate } = v; const { x, y, image, render, animate } = v;
const ff = frame % 4; const ff = frame % v.frame;
const i = animate === -1 ? ff : animate; const i = animate === -1 ? ff : animate;
const [sx, sy, w, h] = render[i]; const [sx, sy, w, h] = render[i];
const px = x * cell - w / 2 + halfCell; const px = x * cell - w / 2 + halfCell;
@ -1350,11 +1350,12 @@ export class Layer extends Container {
y: number, y: number,
fn: TimingFn<3>, fn: TimingFn<3>,
time: number, time: number,
keep: boolean = false,
relative: boolean = true relative: boolean = true
): Promise<void> { ): Promise<void> {
const block = this.renderData[index]; const block = this.renderData[index];
const fx = index % this.width; const fx = index % this.mapWidth;
const fy = Math.floor(index / this.width); const fy = Math.floor(index / this.mapWidth);
const moving = Layer.getMovingRenderable(block, fx, fy); const moving = Layer.getMovingRenderable(block, fx, fy);
if (!moving) return Promise.reject(); if (!moving) return Promise.reject();
@ -1385,7 +1386,7 @@ export class Layer extends Container {
}, },
time, time,
() => { () => {
this.putRenderData([block], 1, x, y); if (keep) this.putRenderData([block], 1, x, y);
this.moving.delete(moving); this.moving.delete(moving);
resolve(); resolve();
} }

View File

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

View File

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

View File

@ -37,56 +37,6 @@ export function init() {
checkMockery(loc, forceMockery); checkMockery(loc, forceMockery);
checkHunt(loc); 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) { function checkMockery(loc: string, force: boolean = false) {

View File

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

View File

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