mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-08-18 17:53:29 +00:00
Add new FX layer and a nuke animation (#807)
## Description: Changes: - Added an AnimatedSprite class to handle spritesheets - New FX layer, displaying cosmectics effects - New Nuke FX: an animated sprite explosion, and a shockwave effect - New "Special effects" setting, toggle to deactivate the FX layer for lower-end hardware / personal taste #### Note that the animation is a placeholder. It should be replaced when a better looking one is available. - Nuke: https://github.com/user-attachments/assets/6eff1d0d-5081-47ad-932f-2bfcda72cb3c - Mirv: https://github.com/user-attachments/assets/3bc891b4-449c-4acb-8e24-e237b423c2a9 - SAM are also using the same Nuke animation. To be improved with a custom FX: https://github.com/user-attachments/assets/d65addce-5890-42c2-81e0-3eaa79ed87f3 ## Performances: Excellent since it's not manipulating the underlying imagedata directly. Profiling during a MIRV with 100's of animations:  ### New settings: - main menu:  - In game:  ## 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
This commit is contained in:
@@ -0,0 +1,7 @@
|
||||
export interface Fx {
|
||||
renderTick(duration: number, ctx: CanvasRenderingContext2D): boolean;
|
||||
}
|
||||
|
||||
export enum FxType {
|
||||
Nuke = "Nuke",
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
import { AnimatedSprite } from "../AnimatedSprite";
|
||||
import { createAnimatedSpriteForUnit } from "../AnimatedSpriteLoader";
|
||||
import { Fx, FxType } from "./Fx";
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Explosion effect: sprite animation of an explosion
|
||||
*/
|
||||
export class NukeExplosionFx implements Fx {
|
||||
private lifeTime: number = 0;
|
||||
private nukeExplosionSprite: AnimatedSprite | null;
|
||||
constructor(
|
||||
private x: number,
|
||||
private y: number,
|
||||
private duration: number,
|
||||
) {
|
||||
this.nukeExplosionSprite = createAnimatedSpriteForUnit(FxType.Nuke);
|
||||
}
|
||||
|
||||
renderTick(frameTime: number, ctx: CanvasRenderingContext2D): boolean {
|
||||
if (this.nukeExplosionSprite) {
|
||||
this.lifeTime += frameTime;
|
||||
if (this.lifeTime >= this.duration) {
|
||||
return false;
|
||||
}
|
||||
if (this.nukeExplosionSprite.isActive()) {
|
||||
this.nukeExplosionSprite.update(frameTime);
|
||||
this.nukeExplosionSprite.draw(ctx, this.x, this.y);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user