Files
OpenFrontIO/src/client/graphics/fx/UnitExplosionFx.ts
T
DevelopingTom e8834e15e6 Add naval combat animations (#858)
## Description:


https://github.com/user-attachments/assets/b46f949a-eb50-4656-8492-216cf820ac46

Add a couple animations for naval combat:

- shell hit
- ship explosion
- ship sinking

Added a simple `Timeline` class to spread FX animations over time.
Added a `ColoredAnimatedSprite` similar to the existing `ColoredSprite`.
Refactored the latter to avoid code duplication.

## Please complete the following:

- [x] I have added screenshots for all UI updates
- [x] I confirm I have thoroughly tested these changes and take full
responsibility for any bugs introduced
- [x] I understand that submitting code with bugs that could have been
caught through manual testing blocks releases and new features for all
contributors

## Please put your Discord username so you can be contacted if a bug or
regression is found:

IngloriousTom
2025-05-26 19:59:11 -04:00

48 lines
1.3 KiB
TypeScript

import { GameView } from "../../../core/game/GameView";
import { AnimatedSpriteLoader } from "../AnimatedSpriteLoader";
import { Fx, FxType } from "./Fx";
import { SpriteFx } from "./SpriteFx";
import { Timeline } from "./Timeline";
/**
* Explosion Effect: a few timed explosions
*/
export class UnitExplosionFx implements Fx {
private timeline = new Timeline();
private explosions: Fx[] = [];
constructor(
animatedSpriteLoader: AnimatedSpriteLoader,
private x: number,
private y: number,
game: GameView,
) {
const config = [
{ dx: 0, dy: 0, delay: 0, type: FxType.UnitExplosion },
{ dx: 4, dy: -6, delay: 80, type: FxType.UnitExplosion },
{ dx: -6, dy: 4, delay: 160, type: FxType.UnitExplosion },
];
for (const { dx, dy, delay, type } of config) {
this.timeline.add(delay, () => {
if (game.isValidCoord(x + dx, y + dy)) {
this.explosions.push(
new SpriteFx(animatedSpriteLoader, x + dx, y + dy, type),
);
}
});
}
}
renderTick(frameTime: number, ctx: CanvasRenderingContext2D): boolean {
this.timeline.update(frameTime);
let allDone = true;
for (const fx of this.explosions) {
if (fx.renderTick(frameTime, ctx)) {
allDone = false;
}
}
return !allDone || !this.timeline.isComplete();
}
}