mirror of
https://github.com/unanmed/HumanBreak.git
synced 2025-09-17 11:11:47 +08:00
feat: 晴天天气
This commit is contained in:
parent
0fc77f5007
commit
1b8624041b
@ -56,5 +56,6 @@ export * from './ui';
|
|||||||
export * from './utils';
|
export * from './utils';
|
||||||
export * from './weather';
|
export * from './weather';
|
||||||
export * from './renderer';
|
export * from './renderer';
|
||||||
|
export * from './scene';
|
||||||
export * from './shared';
|
export * from './shared';
|
||||||
export * from './use';
|
export * from './use';
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
import { WeatherController } from './controller';
|
import { WeatherController } from './controller';
|
||||||
import { CloudWeather, RainWeather } from './presets';
|
import { CloudWeather, RainWeather, SunWeather } from './presets';
|
||||||
|
|
||||||
export function createWeather() {
|
export function createWeather() {
|
||||||
WeatherController.register('cloud', CloudWeather);
|
WeatherController.register('cloud', CloudWeather);
|
||||||
WeatherController.register('rain', RainWeather);
|
WeatherController.register('rain', RainWeather);
|
||||||
|
WeatherController.register('sun', SunWeather);
|
||||||
// WeatherController.register('snow', SnowWeather);
|
// WeatherController.register('snow', SnowWeather);
|
||||||
// WeatherController.register('sun', SunWeather);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export * from './presets';
|
export * from './presets';
|
||||||
|
@ -17,7 +17,7 @@ export class CloudWeather extends Weather<Sprite> {
|
|||||||
/** 云层图像 */
|
/** 云层图像 */
|
||||||
private image: HTMLImageElement | null = null;
|
private image: HTMLImageElement | null = null;
|
||||||
/** 上一次执行速度变换的时刻 */
|
/** 上一次执行速度变换的时刻 */
|
||||||
private lastDvTime = 0;
|
private lastTick = 0;
|
||||||
|
|
||||||
private drawCloud(canvas: MotaOffscreenCanvas2D) {
|
private drawCloud(canvas: MotaOffscreenCanvas2D) {
|
||||||
const ctx = canvas.ctx;
|
const ctx = canvas.ctx;
|
||||||
@ -38,31 +38,33 @@ export class CloudWeather extends Weather<Sprite> {
|
|||||||
tick(time: number): void {
|
tick(time: number): void {
|
||||||
if (!this.element || !this.image) return;
|
if (!this.element || !this.image) return;
|
||||||
this.element.update();
|
this.element.update();
|
||||||
if (time - this.lastDvTime > 50) {
|
const dt = time - this.lastTick;
|
||||||
this.lastDvTime = time;
|
this.lastTick = time;
|
||||||
const dvx = ((Math.random() - 0.5) * this.level) / 20;
|
if (dt > 100) return;
|
||||||
const dvy = ((Math.random() - 0.5) * this.level) / 20;
|
const dvx = (Math.random() - 0.5) * this.level * 10;
|
||||||
if (Math.sign(dvx) === Math.sign(this.vx)) {
|
const dvy = (Math.random() - 0.5) * this.level * 10;
|
||||||
|
const addx = (dvx * dt) / 1000;
|
||||||
|
const addy = (dvy * dt) / 1000;
|
||||||
|
if (Math.sign(addx) === Math.sign(this.vx)) {
|
||||||
const ratio = Math.sqrt(
|
const ratio = Math.sqrt(
|
||||||
(this.maxSpeed - Math.abs(this.vx)) / this.maxSpeed
|
(this.maxSpeed - Math.abs(this.vx)) / this.maxSpeed
|
||||||
);
|
);
|
||||||
const value = Math.abs(dvx) * ratio;
|
const value = Math.abs(addx) * ratio;
|
||||||
this.vx += value * Math.sign(dvx);
|
this.vx += value * Math.sign(addx);
|
||||||
} else {
|
} else {
|
||||||
this.vx += dvx;
|
this.vx += addx;
|
||||||
}
|
}
|
||||||
if (Math.sign(dvy) === Math.sign(this.vy)) {
|
if (Math.sign(addy) === Math.sign(this.vy)) {
|
||||||
const ratio = Math.sqrt(
|
const ratio = Math.sqrt(
|
||||||
(this.maxSpeed - Math.abs(this.vy)) / this.maxSpeed
|
(this.maxSpeed - Math.abs(this.vy)) / this.maxSpeed
|
||||||
);
|
);
|
||||||
const value = Math.abs(dvy) * ratio;
|
const value = Math.abs(addy) * ratio;
|
||||||
this.vy += value * Math.sign(dvy);
|
this.vy += value * Math.sign(addy);
|
||||||
} else {
|
} else {
|
||||||
this.vy += dvy;
|
this.vy += addy;
|
||||||
}
|
}
|
||||||
}
|
this.cx += (this.vx * dt) / 1000;
|
||||||
this.cx += this.vx;
|
this.cy += (this.vy * dt) / 1000;
|
||||||
this.cy += this.vy;
|
|
||||||
this.cx %= this.image.width;
|
this.cx %= this.image.width;
|
||||||
this.cy %= this.image.height;
|
this.cy %= this.image.height;
|
||||||
}
|
}
|
||||||
@ -70,7 +72,7 @@ export class CloudWeather extends Weather<Sprite> {
|
|||||||
createElement(level: number): Sprite {
|
createElement(level: number): Sprite {
|
||||||
const element = new Sprite('static', true);
|
const element = new Sprite('static', true);
|
||||||
element.setRenderFn(canvas => this.drawCloud(canvas));
|
element.setRenderFn(canvas => this.drawCloud(canvas));
|
||||||
this.maxSpeed = Math.sqrt(level) * 5;
|
this.maxSpeed = Math.sqrt(level) * 100;
|
||||||
this.vx = ((Math.random() - 0.5) * this.maxSpeed) / 2;
|
this.vx = ((Math.random() - 0.5) * this.maxSpeed) / 2;
|
||||||
this.vy = ((Math.random() - 0.5) * this.maxSpeed) / 2;
|
this.vy = ((Math.random() - 0.5) * this.maxSpeed) / 2;
|
||||||
this.alpha = Math.sqrt(level) / 10;
|
this.alpha = Math.sqrt(level) / 10;
|
||||||
|
@ -1,16 +1,55 @@
|
|||||||
import { Sprite } from '@motajs/render-core';
|
import { MotaOffscreenCanvas2D, Sprite } from '@motajs/render-core';
|
||||||
import { Weather } from '../weather';
|
import { Weather } from '../weather';
|
||||||
|
import { clamp } from 'lodash-es';
|
||||||
|
|
||||||
export class SunWeather extends Weather<Sprite> {
|
export class SunWeather extends Weather<Sprite> {
|
||||||
|
/** 阳光图片 */
|
||||||
|
private image: HTMLImageElement | null = null;
|
||||||
|
/** 阳光图片的不透明度 */
|
||||||
|
private alpha: number = 0;
|
||||||
|
/** 阳光的最大不透明度 */
|
||||||
|
private maxAlpha: number = 0;
|
||||||
|
/** 阳光的最小不透明度 */
|
||||||
|
private minAlpha: number = 0;
|
||||||
|
/** 不透明度变化率 */
|
||||||
|
private va: number = 0;
|
||||||
|
/** 上一帧的时刻 */
|
||||||
|
private lastTick: number = 0;
|
||||||
|
|
||||||
|
drawSun(canvas: MotaOffscreenCanvas2D) {
|
||||||
|
if (!this.image) return;
|
||||||
|
const ctx = canvas.ctx;
|
||||||
|
ctx.globalAlpha = this.alpha;
|
||||||
|
ctx.drawImage(this.image, 0, 0, canvas.width, canvas.height);
|
||||||
|
}
|
||||||
|
|
||||||
tick(timestamp: number): void {
|
tick(timestamp: number): void {
|
||||||
throw new Error('Method not implemented.');
|
this.element?.update();
|
||||||
|
const dt = timestamp - this.lastTick;
|
||||||
|
this.lastTick = timestamp;
|
||||||
|
if (dt > 100) return;
|
||||||
|
const aa = (Math.random() - 0.5) * this.level;
|
||||||
|
this.va += (aa * dt) / 1000;
|
||||||
|
this.va = clamp(this.va, 0.1);
|
||||||
|
this.alpha += (this.va * dt) / 1000;
|
||||||
|
if (this.alpha < this.minAlpha) {
|
||||||
|
this.va = Math.abs(this.va);
|
||||||
|
this.alpha = this.minAlpha;
|
||||||
|
} else if (this.alpha > this.maxAlpha) {
|
||||||
|
this.va = -Math.abs(this.va);
|
||||||
|
this.alpha = this.maxAlpha;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
createElement(level: number): Sprite {
|
createElement(level: number): Sprite {
|
||||||
throw new Error('Method not implemented.');
|
const element = new Sprite('static', true);
|
||||||
|
element.setRenderFn(canvas => this.drawSun(canvas));
|
||||||
|
this.maxAlpha = level / 10;
|
||||||
|
this.minAlpha = level / 20;
|
||||||
|
this.alpha = (this.maxAlpha + this.minAlpha) / 2;
|
||||||
|
this.image = core.material.images.images['sun.png'];
|
||||||
|
return element;
|
||||||
}
|
}
|
||||||
|
|
||||||
onDestroy(): void {
|
onDestroy(): void {}
|
||||||
throw new Error('Method not implemented.');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -108,6 +108,7 @@ export class ImageResource extends Resource<HTMLImageElement> {
|
|||||||
img.src = this.resolveURI();
|
img.src = this.resolveURI();
|
||||||
this.resource = img;
|
this.resource = img;
|
||||||
return new Promise<HTMLImageElement>(res => {
|
return new Promise<HTMLImageElement>(res => {
|
||||||
|
img.loading = 'eager';
|
||||||
img.addEventListener('load', () => {
|
img.addEventListener('load', () => {
|
||||||
this.loaded = true;
|
this.loaded = true;
|
||||||
img.setAttribute('_width', img.width.toString());
|
img.setAttribute('_width', img.width.toString());
|
||||||
@ -575,7 +576,7 @@ export function loadDefaultResource() {
|
|||||||
] = res.resource;
|
] = res.resource;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
const weathers: (keyof Weather)[] = ['fog', 'sun'];
|
const weathers: (keyof Weather)[] = ['fog'];
|
||||||
weathers.forEach(v => {
|
weathers.forEach(v => {
|
||||||
const res = LoadTask.add('material', `material/${v}.png`);
|
const res = LoadTask.add('material', `material/${v}.png`);
|
||||||
res.once('load', res => {
|
res.once('load', res => {
|
||||||
@ -618,7 +619,7 @@ export async function loadCompressedResource() {
|
|||||||
HTMLImageElement
|
HTMLImageElement
|
||||||
>[];
|
>[];
|
||||||
materialImages.push('keyboard');
|
materialImages.push('keyboard');
|
||||||
const weathers: (keyof Weather)[] = ['fog', 'sun'];
|
const weathers: (keyof Weather)[] = ['fog'];
|
||||||
|
|
||||||
Object.entries(list).forEach(v => {
|
Object.entries(list).forEach(v => {
|
||||||
const [uri, list] = v;
|
const [uri, list] = v;
|
||||||
|
@ -150,6 +150,7 @@ var data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d =
|
|||||||
"skill7.png",
|
"skill7.png",
|
||||||
"skill8.png",
|
"skill8.png",
|
||||||
"skill9.png",
|
"skill9.png",
|
||||||
|
"sun.png",
|
||||||
"tower7.webp",
|
"tower7.webp",
|
||||||
"winskin.png",
|
"winskin.png",
|
||||||
"winskin2.png",
|
"winskin2.png",
|
||||||
|
Before Width: | Height: | Size: 98 KiB After Width: | Height: | Size: 98 KiB |
1
src/types/source/data.d.ts
vendored
1
src/types/source/data.d.ts
vendored
@ -138,6 +138,7 @@ type ImageIds =
|
|||||||
| 'skill7.png'
|
| 'skill7.png'
|
||||||
| 'skill8.png'
|
| 'skill8.png'
|
||||||
| 'skill9.png'
|
| 'skill9.png'
|
||||||
|
| 'sun.png'
|
||||||
| 'tower7.webp'
|
| 'tower7.webp'
|
||||||
| 'winskin.png'
|
| 'winskin.png'
|
||||||
| 'winskin2.png'
|
| 'winskin2.png'
|
||||||
|
Loading…
Reference in New Issue
Block a user