Skip to content

Instantly share code, notes, and snippets.

@aoitaku
Last active July 23, 2020 18:34
Show Gist options
  • Save aoitaku/d471416a73dbb13e69ea0ecf89b7134a to your computer and use it in GitHub Desktop.
Save aoitaku/d471416a73dbb13e69ea0ecf89b7134a to your computer and use it in GitHub Desktop.
//=============================================================================
// Lunatlazur_MessageTextShake.js
// ----------------------------------------------------------------------------
// Copyright (c) 2020 Taku Aoi
// This plugin is released under the zlib/libpng License.
// http://zlib.net/zlib_license.html
// ----------------------------------------------------------------------------
// Version
// 1.0.0 2020/07/24
// ----------------------------------------------------------------------------
// [Web] : https://lunatlazur.com/
// [Twitter]: https://twitter.com/aoitaku/
// [GitHub] : https://github.com/Lunatlazur/
//=============================================================================
/*:
* @plugindesc Add control sequence for message text shaking.
* @author Taku Aoi
* @help This plugin adds control sequence for message text shaking.
*
* Shake character(s) in message text between `\ANIME` and `\END`.
* Specified characters keep shaking until window closing.
*
* History
* *******
*
* 1.0.0 2020/07/24:
* - Published.
*
*/
/*:ja
* @plugindesc メッセージテキストシェイクプラグイン
* @author あおいたく
* @help このプラグインはメッセージ中の文字をシェイクさせるための制御文字を追加します。
*
* `\ANIME` と `\ENDANIME` で囲われた文字をシェイクさせます。
* 指定された文字はメッセージウインドウが表示されている間ずっとシェイクします。
*
* 変更履歴
* ********
*
* 1.0.0 2020/07/24:
* - 公開
*
*/
(function () {
const AnimativeTextManager = {
isAnimativeText: false,
};
function addAnimativeCharacter (window, char, x, y, width, height) {
const bitmap = new Bitmap(width, height);
bitmap.textColor = window.contents.textColor;
bitmap.fontSize = window.contents.fontSize;
bitmap.fontFace = window.standardFontFace();
bitmap.drawText(char, 0, 0, width, height);
const sprite = new Sprite();
sprite.x = x + window.padding + width * 0.25;
sprite.y = y + window.padding + height * 0.5;
sprite.anchor.x = 0.25;
sprite.anchor.y = 0.5;
sprite.bitmap = bitmap;
window._animativeCharacterSprites.push({
sprite,
shakePower: (bitmap.fontSize / 16),
shakeDirection: 0,
shakeDuration: 0,
});
window.addChild(sprite);
};
function clearAnimativeCharacters (window) {
window._animativeCharacterSprites.forEach(({ sprite }) => {
window.removeChild(sprite);
})
window._animativeCharacterSprites = [];
};
function updateAnimativeCharacters (window) {
window._animativeCharacterSprites.forEach((sprite) => {
if (sprite.shakeDuration === 0 ) {
sprite.shakeDirection = Math.random() * Math.PI * 2;
sprite.shakeDuration = 4;
sprite.sprite.rotation = Math.random() * Math.PI / 10 - Math.PI / 20;
} else {
sprite.shakeDuration--;
const x = Math.cos(sprite.shakeDirection) * sprite.shakePower;
const y = Math.sin(sprite.shakeDirection) * sprite.shakePower;
sprite.sprite.x += x * ((sprite.shakeDuration < 2) ? -1 : 1);
sprite.sprite.y += y * ((sprite.shakeDuration < 2) ? -1 : 1);
}
})
};
const Window_Message_initialize = Window_Message.prototype.initialize;
Window_Message.prototype.initialize = function() {
Window_Message_initialize.call(this);
this._animativeCharacterSprites = [];
};
const Window_Message_update = Window_Message.prototype.update;
Window_Message.prototype.update = function() {
updateAnimativeCharacters(this);
Window_Message_update.call(this);
};
const Window_Message_terminateMessage = Window_Message.prototype.terminateMessage;
Window_Message.prototype.terminateMessage = function() {
Window_Message_terminateMessage.call(this);
clearAnimativeCharacters(this);
};
const Window_Message_newPage = Window_Message.prototype.newPage;
Window_Message.prototype.newPage = function(textState) {
Window_Message_newPage.call(this, textState);
clearAnimativeCharacters(this);
};
const Window_Message_processNormalCharacter = Window_Message.prototype.processNormalCharacter;
Window_Message.prototype.processNormalCharacter = function(textState) {
if (!AnimativeTextManager.isAnimativeText) {
Window_Message_processNormalCharacter.call(this, textState)
return;
}
const c = textState.text[textState.index++];
const w = this.textWidth(c);
addAnimativeCharacter(this, c, textState.x, textState.y, w * 2, textState.height);
textState.x += w;
};
const Window_Message_processEscapeCharacter = Window_Message.prototype.processEscapeCharacter;
Window_Message.prototype.processEscapeCharacter = function(code, textState) {
switch (code) {
case 'ANIME':
AnimativeTextManager.isAnimativeText = true;
break;
case 'ENDANIME':
AnimativeTextManager.isAnimativeText = false;
break;
default:
Window_Message_processEscapeCharacter.call(this, code, textState);
break;
}
};
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment