first commit
This commit is contained in:
@@ -0,0 +1,104 @@
|
||||
/**
|
||||
* Explosion.js
|
||||
* Simple explosion effect using frame-based animation.
|
||||
* Managed via object pool for performance.
|
||||
*/
|
||||
|
||||
class Explosion {
|
||||
constructor() {
|
||||
this.x = 0;
|
||||
this.y = 0;
|
||||
this.alive = false;
|
||||
this.size = 0;
|
||||
this.maxSize = 30;
|
||||
this._timer = 0;
|
||||
this._duration = 0.3; // seconds
|
||||
this._phase = 0; // 0 to 1
|
||||
this._isBig = false; // big explosion for tank destruction
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the explosion.
|
||||
* @param {number} x - Center X.
|
||||
* @param {number} y - Center Y.
|
||||
* @param {boolean} [isBig=false] - Whether this is a large explosion (tank death).
|
||||
*/
|
||||
init(x, y, isBig = false) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.alive = true;
|
||||
this._timer = 0;
|
||||
this._phase = 0;
|
||||
this._isBig = isBig;
|
||||
this.maxSize = isBig ? 50 : 25;
|
||||
this._duration = isBig ? 0.5 : 0.3;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update explosion animation.
|
||||
* @param {number} dt - Delta time in seconds.
|
||||
*/
|
||||
update(dt) {
|
||||
if (!this.alive) return;
|
||||
|
||||
this._timer += dt;
|
||||
this._phase = this._timer / this._duration;
|
||||
|
||||
if (this._phase >= 1) {
|
||||
this.alive = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// Size grows then shrinks
|
||||
if (this._phase < 0.4) {
|
||||
this.size = this.maxSize * (this._phase / 0.4);
|
||||
} else {
|
||||
this.size = this.maxSize * (1 - (this._phase - 0.4) / 0.6);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the explosion.
|
||||
* @param {CanvasRenderingContext2D} ctx
|
||||
*/
|
||||
render(ctx) {
|
||||
if (!this.alive) return;
|
||||
|
||||
ctx.save();
|
||||
|
||||
const alpha = 1 - this._phase * 0.5;
|
||||
ctx.globalAlpha = alpha;
|
||||
|
||||
// Outer glow
|
||||
if (this._isBig) {
|
||||
ctx.fillStyle = '#FF4500';
|
||||
ctx.beginPath();
|
||||
ctx.arc(this.x, this.y, this.size * 1.2, 0, Math.PI * 2);
|
||||
ctx.fill();
|
||||
}
|
||||
|
||||
// Main explosion
|
||||
ctx.fillStyle = '#FF8C00';
|
||||
ctx.beginPath();
|
||||
ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2);
|
||||
ctx.fill();
|
||||
|
||||
// Inner bright core
|
||||
ctx.fillStyle = '#FFFF00';
|
||||
ctx.beginPath();
|
||||
ctx.arc(this.x, this.y, this.size * 0.5, 0, Math.PI * 2);
|
||||
ctx.fill();
|
||||
|
||||
// White center flash (early phase only)
|
||||
if (this._phase < 0.3) {
|
||||
ctx.fillStyle = '#FFFFFF';
|
||||
ctx.beginPath();
|
||||
ctx.arc(this.x, this.y, this.size * 0.2, 0, Math.PI * 2);
|
||||
ctx.fill();
|
||||
}
|
||||
|
||||
ctx.restore();
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Explosion;
|
||||
Reference in New Issue
Block a user