/**
* Отображает временные сообщения в нижнем левом углу экрана.
* @param {Game} game игра
* @param {string} [name] имя фида
* @class
* @extends {external:Phaser.Group}
*/
var MessageFeed = function(game, name){
/**
* Стили текста.
* @type {Object}
* @property {object} system Белый текст 30px
* @property {object} warning Красный текст 40px
*/
this.styles = {
system: {fill: 'white', font: '30px Exo, Helvetica', wordWrap: true},
warning: {fill: 'red', font: '40px Exo, Helvetica',wordWrap: true}
};
/**
* Время фейда сообщений.
* @type {Number}
*/
this.fadeTime = 300;
Phaser.Group.call(this, game);
/**
* Имя фида для {@link UI.Layers}.
* @type {string}
*/
this.name = name || 'feed';
};
extend(MessageFeed, Phaser.Group);
/**
* Выводит новое сообщение.
* @param {string} message Сообщение.
* @param {string|object} [style='system'] объект со свойствами текста
* или строка, соответствующая стилю из `styles`.
*
* @param {number} [time] Время, после которого сообщение пропадет.
* Если не указать, сообщение нужно вручную удалять,
* передавая в `removeMessage`.
* Может быть вторым параметром, вместо `style`.
*
* @return {Phaser.Text} Созданный текст объект с сообщением.
*/
MessageFeed.prototype.newMessage = function(message, style, time){
if(typeof style == 'number'){
time = style;
style = undefined;
}
if(style === undefined){
style = 'system';
}
if(typeof style == 'string'){
style = this.styles[style];
}
var text = this._createText(message, style);
if(time !== undefined){
text.endTime = Date.now() + time;
}
this.add(text);
this._fadeInMessage(text);
this.updatePosition();
return text;
};
/**
* Создает текстовый элемент и применяет к нему стиль.
* @param {string} message Сообщение.
* @param {object} style Стиль.
*
* @return {Phaser.Text} Текстовый элемент.
*/
MessageFeed.prototype._createText = function(message, style){
var text = this.game.make.text(this._getX(), this._getLowestY(), message, style);
this._styleText(text);
return text;
};
/**
* Применяет дополнительные стили к тексту.
*/
MessageFeed.prototype._styleText = function(text){
text.setShadow(2, 2, 'rgba(0,0,0,0.8)', 2);
text.anchor.set(0, 1);
};
/**
* Возвращает позицию сообщений по горизонтали.
* @return {number} Позиция по горизонтали.
*/
MessageFeed.prototype._getX = function(){
return 20;
};
/**
* Возвращает позицию, над которой отображаются новые сообщения.
* @return {number} Позиция по вертикали.
*/
MessageFeed.prototype._getLowestY = function(){
return this.game.screenHeight - 10;
};
/**
* Удаляет переданное отображаемое сообщение, устанавливая его `endTime` на текущее время.
* @param {Phaser.Text} text Сообщение, которое нужно удалить.
*/
MessageFeed.prototype.removeMessage = function(text){
if(!~this.children.indexOf(text) || text.destroyTime !== undefined){
return;
}
text.endTime = Date.now();
this.update();
};
/**
* Удаляет сообщение с указанным индексом.
* @param {number} i индекс сообщения
*/
MessageFeed.prototype.removeMessageAt = function(i){
if(this.children[i]){
this.removeMessage(this.children[i]);
}
};
/**
* Удаляет первое добавленное сообщение (с нулевым индексом).
*/
MessageFeed.prototype.nextMessage = function(){
this.removeMessageAt(0);
};
/**
* Удаляет все отображаемые сообщения, устанавливая их `endTime` на текущее время.
*/
MessageFeed.prototype.clear = function(){
var i = this.children.length;
while (i--){
var text = this.children[i];
if(text.destroyTime === undefined){
text.endTime = Date.now();
}
}
};
/**
* Фейдид и удаляет сообщения, время жизни которых истекло.
*/
MessageFeed.prototype.update = function(){
var i = this.children.length;
var now = Date.now();
while (i--){
var text = this.children[i];
if(text.destroyTime !== undefined){
if(text.destroyTime <= now){
this._destroyMessage(text);
}
}
else if(text.endTime !== undefined && text.endTime <= now){
this._fadeOutMessage(text);
this.updatePosition();
}
}
};
/**
* Удаляет сообщение.
* @param {Phaser.Text} text Текст для удаления.
*/
MessageFeed.prototype._destroyMessage = function(text){
if(text.fadeTween){
text.fadeTween.stop();
}
if(text.moveTween){
text.moveTween.stop();
}
this.remove(text, true);
};
/**
* Фейдид сообщение перед удалением.
* @param {Phaser.Text} text Текст.
*/
MessageFeed.prototype._fadeOutMessage = function(text){
text.destroyTime = Date.now() + this.fadeTime;
if(text.fadeTween){
text.fadeTween.stop();
}
text.fadeTween = this.game.add.tween(text);
text.fadeTween.to({alpha: 0}, this.fadeTime, Phaser.Easing.Quadratic.Out, true);
};
/**
* Фейдид сообщение при добавлении.
* @param {Phaser.Text} text Текст.
*/
MessageFeed.prototype._fadeInMessage = function(text){
text.alpha = 0;
text.fadeTween = this.game.add.tween(text);
text.fadeTween.to({alpha: 1}, this.fadeTime, Phaser.Easing.Quadratic.Out, true);
};
/**
* Устанавливает правильные позиции сообщениям.
*/
MessageFeed.prototype.updatePosition = function(){
var y = this._getLowestY();
var x = this._getX();
var i, ii;
for(i = ii = this.children.length - 1; i >= 0; i--){
var text = this.children[i];
if(text.destroyTime !== undefined){
continue;
}
text.wordWrapWidth = game.screenWidth;
this._moveMessage(text, i, ii, x, y);
y -= text.height/Math.min(text.scale.y, 1);
ii--;
}
};
/**
* Передвигает сообщение в заданную позицию.
* @param {Phaser.Text} text Сообщение.
* @param {number} i Реальный индекс сообщения в `children`.
* @param {number} ii Индекс сообщения не учитывая сообщения с установленным `destroyTime`.
* @param {number} y Позиция сообщения по вертикали.
*/
MessageFeed.prototype._moveMessage = function(text, i, ii, x, y){
if(text.moveTween){
text.moveTween.stop();
}
text.moveTween = this.game.add.tween(text.position);
text.moveTween.to({x: x, y: y}, this.fadeTime, Phaser.Easing.Quadratic.Out, true);
};
//@include:AnnounceFeed
//@include:EventFeed