Source: Sprite_Damage.js

Sprite_Damage.js

//-----------------------------------------------------------------------------
// Sprite_Damage
//
// The sprite for displaying a popup damage.
/**
 * The sprite for displaying a popup damage.
 *
 * @class
 * @extends Sprite
 */
function Sprite_Damage() {
    this.initialize(...arguments);
}

Sprite_Damage.prototype = Object.create(Sprite.prototype);
Sprite_Damage.prototype.constructor = Sprite_Damage;

Sprite_Damage.prototype.initialize = function() {
    Sprite.prototype.initialize.call(this);
    this._duration = 90;
    this._flashColor = [0, 0, 0, 0];
    this._flashDuration = 0;
    this._colorType = 0;
};

Sprite_Damage.prototype.destroy = function(options) {
    for (const child of this.children) {
        if (child.bitmap) {
            child.bitmap.destroy();
        }
    }
    Sprite.prototype.destroy.call(this, options);
};

/**
 * Sets the sprite up
 *
 * @param {Game_Battler} target - The target to show the damage sprite for
 */
Sprite_Damage.prototype.setup = function(target) {
    const result = target.result();
    if (result.missed || result.evaded) {
        this._colorType = 0;
        this.createMiss();
    } else if (result.hpAffected) {
        this._colorType = result.hpDamage >= 0 ? 0 : 1;
        this.createDigits(result.hpDamage);
    } else if (target.isAlive() && result.mpDamage !== 0) {
        this._colorType = result.mpDamage >= 0 ? 2 : 3;
        this.createDigits(result.mpDamage);
    }
    if (result.critical) {
        this.setupCriticalEffect();
    }
};

/**
 * Sets the sprite's critical effect variables
 */
Sprite_Damage.prototype.setupCriticalEffect = function() {
    this._flashColor = [255, 0, 0, 160];
    this._flashDuration = 60;
};

/**
 * Gets the font face to use
 *
 * @return {string} The font face to use
 */
Sprite_Damage.prototype.fontFace = function() {
    return $gameSystem.numberFontFace();
};

/**
 * Gets the font size to use
 *
 * @return {number} The font size to use
 */
Sprite_Damage.prototype.fontSize = function() {
    return $gameSystem.mainFontSize() + 4;
};

/**
 * Gets the color to use for the damage color
 *
 * @return {string} The color string in hex format
 */
Sprite_Damage.prototype.damageColor = function() {
    return ColorManager.damageColor(this._colorType);
};

/**
 * Gets the color to use for the outline
 *
 * @return {string} The color string, by default rgba format
 */
Sprite_Damage.prototype.outlineColor = function() {
    return "rgba(0, 0, 0, 0.7)";
};

/**
 * Gets the outline width
 *
 * @return {number} The width of the outline
 */
Sprite_Damage.prototype.outlineWidth = function() {
    return 4;
};

/**
 * Creates the miss damage popup text
 */
Sprite_Damage.prototype.createMiss = function() {
    const h = this.fontSize();
    const w = Math.floor(h * 3.0);
    const sprite = this.createChildSprite(w, h);
    sprite.bitmap.drawText("Miss", 0, 0, w, h, "center");
    sprite.dy = 0;
};

/**
 * Creates the numbers that are part of the damage popup
 *
 * @param {number} value - The number to turn into damage popup digits
 */
Sprite_Damage.prototype.createDigits = function(value) {
    const string = Math.abs(value).toString();
    const h = this.fontSize();
    const w = Math.floor(h * 0.75);
    for (let i = 0; i < string.length; i++) {
        const sprite = this.createChildSprite(w, h);
        sprite.bitmap.drawText(string[i], 0, 0, w, h, "center");
        sprite.x = (i - (string.length - 1) / 2) * w;
        sprite.dy = -i;
    }
};

/**
 * Creates a child sprite of a given width and height
 *
 * @param {number} width - The width of the child sprite
 * @param {number} height - The height of the child sprite
 * @return {Sprite} The child sprite that was created
 */
Sprite_Damage.prototype.createChildSprite = function(width, height) {
    const sprite = new Sprite();
    sprite.bitmap = this.createBitmap(width, height);
    sprite.anchor.x = 0.5;
    sprite.anchor.y = 1;
    sprite.y = -40;
    sprite.ry = sprite.y;
    this.addChild(sprite);
    return sprite;
};

/**
 * Creates a bitmap with font, text color, and outline settings
 *
 * @param {number} width - The width of the bitmap
 * @param {number} height - The height of the bitmap
 * @return {Bitmap} The bitmap that was created
 */
Sprite_Damage.prototype.createBitmap = function(width, height) {
    const bitmap = new Bitmap(width, height);
    bitmap.fontFace = this.fontFace();
    bitmap.fontSize = this.fontSize();
    bitmap.textColor = this.damageColor();
    bitmap.outlineColor = this.outlineColor();
    bitmap.outlineWidth = this.outlineWidth();
    return bitmap;
};

Sprite_Damage.prototype.update = function() {
    Sprite.prototype.update.call(this);
    if (this._duration > 0) {
        this._duration--;
        for (const child of this.children) {
            this.updateChild(child);
        }
    }
    this.updateFlash();
    this.updateOpacity();
};

/**
 * Updates a child sprite
 *
 * @param {Sprite} sprite - The child sprite to update
 */
Sprite_Damage.prototype.updateChild = function(sprite) {
    sprite.dy += 0.5;
    sprite.ry += sprite.dy;
    if (sprite.ry >= 0) {
        sprite.ry = 0;
        sprite.dy *= -0.6;
    }
    sprite.y = Math.round(sprite.ry);
    sprite.setBlendColor(this._flashColor);
};

/**
 * Updates the flash effect
 */
Sprite_Damage.prototype.updateFlash = function() {
    if (this._flashDuration > 0) {
        const d = this._flashDuration--;
        this._flashColor[3] *= (d - 1) / d;
    }
};

/**
 * Updates the opacity
 */
Sprite_Damage.prototype.updateOpacity = function() {
    if (this._duration < 10) {
        this.opacity = (255 * this._duration) / 10;
    }
};

/**
 * Check if the damage popup is currently playing
 *
 * @return {boolean} True if currently playing
 */
Sprite_Damage.prototype.isPlaying = function() {
    return this._duration > 0;
};