From ed229e160133df8a885cfd1d39bf9d1be35b9338 Mon Sep 17 00:00:00 2001 From: unanmed <1319491857@qq.com> Date: Fri, 31 Jan 2025 12:35:31 +0800 Subject: [PATCH] =?UTF-8?q?refactor:=20=E5=A4=A9=E6=B0=94=E7=B3=BB?= =?UTF-8?q?=E7=BB=9F=E7=BB=93=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/module/weather/index.ts | 10 +++- src/module/weather/rain.ts | 89 +++++++++++++++++------------------ src/module/weather/snow.ts | 4 +- src/module/weather/sun.ts | 4 +- src/module/weather/weather.ts | 64 +++++++++++++++++++------ 5 files changed, 104 insertions(+), 67 deletions(-) diff --git a/src/module/weather/index.ts b/src/module/weather/index.ts index 91de7e9..6c29960 100644 --- a/src/module/weather/index.ts +++ b/src/module/weather/index.ts @@ -1,3 +1,11 @@ +import { RainWeather } from './rain'; +import { SnowWeather } from './snow'; +import { SunWeather } from './sun'; import { WeatherController } from './weather'; -export const controller = new WeatherController(); +WeatherController.register('rain', RainWeather); +WeatherController.register('sun', SunWeather); +WeatherController.register('snow', SnowWeather); + +export * from './weather'; +export * from './rain'; diff --git a/src/module/weather/rain.ts b/src/module/weather/rain.ts index 99d8b68..995f109 100644 --- a/src/module/weather/rain.ts +++ b/src/module/weather/rain.ts @@ -1,5 +1,5 @@ import { Shader, ShaderProgram } from '@/core/render/shader'; -import { IWeather, WeatherController } from './weather'; +import { IWeather } from './weather'; import { MotaRenderer } from '@/core/render/render'; import { Container } from '@/core/render/container'; import { IShaderUniform, UniformType } from '@/core/render/gl2'; @@ -78,67 +78,66 @@ void main() { /** 雨滴顶点坐标 */ const vertex = new Float32Array([-1, -1, 1, -1, -1, 1, 1, 1]); -Mota.require('var', 'loading').once('coreInit', () => { - const shader = new RainShader(); - const gl = shader.gl; - shader.size(480, 480); - shader.setHD(true); - shader.setZIndex(100); - RainWeather.shader = shader; - const program = shader.createProgram(ShaderProgram); - program.fs(rainFs); - program.vs(rainVs); - program.requestCompile(); - const pos = program.defineAttribArray('a_rainVertex'); - program.defineAttribArray('a_offset'); - program.defineAttribArray('a_data'); - program.defineUniform('u_progress', shader.UNIFORM_1f); - program.defineUniform('u_color', shader.UNIFORM_4f); - program.mode(shader.DRAW_ARRAYS_INSTANCED); - RainShader.rainProgram = program; - shader.useProgram(program); - - if (pos) { - pos.buffer(vertex, gl.STATIC_DRAW); - pos.pointer(2, gl.FLOAT, false, 0, 0); - pos.enable(); - } -}); - export class RainWeather implements IWeather { - static id: string = 'rain'; - - static shader: RainShader; + readonly shader: RainShader; + readonly program: ShaderProgram; private progress: IShaderUniform | null = null; - constructor(readonly level: number = 5) {} + constructor(readonly level: number = 5) { + const shader = new RainShader(); + const gl = shader.gl; + shader.size(480, 480); + shader.setHD(true); + shader.setZIndex(100); + const program = shader.createProgram(ShaderProgram); + program.fs(rainFs); + program.vs(rainVs); + program.requestCompile(); + const pos = program.defineAttribArray('a_rainVertex'); + program.defineAttribArray('a_offset'); + program.defineAttribArray('a_data'); + program.defineUniform('u_progress', shader.UNIFORM_1f); + program.defineUniform('u_color', shader.UNIFORM_4f); + program.mode(shader.DRAW_ARRAYS_INSTANCED); + shader.useProgram(program); + + if (pos) { + pos.buffer(vertex, gl.STATIC_DRAW); + pos.pointer(2, gl.FLOAT, false, 0, 0); + pos.enable(); + } + this.shader = shader; + this.program = program; + } activate(): void { const render = MotaRenderer.get('render-main'); const draw = render?.getElementById('map-draw') as Container; if (!draw) return; - const shader = RainWeather.shader; + const shader = this.shader; shader.append(draw); const gl = shader.gl; - const program = RainShader.rainProgram; + const program = this.program; program.paramArraysInstanced(gl.TRIANGLE_STRIP, 0, 4, 100 * this.level); this.progress = program.getUniform('u_progress'); + shader.useProgram(program); shader.generateRainPath( this.level * 100, (((Math.random() - 0.5) * Math.PI) / 30) * this.level, - (Math.PI / 180) * (12 - this.level) + (Math.PI / 180) * (12 - this.level), + program ); } frame(): void { - RainWeather.shader.update(RainWeather.shader); + this.shader.update(this.shader); const time = 5000 - 400 * this.level; const progress = (Date.now() % time) / time; - RainWeather.shader.useProgram(RainShader.rainProgram); + this.shader.useProgram(this.program); this.progress?.set(progress); } @@ -147,25 +146,23 @@ export class RainWeather implements IWeather { const draw = render?.getElementById('map-draw') as Container; const layer = draw.children; if (!layer || !draw) return; - const shader = RainWeather.shader; + const shader = this.shader; draw.appendChild(...layer); shader.remove(); } } -WeatherController.register(RainWeather); - class RainShader extends Shader { - static rainProgram: ShaderProgram; - static backProgram: ShaderProgram; - /** * 生成雨滴 * @param num 雨滴数量 */ - generateRainPath(num: number, angle: number, deviation: number) { - const program = RainShader.rainProgram; - RainWeather.shader.useProgram(program); + generateRainPath( + num: number, + angle: number, + deviation: number, + program: ShaderProgram + ) { const aOffset = program.getAttribArray('a_offset'); const aData = program.getAttribArray('a_data'); const color = program.getUniform('u_color'); diff --git a/src/module/weather/snow.ts b/src/module/weather/snow.ts index a0bddcf..2924de4 100644 --- a/src/module/weather/snow.ts +++ b/src/module/weather/snow.ts @@ -1,5 +1,5 @@ import { Shader, ShaderProgram } from '@/core/render/shader'; -import { IWeather, WeatherController } from './weather'; +import { IWeather } from './weather'; import { MotaRenderer } from '@/core/render/render'; import { Container } from '@/core/render/container'; import { GL2Program, IShaderUniform, UniformType } from '@/core/render/gl2'; @@ -174,8 +174,6 @@ export class SnowWeather implements IWeather { } } -WeatherController.register(SnowWeather); - class SnowShader extends Shader { static snowProgram: ShaderProgram; static backProgram: ShaderProgram; diff --git a/src/module/weather/sun.ts b/src/module/weather/sun.ts index da467d1..7959e5b 100644 --- a/src/module/weather/sun.ts +++ b/src/module/weather/sun.ts @@ -1,4 +1,4 @@ -import { IWeather, WeatherController } from './weather'; +import { IWeather } from './weather'; export class SunWeather implements IWeather { static id: string = 'sun'; @@ -9,5 +9,3 @@ export class SunWeather implements IWeather { deactivate(): void {} } - -WeatherController.register(SunWeather); diff --git a/src/module/weather/weather.ts b/src/module/weather/weather.ts index 7e08f0f..29eca1c 100644 --- a/src/module/weather/weather.ts +++ b/src/module/weather/weather.ts @@ -1,11 +1,12 @@ import { logger } from '@/core/common/logger'; +import { RenderItem } from '@/core/render'; import { Ticker } from 'mutate-animate'; export interface IWeather { /** * 初始化天气,当天气被添加时会被立刻调用 */ - activate(): void; + activate(item: RenderItem): void; /** * 每帧执行的函数 @@ -15,21 +16,25 @@ export interface IWeather { /** * 摧毁这个天气,当天气被删除时会执行 */ - deactivate(): void; + deactivate(item: RenderItem): void; } -interface Weather { - id: string; - new (level?: number): T; -} +type Weather = new (level?: number) => IWeather; export class WeatherController { static list: Map = new Map(); + static map: Map = new Map(); /** 当前的所有天气 */ active: Set = new Set(); ticker: Ticker = new Ticker(); + private binded?: RenderItem; + + constructor(public readonly id: string) { + WeatherController.map.set(id, this); + } + private tick = () => { this.active.forEach(v => { v.frame(); @@ -40,9 +45,11 @@ export class WeatherController { * 清空所有天气 */ clearWeather() { - this.active.forEach(v => { - v.deactivate(); - }); + if (this.binded) { + this.active.forEach(v => { + v.deactivate(this.binded!); + }); + } this.active.clear(); } @@ -50,7 +57,7 @@ export class WeatherController { * 获取一个天气 * @param weather 要获取的天气 */ - getWeather(weather: Weather): T | null { + getWeather(weather: Weather): T | null { return ([...this.active].find(v => v instanceof weather) as T) ?? null; } @@ -68,7 +75,9 @@ export class WeatherController { } const weather = new Weather(level); this.active.add(weather); - weather.activate(); + if (this.binded) { + weather.activate(this.binded); + } if (!this.ticker.funcs.has(this.tick)) { this.ticker.add(this.tick); } @@ -84,10 +93,37 @@ export class WeatherController { if (this.active.size === 0) { this.ticker.remove(this.tick); } - weather.deactivate(); + if (this.binded) { + weather.deactivate(this.binded); + } } - static register(weather: Weather) { - this.list.set(weather.id, weather); + /** + * 将这个天气控制器绑定至一个渲染元素上 + * @param item 要绑定的元素,不填表示取消绑定 + */ + bind(item?: RenderItem) { + if (this.binded) { + this.active.forEach(v => v.deactivate(this.binded!)); + } + this.binded = item; + if (item) { + this.active.forEach(v => v.activate(item)); + } + } + + /** + * 摧毁这个天气控制器 + */ + destroy() { + WeatherController.map.delete(this.id); + } + + static get(id: string) { + return this.map.get(id); + } + + static register(id: string, weather: Weather) { + this.list.set(id, weather); } }