mirror of
https://github.com/unanmed/HumanBreak.git
synced 2025-01-31 23:29:27 +08:00
feat: 宝石血瓶显伤
This commit is contained in:
parent
57760d501e
commit
1c369251b1
@ -69,6 +69,7 @@ import { Image, Text } from './render/preset/misc';
|
|||||||
import { RenderItem } from './render/item';
|
import { RenderItem } from './render/item';
|
||||||
import { texture } from './render/cache';
|
import { texture } from './render/cache';
|
||||||
import { RenderAdapter } from './render/adapter';
|
import { RenderAdapter } from './render/adapter';
|
||||||
|
import { getMainRenderer } from './render';
|
||||||
|
|
||||||
// ----- 类注册
|
// ----- 类注册
|
||||||
Mota.register('class', 'AudioPlayer', AudioPlayer);
|
Mota.register('class', 'AudioPlayer', AudioPlayer);
|
||||||
@ -148,6 +149,7 @@ Mota.register('module', 'Effect', {
|
|||||||
});
|
});
|
||||||
Mota.register('module', 'Render', {
|
Mota.register('module', 'Render', {
|
||||||
texture,
|
texture,
|
||||||
|
getMainRenderer: getMainRenderer,
|
||||||
MotaRenderer,
|
MotaRenderer,
|
||||||
Container,
|
Container,
|
||||||
Sprite,
|
Sprite,
|
||||||
|
42
src/core/render/index.ts
Normal file
42
src/core/render/index.ts
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
import { FloorItemDetail } from '@/plugin/fx/itemDetail';
|
||||||
|
import { FloorDamageExtends } from './preset/damage';
|
||||||
|
import { LayerGroupFloorBinder } from './preset/floor';
|
||||||
|
import { HeroRenderer } from './preset/hero';
|
||||||
|
import { LayerGroup, FloorLayer } from './preset/layer';
|
||||||
|
import { MotaRenderer } from './render';
|
||||||
|
|
||||||
|
let main: MotaRenderer;
|
||||||
|
|
||||||
|
export function getMainRenderer() {
|
||||||
|
return main;
|
||||||
|
}
|
||||||
|
|
||||||
|
Mota.require('var', 'loading').once('loaded', () => {
|
||||||
|
const render = new MotaRenderer();
|
||||||
|
main = render;
|
||||||
|
render.mount();
|
||||||
|
render.hide();
|
||||||
|
|
||||||
|
const layer = new LayerGroup();
|
||||||
|
|
||||||
|
['bg', 'bg2', 'event', 'fg', 'fg2'].forEach(v => {
|
||||||
|
layer.addLayer(v as FloorLayer);
|
||||||
|
});
|
||||||
|
|
||||||
|
const damage = new FloorDamageExtends();
|
||||||
|
const hero = new HeroRenderer();
|
||||||
|
const detail = new FloorItemDetail();
|
||||||
|
layer.extends(damage);
|
||||||
|
layer.extends(detail);
|
||||||
|
layer.getLayer('event')?.extends(hero);
|
||||||
|
|
||||||
|
render.appendChild(layer);
|
||||||
|
});
|
||||||
|
|
||||||
|
Mota.require('var', 'hook').on('reset', () => {
|
||||||
|
main.show();
|
||||||
|
});
|
||||||
|
|
||||||
|
Mota.require('var', 'hook').on('restart', () => {
|
||||||
|
main.hide();
|
||||||
|
});
|
@ -40,7 +40,7 @@ export class FloorDamageExtends
|
|||||||
* 立刻刷新伤害渲染
|
* 立刻刷新伤害渲染
|
||||||
*/
|
*/
|
||||||
update(floor: FloorIds) {
|
update(floor: FloorIds) {
|
||||||
if (!this.sprite) return;
|
if (!this.sprite || !floor) return;
|
||||||
const map = core.status.maps[floor];
|
const map = core.status.maps[floor];
|
||||||
this.sprite.setMapSize(map.width, map.height);
|
this.sprite.setMapSize(map.width, map.height);
|
||||||
ensureFloorDamage(floor);
|
ensureFloorDamage(floor);
|
||||||
@ -89,21 +89,19 @@ export class FloorDamageExtends
|
|||||||
}
|
}
|
||||||
|
|
||||||
awake(group: LayerGroup): void {
|
awake(group: LayerGroup): void {
|
||||||
group.requestBeforeFrame(() => {
|
const ex = group.getExtends('floor-binder');
|
||||||
const ex = group.getExtends('floor-binder');
|
if (ex instanceof LayerGroupFloorBinder) {
|
||||||
if (ex instanceof LayerGroupFloorBinder) {
|
this.floorBinder = ex;
|
||||||
this.floorBinder = ex;
|
this.group = group;
|
||||||
this.group = group;
|
this.create();
|
||||||
this.create();
|
this.listen();
|
||||||
this.listen();
|
} else {
|
||||||
} else {
|
logger.warn(
|
||||||
logger.warn(
|
17,
|
||||||
17,
|
`Floor-damage extends needs 'floor-binder' extends as dependency.`
|
||||||
`Floor-damage extends needs 'floor-binder' extends as dependency.`
|
);
|
||||||
);
|
group.removeExtends('floor-damage');
|
||||||
group.removeExtends('floor-damage');
|
}
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onDestroy(group: LayerGroup): void {
|
onDestroy(group: LayerGroup): void {
|
||||||
@ -132,6 +130,7 @@ interface DamageCache {
|
|||||||
interface EDamageEvent extends ESpriteEvent {
|
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>];
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Damage extends Sprite<EDamageEvent> {
|
export class Damage extends Sprite<EDamageEvent> {
|
||||||
@ -241,13 +240,16 @@ export class Damage extends Sprite<EDamageEvent> {
|
|||||||
/**
|
/**
|
||||||
* 更新指定分块
|
* 更新指定分块
|
||||||
* @param blocks 要更新的分块集合
|
* @param blocks 要更新的分块集合
|
||||||
|
* @param map 是否更新地图伤害
|
||||||
*/
|
*/
|
||||||
updateBlocks(blocks?: Set<number>) {
|
updateBlocks(blocks?: Set<number>, map: boolean = true) {
|
||||||
if (blocks) {
|
if (blocks) {
|
||||||
blocks.forEach(v => this.updateBlock(v));
|
blocks.forEach(v => this.updateBlock(v, map));
|
||||||
|
this.emit('updateBlocks', blocks);
|
||||||
} else {
|
} else {
|
||||||
this.blockData.forEach((_, k) => this.updateBlock(k, false));
|
this.blockData.forEach((_, k) => this.updateBlock(k, false));
|
||||||
this.extractAllMapDamage();
|
if (map) this.extractAllMapDamage();
|
||||||
|
this.emit('updateBlocks', new Set(this.blockData.keys()));
|
||||||
}
|
}
|
||||||
this.update(this);
|
this.update(this);
|
||||||
}
|
}
|
||||||
@ -274,7 +276,9 @@ export class Damage extends Sprite<EDamageEvent> {
|
|||||||
this.needUpdateBlocks.add(block);
|
this.needUpdateBlocks.add(block);
|
||||||
this.requestBeforeFrame(() => {
|
this.requestBeforeFrame(() => {
|
||||||
this.needUpdateBlock = false;
|
this.needUpdateBlock = false;
|
||||||
this.needUpdateBlocks.forEach(v => this.updateBlock(v, false));
|
this.updateBlocks(this.needUpdateBlocks, false);
|
||||||
|
this.needUpdateBlocks.clear();
|
||||||
|
// this.needUpdateBlocks.forEach(v => this.updateBlock(v, false));
|
||||||
// todo: 阻击夹域等地图伤害检测是否必要更新,例如不包含阻击夹域的怪就不必要更新这个怪物信息
|
// todo: 阻击夹域等地图伤害检测是否必要更新,例如不包含阻击夹域的怪就不必要更新这个怪物信息
|
||||||
// this.extractAllMapDamage();
|
// this.extractAllMapDamage();
|
||||||
});
|
});
|
||||||
@ -423,6 +427,7 @@ export class Damage extends Sprite<EDamageEvent> {
|
|||||||
ctx.save();
|
ctx.save();
|
||||||
this.damageMap.clear();
|
this.damageMap.clear();
|
||||||
transformCanvas(this.damageMap, transform);
|
transformCanvas(this.damageMap, transform);
|
||||||
|
// console.trace();
|
||||||
|
|
||||||
const { res: render } = this.calNeedRender(transform);
|
const { res: render } = this.calNeedRender(transform);
|
||||||
const block = this.block;
|
const block = this.block;
|
||||||
|
@ -149,9 +149,9 @@ export class LayerGroupFloorBinder
|
|||||||
LayerGroupFloorBinder.activedBinder.add(this);
|
LayerGroupFloorBinder.activedBinder.add(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
onLayerAdd(group: LayerGroup, layer: Layer): void {
|
// onLayerAdd(group: LayerGroup, layer: Layer): void {
|
||||||
this.checkLayerExtends(layer);
|
// this.checkLayerExtends(layer);
|
||||||
}
|
// }
|
||||||
|
|
||||||
onDestroy(group: LayerGroup) {
|
onDestroy(group: LayerGroup) {
|
||||||
LayerGroupFloorBinder.activedBinder.delete(this);
|
LayerGroupFloorBinder.activedBinder.delete(this);
|
||||||
|
@ -145,7 +145,10 @@ export class HeroRenderer
|
|||||||
*/
|
*/
|
||||||
private moveTick(time: number) {
|
private moveTick(time: number) {
|
||||||
if (this.status !== 'moving') return;
|
if (this.status !== 'moving') return;
|
||||||
if (!this.renderable) return;
|
if (!this.renderable) {
|
||||||
|
this.emit('stepEnd');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (time - this.lastFrameTime > this.speed) {
|
if (time - this.lastFrameTime > this.speed) {
|
||||||
this.lastFrameTime = time;
|
this.lastFrameTime = time;
|
||||||
@ -379,6 +382,10 @@ adapter.recieve('turn', (item, dir: Dir2) => {
|
|||||||
item.turn(dir);
|
item.turn(dir);
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
});
|
});
|
||||||
|
adapter.recieve('setImage', (item, image: SizedCanvasImageSource) => {
|
||||||
|
item.setImage(image);
|
||||||
|
return Promise.resolve();
|
||||||
|
});
|
||||||
// 同步fallback,用于适配现在的样板,之后会删除
|
// 同步fallback,用于适配现在的样板,之后会删除
|
||||||
adapter.recieveSync('setHeroLoc', (item, x?: number, y?: number) => {
|
adapter.recieveSync('setHeroLoc', (item, x?: number, y?: number) => {
|
||||||
item.setHeroLoc(x, y);
|
item.setHeroLoc(x, y);
|
||||||
|
@ -8,6 +8,7 @@ import { RenderableData, texture } from '../cache';
|
|||||||
import { glMatrix } from 'gl-matrix';
|
import { glMatrix } from 'gl-matrix';
|
||||||
import { BlockCacher } from './block';
|
import { BlockCacher } from './block';
|
||||||
import { Transform } from '../transform';
|
import { Transform } from '../transform';
|
||||||
|
import { LayerFloorBinder, LayerGroupFloorBinder } from './floor';
|
||||||
|
|
||||||
export interface ILayerGroupRenderExtends {
|
export interface ILayerGroupRenderExtends {
|
||||||
/** 拓展的唯一标识符 */
|
/** 拓展的唯一标识符 */
|
||||||
@ -60,6 +61,18 @@ export interface ILayerGroupRenderExtends {
|
|||||||
*/
|
*/
|
||||||
onFrameUpdate?(group: LayerGroup, frame: number): void;
|
onFrameUpdate?(group: LayerGroup, frame: number): void;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 在渲染之前执行的函数
|
||||||
|
* @param group 目标LayerGroup实例
|
||||||
|
*/
|
||||||
|
onBeforeRender?(group: LayerGroup): void;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 在渲染之后执行的函数
|
||||||
|
* @param group 目标LayerGroup实例
|
||||||
|
*/
|
||||||
|
onAfterRender?(group: LayerGroup): void;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 当拓展被取消挂载时执行的函数(LayerGroup被销毁,拓展被移除等)
|
* 当拓展被取消挂载时执行的函数(LayerGroup被销毁,拓展被移除等)
|
||||||
* @param group 目标LayerGroup实例
|
* @param group 目标LayerGroup实例
|
||||||
@ -100,6 +113,10 @@ export class LayerGroup extends Container implements IAnimateFrame {
|
|||||||
});
|
});
|
||||||
|
|
||||||
renderEmits.addFramer(this);
|
renderEmits.addFramer(this);
|
||||||
|
|
||||||
|
const binder = new LayerGroupFloorBinder();
|
||||||
|
this.extends(binder);
|
||||||
|
binder.bindThis();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -675,6 +692,8 @@ export class Layer extends Container {
|
|||||||
ctx.drawImage(this.staticMap.canvas, 0, 0, width, height);
|
ctx.drawImage(this.staticMap.canvas, 0, 0, width, height);
|
||||||
ctx.drawImage(this.movingMap.canvas, 0, 0, width, height);
|
ctx.drawImage(this.movingMap.canvas, 0, 0, width, height);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.extends(new LayerFloorBinder());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,14 +1,7 @@
|
|||||||
import { Animation, hyper, linear, sleep } from 'mutate-animate';
|
import { MotaCanvas2D } from '../fx/canvas2d';
|
||||||
import { MotaCanvas2D, MotaOffscreenCanvas2D } from '../fx/canvas2d';
|
|
||||||
import { Container } from './container';
|
import { Container } from './container';
|
||||||
import { RenderItem, transformCanvas } from './item';
|
import { RenderItem } from './item';
|
||||||
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 { Transform } from './transform';
|
||||||
import { Text } from './preset/misc';
|
|
||||||
import { Shader } from './shader';
|
|
||||||
|
|
||||||
export class MotaRenderer extends Container {
|
export class MotaRenderer extends Container {
|
||||||
static list: Set<MotaRenderer> = new Set();
|
static list: Set<MotaRenderer> = new Set();
|
||||||
@ -69,65 +62,3 @@ export class MotaRenderer extends Container {
|
|||||||
window.addEventListener('resize', () => {
|
window.addEventListener('resize', () => {
|
||||||
MotaRenderer.list.forEach(v => v.update(v));
|
MotaRenderer.list.forEach(v => v.update(v));
|
||||||
});
|
});
|
||||||
|
|
||||||
Mota.require('var', 'hook').once('reset', () => {
|
|
||||||
const render = new MotaRenderer();
|
|
||||||
const transform = render.transform;
|
|
||||||
render.mount();
|
|
||||||
|
|
||||||
const ani = new Animation();
|
|
||||||
|
|
||||||
const shader = new Shader();
|
|
||||||
const layer = new LayerGroup();
|
|
||||||
|
|
||||||
['bg', 'bg2', 'event', 'fg', 'fg2'].forEach(v => {
|
|
||||||
layer.addLayer(v as FloorLayer);
|
|
||||||
});
|
|
||||||
|
|
||||||
const binder = new LayerGroupFloorBinder();
|
|
||||||
const damage = new FloorDamageExtends();
|
|
||||||
const hero = new HeroRenderer();
|
|
||||||
layer.extends(binder);
|
|
||||||
layer.extends(damage);
|
|
||||||
layer.getLayer('event')?.extends(hero);
|
|
||||||
binder.bindThis();
|
|
||||||
render.appendChild(shader);
|
|
||||||
shader.appendChild(layer);
|
|
||||||
shader.size(480, 480);
|
|
||||||
shader.fs(`
|
|
||||||
uniform float u_offset;
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
// 计算当前像素到爆炸中心的距离
|
|
||||||
vec2 coordToCenter = v_texCoord - vec2(0.5, 0.5);
|
|
||||||
float distance = length(coordToCenter);
|
|
||||||
|
|
||||||
// 根据时间计算当前距离上的波动相位
|
|
||||||
float wavePhase = 100.0 * (distance - u_offset);
|
|
||||||
|
|
||||||
// 计算波动的强度(正弦波)并结合衰减
|
|
||||||
float wave = sin(wavePhase) * 0.02 / (1.0 + 10.0 * distance);
|
|
||||||
|
|
||||||
// 将波动效果应用到纹理坐标上,造成扭曲
|
|
||||||
vec2 warpedCoords = v_texCoord + normalize(coordToCenter) * wave;
|
|
||||||
|
|
||||||
// 采样纹理并输出颜色
|
|
||||||
gl_FragColor = texture2D(u_sampler, warpedCoords);
|
|
||||||
}
|
|
||||||
`);
|
|
||||||
shader.compileShader();
|
|
||||||
|
|
||||||
const offset = shader.getUniform('u_offset');
|
|
||||||
shader.delegateTicker(() => {
|
|
||||||
shader.gl.uniform1f(offset, ani.value.offset);
|
|
||||||
shader.update();
|
|
||||||
}, 20000);
|
|
||||||
ani.value.offset = 0;
|
|
||||||
ani.mode(linear()).time(10000).absolute().apply('offset', 1);
|
|
||||||
|
|
||||||
layer.requestAfterFrame(() => {
|
|
||||||
hero.setImage(core.material.images.images['hero2.png']);
|
|
||||||
});
|
|
||||||
|
|
||||||
console.log(render);
|
|
||||||
});
|
|
||||||
|
@ -31,7 +31,6 @@ import type { texture } from '@/core/render/cache';
|
|||||||
import type { MotaRenderer } from '@/core/render/render';
|
import type { MotaRenderer } from '@/core/render/render';
|
||||||
import type { Container } from '@/core/render/container';
|
import type { Container } from '@/core/render/container';
|
||||||
import type { Sprite } from '@/core/render/sprite';
|
import type { Sprite } from '@/core/render/sprite';
|
||||||
import type { Camera } from '@/core/render/camera';
|
|
||||||
import type { Image, Text } from '@/core/render/preset/misc';
|
import type { Image, Text } from '@/core/render/preset/misc';
|
||||||
import type { RenderItem } from '@/core/render/item';
|
import type { RenderItem } from '@/core/render/item';
|
||||||
import type { RenderAdapter } from '@/core/render/adapter';
|
import type { RenderAdapter } from '@/core/render/adapter';
|
||||||
@ -107,10 +106,10 @@ interface ModuleInterface {
|
|||||||
};
|
};
|
||||||
Render: {
|
Render: {
|
||||||
texture: typeof texture;
|
texture: typeof texture;
|
||||||
|
main: MotaRenderer;
|
||||||
MotaRenderer: typeof MotaRenderer;
|
MotaRenderer: typeof MotaRenderer;
|
||||||
Container: typeof Container;
|
Container: typeof Container;
|
||||||
Sprite: typeof Sprite;
|
Sprite: typeof Sprite;
|
||||||
Camera: typeof Camera;
|
|
||||||
Text: typeof Text;
|
Text: typeof Text;
|
||||||
Image: typeof Image;
|
Image: typeof Image;
|
||||||
RenderItem: typeof RenderItem;
|
RenderItem: typeof RenderItem;
|
||||||
|
@ -10,7 +10,6 @@ import {
|
|||||||
ILayerGroupRenderExtends,
|
ILayerGroupRenderExtends,
|
||||||
LayerGroup
|
LayerGroup
|
||||||
} from '@/core/render/preset/layer';
|
} from '@/core/render/preset/layer';
|
||||||
import { cloneDeep } from 'lodash-es';
|
|
||||||
|
|
||||||
interface ItemDetailData {
|
interface ItemDetailData {
|
||||||
x: number;
|
x: number;
|
||||||
@ -25,8 +24,13 @@ interface ItemData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const ItemState = Mota.require('module', 'State').ItemState;
|
const ItemState = Mota.require('module', 'State').ItemState;
|
||||||
|
Mota.require('var', 'hook').on('setBlock', (x, y, floorId, block) => {
|
||||||
|
FloorItemDetail.listened.forEach(v => {
|
||||||
|
v.setBlock(block, x, y);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
class FloorItemDetail implements ILayerGroupRenderExtends {
|
export class FloorItemDetail implements ILayerGroupRenderExtends {
|
||||||
id: string = 'item-detail';
|
id: string = 'item-detail';
|
||||||
|
|
||||||
group!: LayerGroup;
|
group!: LayerGroup;
|
||||||
@ -35,7 +39,12 @@ class FloorItemDetail implements ILayerGroupRenderExtends {
|
|||||||
sprite!: Damage;
|
sprite!: Damage;
|
||||||
|
|
||||||
/** 每个分块中包含的物品信息 */
|
/** 每个分块中包含的物品信息 */
|
||||||
blockData: Map<number, Set<ItemData>> = new Map();
|
blockData: Map<number, Map<number, ItemData>> = new Map();
|
||||||
|
|
||||||
|
/** 需要更新的分块 */
|
||||||
|
private dirtyBlock: Set<number> = new Set();
|
||||||
|
/** 道具详细信息 */
|
||||||
|
private detailData: Map<number, Map<number, ItemDetailData>> = new Map();
|
||||||
|
|
||||||
static detailColor: Record<string, CanvasStyle> = {
|
static detailColor: Record<string, CanvasStyle> = {
|
||||||
atk: '#FF7A7A',
|
atk: '#FF7A7A',
|
||||||
@ -51,8 +60,15 @@ class FloorItemDetail implements ILayerGroupRenderExtends {
|
|||||||
manaper: '#c66'
|
manaper: '#c66'
|
||||||
};
|
};
|
||||||
|
|
||||||
private onBeforeRender = (need: Set<number>) => {
|
static listened: Set<FloorItemDetail> = new Set();
|
||||||
|
|
||||||
|
private onBeforeDamageRender = (need: Set<number>) => {
|
||||||
if (!mainSetting.getValue('screen.itemDetail')) return;
|
if (!mainSetting.getValue('screen.itemDetail')) return;
|
||||||
|
need.forEach(v => {
|
||||||
|
if (this.dirtyBlock.has(v)) {
|
||||||
|
this.sprite.block.clearCache(v, 1);
|
||||||
|
}
|
||||||
|
});
|
||||||
this.render(need);
|
this.render(need);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -60,9 +76,21 @@ class FloorItemDetail implements ILayerGroupRenderExtends {
|
|||||||
this.updateMapSize(width, height);
|
this.updateMapSize(width, height);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private onUpdate = () => {
|
||||||
|
this.updateItems();
|
||||||
|
};
|
||||||
|
|
||||||
|
private onUpdateBlocks = (blocks: Set<number>) => {
|
||||||
|
blocks.forEach(v => {
|
||||||
|
this.dirtyBlock.add(v);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
private listen() {
|
private listen() {
|
||||||
this.sprite.on('beforeDamageRender', this.onBeforeRender);
|
this.sprite.on('beforeDamageRender', this.onBeforeDamageRender);
|
||||||
this.sprite.on('setMapSize', this.onUpdateMapSize);
|
this.sprite.on('setMapSize', this.onUpdateMapSize);
|
||||||
|
this.sprite.on('updateBlocks', this.onUpdateBlocks);
|
||||||
|
this.damage.on('update', this.onUpdate);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -72,9 +100,12 @@ class FloorItemDetail implements ILayerGroupRenderExtends {
|
|||||||
this.blockData.clear();
|
this.blockData.clear();
|
||||||
|
|
||||||
// 预留blockData
|
// 预留blockData
|
||||||
const num = width * height;
|
const [x, y] = this.sprite.block.getBlockXY(width, height);
|
||||||
|
const num = x * y;
|
||||||
for (let i = 0; i < num; i++) {
|
for (let i = 0; i < num; i++) {
|
||||||
this.blockData.set(i, new Set());
|
this.blockData.set(i, new Map());
|
||||||
|
this.detailData.set(i, new Map());
|
||||||
|
this.dirtyBlock.add(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -83,6 +114,7 @@ class FloorItemDetail implements ILayerGroupRenderExtends {
|
|||||||
*/
|
*/
|
||||||
updateItems() {
|
updateItems() {
|
||||||
const floor = this.floorBinder.getFloor();
|
const floor = this.floorBinder.getFloor();
|
||||||
|
if (!floor) return;
|
||||||
core.extractBlocks(floor);
|
core.extractBlocks(floor);
|
||||||
|
|
||||||
core.status.maps[floor].blocks.forEach(v => {
|
core.status.maps[floor].blocks.forEach(v => {
|
||||||
@ -93,18 +125,46 @@ class FloorItemDetail implements ILayerGroupRenderExtends {
|
|||||||
const x = v.x;
|
const x = v.x;
|
||||||
const y = v.y;
|
const y = v.y;
|
||||||
const block = this.sprite.block.getIndexByLoc(x, y);
|
const block = this.sprite.block.getIndexByLoc(x, y);
|
||||||
this.blockData.get(block)?.add({ x, y, id });
|
const index = x + y * this.sprite.mapWidth;
|
||||||
|
const blockData = this.blockData.get(block);
|
||||||
|
blockData?.set(index, { x, y, id });
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置图块
|
||||||
|
* @param block 图块数字
|
||||||
|
* @param x 横坐标
|
||||||
|
* @param y 纵坐标
|
||||||
|
*/
|
||||||
|
setBlock(block: AllNumbers, x: number, y: number) {
|
||||||
|
const map = maps_90f36752_8815_4be8_b32b_d7fad1d0542e;
|
||||||
|
const index = this.sprite.block.getIndexByLoc(x, y);
|
||||||
|
const itemIndex = x + y * this.sprite.mapWidth;
|
||||||
|
const blockData = this.blockData.get(index);
|
||||||
|
this.dirtyBlock.add(index);
|
||||||
|
if (block === 0) {
|
||||||
|
blockData?.delete(itemIndex);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const cls = map[block].cls;
|
||||||
|
if (cls !== 'items') {
|
||||||
|
blockData?.delete(itemIndex);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const id = map[block].id;
|
||||||
|
blockData?.set(itemIndex, { x, y, id });
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 计算指定分块中的物品信息
|
* 计算指定分块中的物品信息
|
||||||
* @param block 要计算的分块
|
* @param block 要计算的分块
|
||||||
*/
|
*/
|
||||||
calAllItems(block: Set<number>) {
|
calAllItems(block: Set<number>) {
|
||||||
|
if (this.dirtyBlock.size === 0 || block.size === 0) return;
|
||||||
let diff: Record<string | symbol, number | undefined> = {};
|
let diff: Record<string | symbol, number | undefined> = {};
|
||||||
const before = core.status.hero;
|
const before = core.status.hero;
|
||||||
const hero = cloneDeep(core.status.hero);
|
const hero = structuredClone(core.status.hero);
|
||||||
const handler: ProxyHandler<any> = {
|
const handler: ProxyHandler<any> = {
|
||||||
set(target, key, v) {
|
set(target, key, v) {
|
||||||
diff[key] = v - (target[key] || 0);
|
diff[key] = v - (target[key] || 0);
|
||||||
@ -114,14 +174,16 @@ class FloorItemDetail implements ILayerGroupRenderExtends {
|
|||||||
};
|
};
|
||||||
core.status.hero = new Proxy(hero, handler);
|
core.status.hero = new Proxy(hero, handler);
|
||||||
|
|
||||||
const res: Map<number, Set<ItemDetailData>> = new Map();
|
|
||||||
core.setFlag('__statistics__', true);
|
core.setFlag('__statistics__', true);
|
||||||
block.forEach(v => {
|
block.forEach(v => {
|
||||||
|
if (!this.dirtyBlock.has(v)) return;
|
||||||
const data = this.blockData.get(v);
|
const data = this.blockData.get(v);
|
||||||
|
const detail = this.detailData.get(v);
|
||||||
|
detail?.clear();
|
||||||
if (!data) return;
|
if (!data) return;
|
||||||
const info: Set<ItemDetailData> = new Set();
|
|
||||||
data.forEach(v => {
|
data.forEach(v => {
|
||||||
const { x, y, id } = v;
|
const { id, x, y } = v;
|
||||||
|
const index = x + y * this.sprite.mapWidth;
|
||||||
diff = {};
|
diff = {};
|
||||||
|
|
||||||
const item = core.material.items[id];
|
const item = core.material.items[id];
|
||||||
@ -135,21 +197,18 @@ class FloorItemDetail implements ILayerGroupRenderExtends {
|
|||||||
const n = name as SelectKey<HeroStatus, number>;
|
const n = name as SelectKey<HeroStatus, number>;
|
||||||
diff[name + 'per'] = per[n].toString() + '%';
|
diff[name + 'per'] = per[n].toString() + '%';
|
||||||
}
|
}
|
||||||
info.add({ x, y, diff });
|
detail?.set(index, { x, y, diff });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
ItemState.item(id)?.itemEffectFn();
|
ItemState.item(id)?.itemEffectFn();
|
||||||
info.add({ x, y, diff });
|
detail?.set(index, { x, y, diff });
|
||||||
});
|
});
|
||||||
res.set(v, info);
|
|
||||||
});
|
});
|
||||||
core.status.hero = before;
|
core.status.hero = before;
|
||||||
window.hero = before;
|
window.hero = before;
|
||||||
window.flags = before.flags;
|
window.flags = before.flags;
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -157,8 +216,13 @@ class FloorItemDetail implements ILayerGroupRenderExtends {
|
|||||||
* @param block 需要渲染的格子
|
* @param block 需要渲染的格子
|
||||||
*/
|
*/
|
||||||
render(block: Set<number>) {
|
render(block: Set<number>) {
|
||||||
const data = this.calAllItems(block);
|
this.calAllItems(block);
|
||||||
data.forEach((info, k) => {
|
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 }) => {
|
info.forEach(({ x, y, diff }) => {
|
||||||
let n = 0;
|
let n = 0;
|
||||||
for (const [key, value] of Object.entries(diff)) {
|
for (const [key, value] of Object.entries(diff)) {
|
||||||
@ -173,7 +237,7 @@ class FloorItemDetail implements ILayerGroupRenderExtends {
|
|||||||
align: 'left',
|
align: 'left',
|
||||||
baseline: 'alphabetic'
|
baseline: 'alphabetic'
|
||||||
};
|
};
|
||||||
this.sprite.renderable.get(k)?.add(renderable);
|
this.sprite.renderable.get(v)?.add(renderable);
|
||||||
n++;
|
n++;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -181,32 +245,33 @@ class FloorItemDetail implements ILayerGroupRenderExtends {
|
|||||||
}
|
}
|
||||||
|
|
||||||
awake(group: LayerGroup): void {
|
awake(group: LayerGroup): void {
|
||||||
|
console.log(this);
|
||||||
|
|
||||||
this.group = group;
|
this.group = group;
|
||||||
group.requestBeforeFrame(() => {
|
|
||||||
const binder = group.getExtends('floor-binder');
|
const binder = group.getExtends('floor-binder');
|
||||||
const damage = group.getExtends('floor-damage');
|
const damage = group.getExtends('floor-damage');
|
||||||
if (
|
if (
|
||||||
binder instanceof LayerGroupFloorBinder &&
|
binder instanceof LayerGroupFloorBinder &&
|
||||||
damage instanceof FloorDamageExtends
|
damage instanceof FloorDamageExtends
|
||||||
) {
|
) {
|
||||||
this.floorBinder = binder;
|
this.floorBinder = binder;
|
||||||
this.damage = damage;
|
this.damage = damage;
|
||||||
group.requestAfterFrame(() => {
|
this.sprite = damage.sprite;
|
||||||
this.sprite = damage.sprite;
|
this.listen();
|
||||||
this.listen();
|
FloorItemDetail.listened.add(this);
|
||||||
});
|
} else {
|
||||||
} else {
|
logger.warn(
|
||||||
logger.warn(
|
1001,
|
||||||
1001,
|
`Item-detail extends needs 'floor-binder' and 'floor-damage' as dependency`
|
||||||
`Item-detail extends needs 'floor-binder' and 'floor-damage' as dependency`
|
);
|
||||||
);
|
group.removeExtends('item-detail');
|
||||||
group.removeExtends('item-detail');
|
}
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onDestroy(group: LayerGroup): void {
|
onDestroy(group: LayerGroup): void {
|
||||||
this.sprite.off('beforeDamageRender', this.onBeforeRender);
|
this.sprite.off('beforeDamageRender', this.onBeforeDamageRender);
|
||||||
this.sprite.off('setMapSize', this.onUpdateMapSize);
|
this.sprite.off('setMapSize', this.onUpdateMapSize);
|
||||||
|
FloorItemDetail.listened.delete(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -267,9 +267,12 @@ export function init() {
|
|||||||
stopChian = true;
|
stopChian = true;
|
||||||
|
|
||||||
callback?.();
|
callback?.();
|
||||||
|
};
|
||||||
|
|
||||||
// if (callback) return this.moveAction(callback);
|
events.prototype.setHeroIcon = function (name: ImageIds) {
|
||||||
// this._moveHero_moving();
|
const img = core.material.images.images[name];
|
||||||
|
if (!img) return;
|
||||||
|
adapters['hero-adapter']?.all('setImage', img);
|
||||||
};
|
};
|
||||||
|
|
||||||
hook.on('reset', () => {
|
hook.on('reset', () => {
|
||||||
|
7
src/types/control.d.ts
vendored
7
src/types/control.d.ts
vendored
@ -312,7 +312,8 @@ interface Control {
|
|||||||
moveOneStep(callback?: () => any): void;
|
moveOneStep(callback?: () => any): void;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated
|
* @deprecated 尽量不要使用!!如果需要无视地形使用代码来移动勇士,请使用 `eventMoveHero`
|
||||||
|
* 如果需要向前前进一格或撞击,请使用 `moveHero`
|
||||||
* 尝试前进一步,如果面前不可被踏入就会直接触发该点事件
|
* 尝试前进一步,如果面前不可被踏入就会直接触发该点事件
|
||||||
* @example core.moveAction(core.doAction); // 尝试前进一步,然后继续事件处理
|
* @example core.moveAction(core.doAction); // 尝试前进一步,然后继续事件处理
|
||||||
* @param callback 走一步后的回调函数
|
* @param callback 走一步后的回调函数
|
||||||
@ -320,8 +321,8 @@ interface Control {
|
|||||||
moveAction(callback?: () => void): void;
|
moveAction(callback?: () => void): void;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated
|
* @deprecated 尽量不要使用!!如果需要无视地形使用代码来移动勇士,请使用 `eventMoveHero`
|
||||||
* 连续前进,不撞南墙不回头
|
* 向指定方向移动一格
|
||||||
* @example core.moveHero(); // 连续前进
|
* @example core.moveHero(); // 连续前进
|
||||||
* @param direction 移动的方向,不设置就是勇士当前的方向
|
* @param direction 移动的方向,不设置就是勇士当前的方向
|
||||||
* @param callback 回调函数,设置了就只走一步
|
* @param callback 回调函数,设置了就只走一步
|
||||||
|
Loading…
Reference in New Issue
Block a user