//-----------------------------------------------------------------------------
/**
* The basic object that is rendered to the game screen.
*
* @class
* @extends PIXI.Sprite
* @param {Bitmap} bitmap - The image for the sprite.
*/
function Sprite() {
this.initialize(...arguments);
}
Sprite.prototype = Object.create(PIXI.Sprite.prototype);
Sprite.prototype.constructor = Sprite;
Sprite.prototype.initialize = function(bitmap) {
if (!Sprite._emptyBaseTexture) {
Sprite._emptyBaseTexture = new PIXI.BaseTexture();
Sprite._emptyBaseTexture.setSize(1, 1);
}
const frame = new Rectangle();
const texture = new PIXI.Texture(Sprite._emptyBaseTexture, frame);
PIXI.Sprite.call(this, texture);
this.spriteId = Sprite._counter++;
this._bitmap = bitmap;
this._frame = frame;
this._hue = 0;
this._blendColor = [0, 0, 0, 0];
this._colorTone = [0, 0, 0, 0];
this._colorFilter = null;
this._blendMode = PIXI.BLEND_MODES.NORMAL;
this._hidden = false;
this._onBitmapChange();
};
Sprite._emptyBaseTexture = null;
Sprite._counter = 0;
/**
* The image for the sprite.
*
* @type Bitmap
* @name Sprite#bitmap
*/
Object.defineProperty(Sprite.prototype, "bitmap", {
get: function() {
return this._bitmap;
},
set: function(value) {
if (this._bitmap !== value) {
this._bitmap = value;
this._onBitmapChange();
}
},
configurable: true
});
/**
* The width of the sprite without the scale.
*
* @type number
* @name Sprite#width
*/
Object.defineProperty(Sprite.prototype, "width", {
get: function() {
return this._frame.width;
},
set: function(value) {
this._frame.width = value;
this._refresh();
},
configurable: true
});
/**
* The height of the sprite without the scale.
*
* @type number
* @name Sprite#height
*/
Object.defineProperty(Sprite.prototype, "height", {
get: function() {
return this._frame.height;
},
set: function(value) {
this._frame.height = value;
this._refresh();
},
configurable: true
});
/**
* The opacity of the sprite (0 to 255).
*
* @type number
* @name Sprite#opacity
*/
Object.defineProperty(Sprite.prototype, "opacity", {
get: function() {
return this.alpha * 255;
},
set: function(value) {
this.alpha = value.clamp(0, 255) / 255;
},
configurable: true
});
/**
* The blend mode to be applied to the sprite.
*
* @type number
* @name Sprite#blendMode
*/
Object.defineProperty(Sprite.prototype, "blendMode", {
get: function() {
if (this._colorFilter) {
return this._colorFilter.blendMode;
} else {
return this._blendMode;
}
},
set: function(value) {
this._blendMode = value;
if (this._colorFilter) {
this._colorFilter.blendMode = value;
}
},
configurable: true
});
/**
* Destroys the sprite.
*/
Sprite.prototype.destroy = function() {
const options = { children: true, texture: true };
PIXI.Sprite.prototype.destroy.call(this, options);
};
/**
* Updates the sprite for each frame.
*/
Sprite.prototype.update = function() {
for (const child of this.children) {
if (child.update) {
child.update();
}
}
};
/**
* Makes the sprite "hidden".
*/
Sprite.prototype.hide = function() {
this._hidden = true;
this.updateVisibility();
};
/**
* Releases the "hidden" state of the sprite.
*/
Sprite.prototype.show = function() {
this._hidden = false;
this.updateVisibility();
};
/**
* Reflects the "hidden" state of the sprite to the visible state.
*/
Sprite.prototype.updateVisibility = function() {
this.visible = !this._hidden;
};
/**
* Sets the x and y at once.
*
* @param {number} x - The x coordinate of the sprite.
* @param {number} y - The y coordinate of the sprite.
*/
Sprite.prototype.move = function(x, y) {
this.x = x;
this.y = y;
};
/**
* Sets the rectagle of the bitmap that the sprite displays.
*
* @param {number} x - The x coordinate of the frame.
* @param {number} y - The y coordinate of the frame.
* @param {number} width - The width of the frame.
* @param {number} height - The height of the frame.
*/
Sprite.prototype.setFrame = function(x, y, width, height) {
this._refreshFrame = false;
const frame = this._frame;
if (
x !== frame.x ||
y !== frame.y ||
width !== frame.width ||
height !== frame.height
) {
frame.x = x;
frame.y = y;
frame.width = width;
frame.height = height;
this._refresh();
}
};
/**
* Sets the hue rotation value.
*
* @param {number} hue - The hue value (-360, 360).
*/
Sprite.prototype.setHue = function(hue) {
if (this._hue !== Number(hue)) {
this._hue = Number(hue);
this._updateColorFilter();
}
};
/**
* Gets the blend color for the sprite.
*
* @returns {array} The blend color [r, g, b, a].
*/
Sprite.prototype.getBlendColor = function() {
return this._blendColor.clone();
};
/**
* Sets the blend color for the sprite.
*
* @param {array} color - The blend color [r, g, b, a].
*/
Sprite.prototype.setBlendColor = function(color) {
if (!(color instanceof Array)) {
throw new Error("Argument must be an array");
}
if (!this._blendColor.equals(color)) {
this._blendColor = color.clone();
this._updateColorFilter();
}
};
/**
* Gets the color tone for the sprite.
*
* @returns {array} The color tone [r, g, b, gray].
*/
Sprite.prototype.getColorTone = function() {
return this._colorTone.clone();
};
/**
* Sets the color tone for the sprite.
*
* @param {array} tone - The color tone [r, g, b, gray].
*/
Sprite.prototype.setColorTone = function(tone) {
if (!(tone instanceof Array)) {
throw new Error("Argument must be an array");
}
if (!this._colorTone.equals(tone)) {
this._colorTone = tone.clone();
this._updateColorFilter();
}
};
Sprite.prototype._onBitmapChange = function() {
if (this._bitmap) {
this._refreshFrame = true;
this._bitmap.addLoadListener(this._onBitmapLoad.bind(this));
} else {
this._refreshFrame = false;
this.texture.frame = new Rectangle();
}
};
Sprite.prototype._onBitmapLoad = function(bitmapLoaded) {
if (bitmapLoaded === this._bitmap) {
if (this._refreshFrame && this._bitmap) {
this._refreshFrame = false;
this._frame.width = this._bitmap.width;
this._frame.height = this._bitmap.height;
}
}
this._refresh();
};
Sprite.prototype._refresh = function() {
const texture = this.texture;
const frameX = Math.floor(this._frame.x);
const frameY = Math.floor(this._frame.y);
const frameW = Math.floor(this._frame.width);
const frameH = Math.floor(this._frame.height);
const baseTexture = this._bitmap ? this._bitmap.baseTexture : null;
const baseTextureW = baseTexture ? baseTexture.width : 0;
const baseTextureH = baseTexture ? baseTexture.height : 0;
const realX = frameX.clamp(0, baseTextureW);
const realY = frameY.clamp(0, baseTextureH);
const realW = (frameW - realX + frameX).clamp(0, baseTextureW - realX);
const realH = (frameH - realY + frameY).clamp(0, baseTextureH - realY);
const frame = new Rectangle(realX, realY, realW, realH);
if (texture) {
this.pivot.x = frameX - realX;
this.pivot.y = frameY - realY;
if (baseTexture) {
texture.baseTexture = baseTexture;
try {
texture.frame = frame;
} catch (e) {
texture.frame = new Rectangle();
}
}
texture._updateID++;
}
};
Sprite.prototype._createColorFilter = function() {
this._colorFilter = new ColorFilter();
if (!this.filters) {
this.filters = [];
}
this.filters.push(this._colorFilter);
};
Sprite.prototype._updateColorFilter = function() {
if (!this._colorFilter) {
this._createColorFilter();
}
this._colorFilter.setHue(this._hue);
this._colorFilter.setBlendColor(this._blendColor);
this._colorFilter.setColorTone(this._colorTone);
};