mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-06-21 10:10:55 +00:00
e246289876
This reverts commit ec694593a6.
111 lines
2.8 KiB
TypeScript
111 lines
2.8 KiB
TypeScript
import { GameView } from "../../../core/game/GameView";
|
|
import { AnimatedSpriteLoader } from "../AnimatedSpriteLoader";
|
|
import { Fx, FxType } from "./Fx";
|
|
import { FadeFx, SpriteFx } from "./SpriteFx";
|
|
|
|
/**
|
|
* Shockwave effect: draw a growing 1px white circle
|
|
*/
|
|
export class ShockwaveFx implements Fx {
|
|
private lifeTime: number = 0;
|
|
constructor(
|
|
private x: number,
|
|
private y: number,
|
|
private duration: number,
|
|
private maxRadius: number,
|
|
) {}
|
|
|
|
renderTick(frameTime: number, ctx: CanvasRenderingContext2D): boolean {
|
|
this.lifeTime += frameTime;
|
|
if (this.lifeTime >= this.duration) {
|
|
return false;
|
|
}
|
|
const t = this.lifeTime / this.duration;
|
|
const radius = t * this.maxRadius;
|
|
ctx.beginPath();
|
|
ctx.arc(this.x, this.y, radius, 0, Math.PI * 2);
|
|
ctx.strokeStyle = "rgba(255, 255, 255, " + (1 - t) + ")";
|
|
ctx.lineWidth = 0.5;
|
|
ctx.stroke();
|
|
return true;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Spawn @p number of @p type animation within a perimeter
|
|
*/
|
|
function addSpriteInCircle(
|
|
animatedSpriteLoader: AnimatedSpriteLoader,
|
|
x: number,
|
|
y: number,
|
|
radius: number,
|
|
num: number,
|
|
type: FxType,
|
|
result: Fx[],
|
|
game: GameView,
|
|
) {
|
|
const count = Math.max(0, Math.floor(num));
|
|
for (let i = 0; i < count; i++) {
|
|
const angle = Math.random() * 2 * Math.PI;
|
|
const distance = Math.random() * (radius / 2);
|
|
const spawnX = Math.floor(x + Math.cos(angle) * distance);
|
|
const spawnY = Math.floor(y + Math.sin(angle) * distance);
|
|
if (
|
|
game.isValidCoord(spawnX, spawnY) &&
|
|
game.isLand(game.ref(spawnX, spawnY))
|
|
) {
|
|
const sprite = new FadeFx(
|
|
new SpriteFx(animatedSpriteLoader, spawnX, spawnY, type, 6000),
|
|
0.1,
|
|
0.8,
|
|
);
|
|
result.push(sprite as Fx);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Explosion effect:
|
|
* - explosion animation
|
|
* - shockwave
|
|
* - ruins and desolation fx
|
|
*/
|
|
export function nukeFxFactory(
|
|
animatedSpriteLoader: AnimatedSpriteLoader,
|
|
x: number,
|
|
y: number,
|
|
radius: number,
|
|
game: GameView,
|
|
): Fx[] {
|
|
const nukeFx: Fx[] = [];
|
|
// Explosion animation
|
|
nukeFx.push(new SpriteFx(animatedSpriteLoader, x, y, FxType.Nuke));
|
|
// Shockwave animation
|
|
nukeFx.push(new ShockwaveFx(x, y, 1500, radius * 1.5));
|
|
// Ruins and desolation sprites
|
|
const debrisPlan: Array<{
|
|
type: FxType;
|
|
radiusFactor: number;
|
|
density: number;
|
|
}> = [
|
|
{ type: FxType.MiniFire, radiusFactor: 1.0, density: 1 / 25 },
|
|
{ type: FxType.MiniSmoke, radiusFactor: 1.0, density: 1 / 28 },
|
|
{ type: FxType.MiniBigSmoke, radiusFactor: 0.9, density: 1 / 70 },
|
|
{ type: FxType.MiniSmokeAndFire, radiusFactor: 0.9, density: 1 / 70 },
|
|
];
|
|
|
|
for (const { type, radiusFactor, density } of debrisPlan) {
|
|
addSpriteInCircle(
|
|
animatedSpriteLoader,
|
|
x,
|
|
y,
|
|
radius * radiusFactor,
|
|
radius * density,
|
|
type,
|
|
nukeFx,
|
|
game,
|
|
);
|
|
}
|
|
return nukeFx;
|
|
}
|