Compare commits

..

No commits in common. "69da0484388643bac1a6d77f34d1ca7acb553b07" and "6f10ac3d81bdd3a9be6bbbc0826bb8c99568ed78" have entirely different histories.

20 changed files with 126 additions and 187 deletions

View File

@ -2853,7 +2853,11 @@ control.prototype.getMappedName = function (name) {
////// 更改天气效果 ////// ////// 更改天气效果 //////
control.prototype.setWeather = function (type, level) { control.prototype.setWeather = function (type, level) {
// Deprecated. Use WeatherController API instead. // Deprecated. Use WeatherController API instead.
// Fallback see src/module/fallback/weather.ts Mota.r(() => {
const controller = Mota.require('module', 'Weather').controller;
controller.clearWeather();
if (type !== null && type !== void 0) controller.activate(type, level);
});
}; };
////// 注册一个天气 ////// ////// 注册一个天气 //////

View File

@ -75,6 +75,7 @@ import './render/index';
import * as RenderUtils from './render/utils'; import * as RenderUtils from './render/utils';
import '@/module'; import '@/module';
import { MotaOffscreenCanvas2D } from './fx/canvas2d'; import { MotaOffscreenCanvas2D } from './fx/canvas2d';
import { TextboxStore } from './render/index';
// ----- 类注册 // ----- 类注册
Mota.register('class', 'CustomToolbar', CustomToolbar); Mota.register('class', 'CustomToolbar', CustomToolbar);
@ -156,7 +157,8 @@ Mota.register('module', 'Render', {
LayerGroupFloorBinder, LayerGroupFloorBinder,
Camera, Camera,
MotaOffscreenCanvas2D, MotaOffscreenCanvas2D,
Utils: RenderUtils Utils: RenderUtils,
TextboxStore
}); });
Mota.register('module', 'Action', { Mota.register('module', 'Action', {
HeroKeyMover HeroKeyMover

View File

@ -1,14 +0,0 @@
export * from './preset';
export * from './renderer';
export * from './adapter';
export * from './cache';
export * from './camera';
export * from './container';
export * from './frame';
export * from './gl2';
export * from './item';
export * from './render';
export * from './shader';
export * from './sprite';
export * from './transform';
export * from './utils';

View File

@ -1,25 +1,26 @@
import { FloorItemDetail } from '@/plugin/fx/itemDetail'; import { FloorItemDetail } from '@/plugin/fx/itemDetail';
import { FloorDamageExtends, LayerGroup } from '@/core/render'; import { FloorDamageExtends } from './preset/damage';
import { LayerDoorAnimate } from '@/core/render'; import { LayerDoorAnimate } from './preset/floor';
import { HeroRenderer } from '@/core/render'; import { HeroRenderer } from './preset/hero';
import { MotaRenderer } from '@/core/render'; import { MotaRenderer } from './render';
import { LayerShadowExtends } from '@/core/fx/shadow'; import { LayerShadowExtends } from '../fx/shadow';
import { LayerGroupFilter } from '@/plugin/fx/gameCanvas'; import { LayerGroupFilter } from '@/plugin/fx/gameCanvas';
import { LayerGroupAnimate } from '@/core/render'; import { LayerGroupAnimate } from './preset/animate';
import { LayerGroupPortal } from '@/plugin/fx/portal'; import { LayerGroupPortal } from '@/plugin/fx/portal';
import { LayerGroupHalo } from '@/plugin/fx/halo'; import { LayerGroupHalo } from '@/plugin/fx/halo';
import { FloorViewport } from '@/core/render'; import { FloorViewport } from './preset/viewport';
import { PopText } from '@/plugin/fx/pop'; import { PopText } from '@/plugin/fx/pop';
import { FloorChange } from '@/plugin/fallback'; import { FloorChange } from '@/plugin/fallback';
import { createApp } from '@/core/render'; import { createApp } from './renderer';
import { defineComponent, onMounted, ref } from 'vue'; import { defineComponent } from 'vue';
import { Textbox } from './components'; import { Textbox } from '../../module/ui/components';
import { ILayerGroupRenderExtends, ILayerRenderExtends } from '@/core/render'; import { ILayerGroupRenderExtends, ILayerRenderExtends } from './preset';
import { Props } from '@/core/render'; import { Props } from './utils';
import { WeatherController } from '../weather';
export function create() { let main: MotaRenderer;
const main = new MotaRenderer();
Mota.require('var', 'loading').once('coreInit', () => {
main = new MotaRenderer();
const App = defineComponent(_props => { const App = defineComponent(_props => {
const layerGroupExtends: ILayerGroupRenderExtends[] = [ const layerGroupExtends: ILayerGroupRenderExtends[] = [
@ -56,16 +57,9 @@ export function create() {
lineHeight: 6 lineHeight: 6
}; };
const map = ref<LayerGroup>();
const weather = new WeatherController('main');
onMounted(() => {
weather.bind(map.value);
});
return () => ( return () => (
<container id="map-draw" {...mapDrawProps}> <container id="map-draw" {...mapDrawProps}>
<layer-group id="layer-main" ex={layerGroupExtends} ref={map}> <layer-group id="layer-main" ex={layerGroupExtends}>
<layer layer="bg" zIndex={10}></layer> <layer layer="bg" zIndex={10}></layer>
<layer layer="bg2" zIndex={20}></layer> <layer layer="bg2" zIndex={20}></layer>
<layer layer="event" zIndex={30} ex={eventExtends}></layer> <layer layer="event" zIndex={30} ex={eventExtends}></layer>
@ -81,16 +75,28 @@ export function create() {
main.hide(); main.hide();
createApp(App).mount(main); createApp(App).mount(main);
// render(<Com></Com>, main);
Mota.require('var', 'hook').on('reset', () => {
main.show();
});
Mota.require('var', 'hook').on('restart', () => {
main.hide();
});
console.log(main); console.log(main);
} });
export * from './components'; Mota.require('var', 'hook').on('reset', () => {
main.show();
});
Mota.require('var', 'hook').on('restart', () => {
main.hide();
});
export * from './preset';
export * from './renderer';
export * from './adapter';
export * from './cache';
export * from './camera';
export * from './container';
export * from './gl2';
export * from './item';
export * from './render';
export * from './shader';
export * from './sprite';
export * from './transform';

View File

@ -388,7 +388,7 @@ export abstract class RenderItem<E extends ERenderItemEvent = ERenderItemEvent>
/** /**
* *
* @param canvas * @param canvas
* @param transform * @param transform
* *
* `absolute` * `absolute`
* `Layer``Damage` * `Layer``Damage`

View File

@ -38,6 +38,7 @@ import type * as Animation from 'mutate-animate';
import type * as RenderUtils from '@/core/render/utils'; import type * as RenderUtils from '@/core/render/utils';
import type { WeatherController } from '@/module/weather/weather'; import type { WeatherController } from '@/module/weather/weather';
import type { MotaOffscreenCanvas2D } from '@/core/fx/canvas2d'; import type { MotaOffscreenCanvas2D } from '@/core/fx/canvas2d';
import type { TextboxStore } from '@/core/render';
interface ClassInterface { interface ClassInterface {
// 渲染进程与游戏进程通用 // 渲染进程与游戏进程通用
@ -114,6 +115,7 @@ interface ModuleInterface {
Camera: typeof Camera; Camera: typeof Camera;
MotaOffscreenCanvas2D: typeof MotaOffscreenCanvas2D; MotaOffscreenCanvas2D: typeof MotaOffscreenCanvas2D;
Utils: typeof RenderUtils; Utils: typeof RenderUtils;
TextboxStore: typeof TextboxStore;
}; };
State: { State: {
ItemState: typeof ItemState; ItemState: typeof ItemState;

View File

@ -1,10 +1,9 @@
import { Patch } from '@/common/patch'; import { Patch } from '@/common/patch';
import { patchAudio } from './audio'; import { patchAudio } from './audio';
import { patchWeather } from './weather';
patchAudio();
export function patchAll() { export function patchAll() {
patchAudio();
patchWeather();
const loading = Mota.require('var', 'loading'); const loading = Mota.require('var', 'loading');
loading.once('coreInit', () => { loading.once('coreInit', () => {
Patch.patchAll(); Patch.patchAll();

View File

@ -1,21 +0,0 @@
import { Patch, PatchClass } from '@/common/patch';
import { WeatherController } from '../weather';
import { isNil } from 'lodash-es';
export function patchWeather() {
const patch = new Patch(PatchClass.Control);
let nowWeather: string = '';
let nowLevel: number = 0;
patch.add('setWeather', (type, level) => {
const weather = WeatherController.get('main');
if (!weather) return;
if (type === nowWeather && level === nowLevel) return;
weather.clearWeather();
if (!isNil(type)) {
weather.activate(type, level);
nowWeather = type;
nowLevel = level ?? 5;
}
});
}

View File

@ -1,21 +1,19 @@
import { soundPlayer } from './audio'; import { soundPlayer } from './audio';
import { patchAll } from './fallback'; import { patchAll } from './fallback';
import { create } from './render'; import { controller } from './weather';
import { RainWeather } from './weather/rain'; import { RainWeather } from './weather/rain';
import { WeatherController } from './weather/weather'; import { WeatherController } from './weather/weather';
patchAll(); patchAll();
Mota.register('module', 'Weather', { Mota.register('module', 'Weather', {
controller,
WeatherController, WeatherController,
RainWeather RainWeather
}); });
Mota.register('module', 'Audio', { Mota.register('module', 'Audio', { soundPlayer });
soundPlayer
});
Mota.require('var', 'loading').once('coreInit', create);
export * from './weather'; export * from './weather';
export * from './audio'; export * from './audio';
export * from './loader'; export * from './loader';
export * from './fallback'; export * from './fallback';
export * from './render'; export * from './ui';

1
src/module/ui/index.ts Normal file
View File

@ -0,0 +1 @@
export * from './components';

View File

@ -1,11 +1,3 @@
import { RainWeather } from './rain';
import { SnowWeather } from './snow';
import { SunWeather } from './sun';
import { WeatherController } from './weather'; import { WeatherController } from './weather';
WeatherController.register('rain', RainWeather); export const controller = new WeatherController();
WeatherController.register('sun', SunWeather);
WeatherController.register('snow', SnowWeather);
export * from './weather';
export * from './rain';

View File

@ -1,5 +1,5 @@
import { Shader, ShaderProgram } from '@/core/render/shader'; import { Shader, ShaderProgram } from '@/core/render/shader';
import { IWeather } from './weather'; import { IWeather, WeatherController } from './weather';
import { MotaRenderer } from '@/core/render/render'; import { MotaRenderer } from '@/core/render/render';
import { Container } from '@/core/render/container'; import { Container } from '@/core/render/container';
import { IShaderUniform, UniformType } from '@/core/render/gl2'; import { IShaderUniform, UniformType } from '@/core/render/gl2';
@ -78,66 +78,67 @@ void main() {
/** 雨滴顶点坐标 */ /** 雨滴顶点坐标 */
const vertex = new Float32Array([-1, -1, 1, -1, -1, 1, 1, 1]); 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 { export class RainWeather implements IWeather {
readonly shader: RainShader; static id: string = 'rain';
readonly program: ShaderProgram;
static shader: RainShader;
private progress: IShaderUniform<UniformType.Uniform1f> | null = null; private progress: IShaderUniform<UniformType.Uniform1f> | 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 { activate(): void {
const render = MotaRenderer.get('render-main'); const render = MotaRenderer.get('render-main');
const draw = render?.getElementById('map-draw') as Container; const draw = render?.getElementById('map-draw') as Container;
if (!draw) return; if (!draw) return;
const shader = this.shader; const shader = RainWeather.shader;
shader.append(draw); shader.append(draw);
const gl = shader.gl; const gl = shader.gl;
const program = this.program; const program = RainShader.rainProgram;
program.paramArraysInstanced(gl.TRIANGLE_STRIP, 0, 4, 100 * this.level); program.paramArraysInstanced(gl.TRIANGLE_STRIP, 0, 4, 100 * this.level);
this.progress = program.getUniform<UniformType.Uniform1f>('u_progress'); this.progress = program.getUniform<UniformType.Uniform1f>('u_progress');
shader.useProgram(program);
shader.generateRainPath( shader.generateRainPath(
this.level * 100, this.level * 100,
(((Math.random() - 0.5) * Math.PI) / 30) * this.level, (((Math.random() - 0.5) * Math.PI) / 30) * this.level,
(Math.PI / 180) * (12 - this.level), (Math.PI / 180) * (12 - this.level)
program
); );
} }
frame(): void { frame(): void {
this.shader.update(this.shader); RainWeather.shader.update(RainWeather.shader);
const time = 5000 - 400 * this.level; const time = 5000 - 400 * this.level;
const progress = (Date.now() % time) / time; const progress = (Date.now() % time) / time;
this.shader.useProgram(this.program); RainWeather.shader.useProgram(RainShader.rainProgram);
this.progress?.set(progress); this.progress?.set(progress);
} }
@ -146,23 +147,25 @@ export class RainWeather implements IWeather {
const draw = render?.getElementById('map-draw') as Container; const draw = render?.getElementById('map-draw') as Container;
const layer = draw.children; const layer = draw.children;
if (!layer || !draw) return; if (!layer || !draw) return;
const shader = this.shader; const shader = RainWeather.shader;
draw.appendChild(...layer); draw.appendChild(...layer);
shader.remove(); shader.remove();
} }
} }
WeatherController.register(RainWeather);
class RainShader extends Shader { class RainShader extends Shader {
static rainProgram: ShaderProgram;
static backProgram: ShaderProgram;
/** /**
* *
* @param num * @param num
*/ */
generateRainPath( generateRainPath(num: number, angle: number, deviation: number) {
num: number, const program = RainShader.rainProgram;
angle: number, RainWeather.shader.useProgram(program);
deviation: number,
program: ShaderProgram
) {
const aOffset = program.getAttribArray('a_offset'); const aOffset = program.getAttribArray('a_offset');
const aData = program.getAttribArray('a_data'); const aData = program.getAttribArray('a_data');
const color = program.getUniform<UniformType.Uniform4f>('u_color'); const color = program.getUniform<UniformType.Uniform4f>('u_color');

View File

@ -1,5 +1,5 @@
import { Shader, ShaderProgram } from '@/core/render/shader'; import { Shader, ShaderProgram } from '@/core/render/shader';
import { IWeather } from './weather'; import { IWeather, WeatherController } from './weather';
import { MotaRenderer } from '@/core/render/render'; import { MotaRenderer } from '@/core/render/render';
import { Container } from '@/core/render/container'; import { Container } from '@/core/render/container';
import { GL2Program, IShaderUniform, UniformType } from '@/core/render/gl2'; import { GL2Program, IShaderUniform, UniformType } from '@/core/render/gl2';
@ -174,6 +174,8 @@ export class SnowWeather implements IWeather {
} }
} }
WeatherController.register(SnowWeather);
class SnowShader extends Shader { class SnowShader extends Shader {
static snowProgram: ShaderProgram; static snowProgram: ShaderProgram;
static backProgram: ShaderProgram; static backProgram: ShaderProgram;

View File

@ -1,4 +1,4 @@
import { IWeather } from './weather'; import { IWeather, WeatherController } from './weather';
export class SunWeather implements IWeather { export class SunWeather implements IWeather {
static id: string = 'sun'; static id: string = 'sun';
@ -9,3 +9,5 @@ export class SunWeather implements IWeather {
deactivate(): void {} deactivate(): void {}
} }
WeatherController.register(SunWeather);

View File

@ -1,12 +1,11 @@
import { logger } from '@/core/common/logger'; import { logger } from '@/core/common/logger';
import { RenderItem } from '@/core/render';
import { Ticker } from 'mutate-animate'; import { Ticker } from 'mutate-animate';
export interface IWeather { export interface IWeather {
/** /**
* *
*/ */
activate(item: RenderItem): void; activate(): void;
/** /**
* *
@ -16,25 +15,21 @@ export interface IWeather {
/** /**
* *
*/ */
deactivate(item: RenderItem): void; deactivate(): void;
} }
type Weather = new (level?: number) => IWeather; interface Weather<T extends IWeather = IWeather> {
id: string;
new (level?: number): T;
}
export class WeatherController { export class WeatherController {
static list: Map<string, Weather> = new Map(); static list: Map<string, Weather> = new Map();
static map: Map<string, WeatherController> = new Map();
/** 当前的所有天气 */ /** 当前的所有天气 */
active: Set<IWeather> = new Set(); active: Set<IWeather> = new Set();
ticker: Ticker = new Ticker(); ticker: Ticker = new Ticker();
private binded?: RenderItem;
constructor(public readonly id: string) {
WeatherController.map.set(id, this);
}
private tick = () => { private tick = () => {
this.active.forEach(v => { this.active.forEach(v => {
v.frame(); v.frame();
@ -45,11 +40,9 @@ export class WeatherController {
* *
*/ */
clearWeather() { clearWeather() {
if (this.binded) { this.active.forEach(v => {
this.active.forEach(v => { v.deactivate();
v.deactivate(this.binded!); });
});
}
this.active.clear(); this.active.clear();
} }
@ -57,7 +50,7 @@ export class WeatherController {
* *
* @param weather * @param weather
*/ */
getWeather<T extends IWeather = IWeather>(weather: Weather): T | null { getWeather<T extends IWeather>(weather: Weather<T>): T | null {
return ([...this.active].find(v => v instanceof weather) as T) ?? null; return ([...this.active].find(v => v instanceof weather) as T) ?? null;
} }
@ -75,9 +68,7 @@ export class WeatherController {
} }
const weather = new Weather(level); const weather = new Weather(level);
this.active.add(weather); this.active.add(weather);
if (this.binded) { weather.activate();
weather.activate(this.binded);
}
if (!this.ticker.funcs.has(this.tick)) { if (!this.ticker.funcs.has(this.tick)) {
this.ticker.add(this.tick); this.ticker.add(this.tick);
} }
@ -93,37 +84,10 @@ export class WeatherController {
if (this.active.size === 0) { if (this.active.size === 0) {
this.ticker.remove(this.tick); this.ticker.remove(this.tick);
} }
if (this.binded) { weather.deactivate();
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);
} }
} }

View File

@ -20,8 +20,8 @@ import {
} from './towerBossProjectile'; } from './towerBossProjectile';
import { IStateDamageable } from '@/game/state/interface'; import { IStateDamageable } from '@/game/state/interface';
import { HeroRenderer } from '@/core/render/preset/hero'; import { HeroRenderer } from '@/core/render/preset/hero';
import { controller } from '@/module/weather';
import { Pop } from '../fx/pop'; import { Pop } from '../fx/pop';
import { WeatherController } from '@/module';
Mota.require('var', 'loading').once('coreInit', () => { Mota.require('var', 'loading').once('coreInit', () => {
const shader = new Shader(); const shader = new Shader();
@ -401,8 +401,7 @@ export class TowerBoss extends BarrageBoss {
this.skill4Time = 5; this.skill4Time = 5;
this.skill5Time = 3; this.skill5Time = 3;
core.playBgm('towerBoss2.opus'); core.playBgm('towerBoss2.opus');
const weather = WeatherController.get('main'); controller.activate('rain', 6);
weather?.activate('rain', 6);
} }
releaseSkill4() { releaseSkill4() {