feat: 宝石血瓶显伤

This commit is contained in:
AncTe committed 2024-08-26 21:10:56 +08:00
1 parent 57760d501e
commit 1c369251b1
11 files changed
+218 -144

No files matched your search

+42
View 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();
});
+25 -20
View File
@@ -40,7 +40,7 @@ export class FloorDamageExtends
* 立刻刷新伤害渲染
*/
update(floor: FloorIds) {
if (!this.sprite) return;
if (!this.sprite || !floor) return;
const map = core.status.maps[floor];
this.sprite.setMapSize(map.width, map.height);
ensureFloorDamage(floor);
@@ -89,21 +89,19 @@ export class FloorDamageExtends
}
awake(group: LayerGroup): void {
group.requestBeforeFrame(() => {
const ex = group.getExtends('floor-binder');
if (ex instanceof LayerGroupFloorBinder) {
this.floorBinder = ex;
this.group = group;
this.create();
this.listen();
} else {
logger.warn(
17,
`Floor-damage extends needs 'floor-binder' extends as dependency.`
);
group.removeExtends('floor-damage');
}
});
const ex = group.getExtends('floor-binder');
if (ex instanceof LayerGroupFloorBinder) {
this.floorBinder = ex;
this.group = group;
this.create();
this.listen();
} else {
logger.warn(
17,
`Floor-damage extends needs 'floor-binder' extends as dependency.`
);
group.removeExtends('floor-damage');
}
}
onDestroy(group: LayerGroup): void {
@@ -132,6 +130,7 @@ interface DamageCache {
interface EDamageEvent extends ESpriteEvent {
setMapSize: [width: number, height: number];
beforeDamageRender: [need: Set<number>, transform: Transform];
updateBlocks: [blocks: Set<number>];
}
export class Damage extends Sprite<EDamageEvent> {
@@ -241,13 +240,16 @@ export class Damage extends Sprite<EDamageEvent> {
/**
* 更新指定分块
* @param blocks 要更新的分块集合
* @param map 是否更新地图伤害
*/
updateBlocks(blocks?: Set<number>) {
updateBlocks(blocks?: Set<number>, map: boolean = true) {
if (blocks) {
blocks.forEach(v => this.updateBlock(v));
blocks.forEach(v => this.updateBlock(v, map));
this.emit('updateBlocks', blocks);
} else {
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);
}
@@ -274,7 +276,9 @@ export class Damage extends Sprite<EDamageEvent> {
this.needUpdateBlocks.add(block);
this.requestBeforeFrame(() => {
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: 阻击夹域等地图伤害检测是否必要更新,例如不包含阻击夹域的怪就不必要更新这个怪物信息
// this.extractAllMapDamage();
});
@@ -423,6 +427,7 @@ export class Damage extends Sprite<EDamageEvent> {
ctx.save();
this.damageMap.clear();
transformCanvas(this.damageMap, transform);
// console.trace();
const { res: render } = this.calNeedRender(transform);
const block = this.block;
+3 -3
View File
@@ -149,9 +149,9 @@ export class LayerGroupFloorBinder
LayerGroupFloorBinder.activedBinder.add(this);
}
onLayerAdd(group: LayerGroup, layer: Layer): void {
this.checkLayerExtends(layer);
}
// onLayerAdd(group: LayerGroup, layer: Layer): void {
// this.checkLayerExtends(layer);
// }
onDestroy(group: LayerGroup) {
LayerGroupFloorBinder.activedBinder.delete(this);
+8 -1
View File
@@ -145,7 +145,10 @@ export class HeroRenderer
*/
private moveTick(time: number) {
if (this.status !== 'moving') return;
if (!this.renderable) return;
if (!this.renderable) {
this.emit('stepEnd');
return;
}
if (time - this.lastFrameTime > this.speed) {
this.lastFrameTime = time;
@@ -379,6 +382,10 @@ adapter.recieve('turn', (item, dir: Dir2) => {
item.turn(dir);
return Promise.resolve();
});
adapter.recieve('setImage', (item, image: SizedCanvasImageSource) => {
item.setImage(image);
return Promise.resolve();
});
// 同步fallback,用于适配现在的样板,之后会删除
adapter.recieveSync('setHeroLoc', (item, x?: number, y?: number) => {
item.setHeroLoc(x, y);
+19
View File
@@ -8,6 +8,7 @@ import { RenderableData, texture } from '../cache';
import { glMatrix } from 'gl-matrix';
import { BlockCacher } from './block';
import { Transform } from '../transform';
import { LayerFloorBinder, LayerGroupFloorBinder } from './floor';
export interface ILayerGroupRenderExtends {
/** 拓展的唯一标识符 */
@@ -60,6 +61,18 @@ export interface ILayerGroupRenderExtends {
*/
onFrameUpdate?(group: LayerGroup, frame: number): void;
/**
* 在渲染之前执行的函数
* @param group 目标LayerGroup实例
*/
onBeforeRender?(group: LayerGroup): void;
/**
* 在渲染之后执行的函数
* @param group 目标LayerGroup实例
*/
onAfterRender?(group: LayerGroup): void;
/**
* 当拓展被取消挂载时执行的函数(LayerGroup被销毁,拓展被移除等)
* @param group 目标LayerGroup实例
@@ -100,6 +113,10 @@ export class LayerGroup extends Container implements IAnimateFrame {
});
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.movingMap.canvas, 0, 0, width, height);
});
this.extends(new LayerFloorBinder());
}
/**
+2 -71
View File
@@ -1,14 +1,7 @@
import { Animation, hyper, linear, sleep } from 'mutate-animate';
import { MotaCanvas2D, MotaOffscreenCanvas2D } from '../fx/canvas2d';
import { MotaCanvas2D } from '../fx/canvas2d';
import { Container } from './container';
import { RenderItem, transformCanvas } 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 { RenderItem } from './item';
import { Transform } from './transform';
import { Text } from './preset/misc';
import { Shader } from './shader';
export class MotaRenderer extends Container {
static list: Set<MotaRenderer> = new Set();
@@ -69,65 +62,3 @@ export class MotaRenderer extends Container {
window.addEventListener('resize', () => {
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);
});