Sphinx-MathEasing
Comme tous mes plugins, ce script est publié sous licence CC BY 4.0.
Ce plugin tout simple réunit au sein d’un même « namespace » (l’objet Math.easing) des fonctions d’accélération diverses.
//=============================================================================
// Sphinx-MathEasing.js
//=============================================================================
/*:
* @plugindesc Fonctions d'accélération
* @author Sphinx
*
* @help
* //==========================================================================
* // Plugin : Sphinx-MathEasing
* // Date : 29 décembre 2019
* // Auteur : Sphinx
* //==========================================================================
* Fonctions d'accélérations. Retourne la valeur de la propriété à un instant T
* d'une animation
*
* Ces équations de ont été trouvées sur le site http://www.gizma.com/easing/
* et ont été assemblées dans un plugin par moi-même.
* Vous pouvez bien entendu rajouter vos propres équations en enrichissant
* l'objet Math.
*
* Chacune de ces fonctions prend 4 arguments en paramètres, dans cet ordre :
* - t : temps écoulé (depuis le début de l'animation)
* - b : valeur au début de l'animation
* - c : décallage à la fin de l'animation par rapport à la valeur au début
* - d : durée totale de l'animation
*
* Liste des fonctions d'accélération disponibles :
* - Math.easing.linearTween
* - Math.easing.easeInQuad
* - Math.easing.easeOutQuad
* - Math.easing.easeInOutQuad
* - Math.easing.easeInCubic
* - Math.easing.easeOutCubic
* - Math.easing.easeInOutCubic
* - Math.easing.easeInQuart
* - Math.easing.easeOutQuart
* - Math.easing.easeInOutQuart
* - Math.easing.easeInQuint
* - Math.easing.easeOutQuint
* - Math.easing.easeInOutQuint
* - Math.easing.easeInSine
* - Math.easing.easeOutSine
* - Math.easing.easeInOutSine
* - Math.easing.easeInExpo
* - Math.easing.easeOutExpo
* - Math.easing.easeInOutExpo
* - Math.easing.easeInCirc
* - Math.easing.easeOutCirc
* - Math.easing.easeInOutCirc
*
* Ce plugin n'a pas beaucoup d'effet seul, il a vocation à être utilisé dans
* d'autres plugins utilisant des animations, par exemple.
*
* Dépendances :
* Aucune
*/
Math.easing = {};
Math.easing.linearTween = function (t, b, c, d) {
return c*t/d + b;
};
Math.easing.easeInQuad = function (t, b, c, d) {
t /= d;
return c*t*t + b;
};
Math.easing.easeOutQuad = function (t, b, c, d) {
t /= d;
return -c * t*(t-2) + b;
};
Math.easing.easeInOutQuad = function (t, b, c, d) {
t /= d/2;
if (t < 1) return c/2*t*t + b;
t--;
return -c/2 * (t*(t-2) - 1) + b;
};
Math.easing.easeInCubic = function (t, b, c, d) {
t /= d;
return c*t*t*t + b;
};
Math.easing.easeOutCubic = function (t, b, c, d) {
t /= d;
t--;
return c*(t*t*t + 1) + b;
};
Math.easing.easeInOutCubic = function (t, b, c, d) {
t /= d/2;
if (t < 1) return c/2*t*t*t + b;
t -= 2;
return c/2*(t*t*t + 2) + b;
};
Math.easing.easeInQuart = function (t, b, c, d) {
t /= d;
return c*t*t*t*t + b;
};
Math.easing.easeOutQuart = function (t, b, c, d) {
t /= d;
t--;
return -c * (t*t*t*t - 1) + b;
};
Math.easing.easeInOutQuart = function (t, b, c, d) {
t /= d/2;
if (t < 1) return c/2*t*t*t*t + b;
t -= 2;
return -c/2 * (t*t*t*t - 2) + b;
};
Math.easing.easeInQuint = function (t, b, c, d) {
t /= d;
return c*t*t*t*t*t + b;
};
Math.easing.easeOutQuint = function (t, b, c, d) {
t /= d;
t--;
return c*(t*t*t*t*t + 1) + b;
};
Math.easing.easeInOutQuint = function (t, b, c, d) {
t /= d/2;
if (t < 1) return c/2*t*t*t*t*t + b;
t -= 2;
return c/2*(t*t*t*t*t + 2) + b;
};
Math.easing.easeInSine = function (t, b, c, d) {
return -c * Math.cos(t/d * (Math.PI/2)) + c + b;
};
Math.easing.easeOutSine = function (t, b, c, d) {
return c * Math.sin(t/d * (Math.PI/2)) + b;
};
Math.easing.easeInOutSine = function (t, b, c, d) {
return -c/2 * (Math.cos(Math.PI*t/d) - 1) + b;
};
Math.easing.easeInExpo = function (t, b, c, d) {
return c * Math.pow( 2, 10 * (t/d - 1) ) + b;
};
Math.easing.easeOutExpo = function (t, b, c, d) {
return c * ( -Math.pow( 2, -10 * t/d ) + 1 ) + b;
};
Math.easing.easeInOutExpo = function (t, b, c, d) {
t /= d/2;
if (t < 1) return c/2 * Math.pow( 2, 10 * (t - 1) ) + b;
t--;
return c/2 * ( -Math.pow( 2, -10 * t) + 2 ) + b;
};
Math.easing.easeInCirc = function (t, b, c, d) {
t /= d;
return -c * (Math.sqrt(1 - t*t) - 1) + b;
};
Math.easing.easeOutCirc = function (t, b, c, d) {
t /= d;
t--;
return c * Math.sqrt(1 - t*t) + b;
};
Math.easing.easeInOutCirc = function (t, b, c, d) {
t /= d/2;
if (t < 1) return -c/2 * (Math.sqrt(1 - t*t) - 1) + b;
t -= 2;
return c/2 * (Math.sqrt(1 - t*t) + 1) + b;
};
Vous pouvez, bien entendu, ajouter vos propres formules. La seule contrainte à respecter est la suivante. Votre fonction doit prendre ces 4 paramètres et dans l’ordre :
- Le temps écoulé
- La valeur de départ
- La modification totale
- Et la durée totale de l’animation
Votre fonction vous retournera la valeur actuelle. Il est évident que ces 4 paramètres sont nécessairement des nombres, entiers ou décimaux, positifs ou négatifs. Mais allons-y dans l’ordre.
Le temps écoulé et la durée totale de l’animation
C’est le ratio du temps écoulé par rapport à la durée totale qui détermine le pourcentage de l’animation écoulée. Et c’est ce qui permettra de déterminer la valeur actuelle en fonction d’une courbe déterminée par l’équation correspondant à la méthode.
La valeur de départ et la modification totale
La modification totale correspond à la valeur attendue à la fin de l’animation moins la valeur de départ.
L’usage que vous ferez de ces fonctions dépend de la valeur de départ que vous passerez à la fonction. Moi je me suis servi de ces méthodes pour créer les animations des Sphinx-Chart2. Je me suis aussi servi de ces méthodes pour mon script Sphinx-GameClock, pour actualiser la teinte de l’écran en fonction de l’heure.
Les courbes d’accélération incluses
Voici la liste des courbes d’accélération que j’ai agrégé dans ce plugin :
- linearTween
- easeInQuad
- easeOutQuad
- easeInOutQuad
- easeInCubic
- easeOutCubic
- easeInOutCubic
- easeInQuart
- easeOutQuart
- easeInOutQuart
- easeInQuint
- easeOutQuint
- easeInOutQuint
- easeInSine
- easeOutSine
- easeInOutSine
- easeInExpo
- easeOutExpo
- easeInOutExpo
- easeInCirc
- easeOutCirc
- easeInOutCirc
Pour bien visualiser les courbes correspondant à chacune de ces méthodes, j’ai créé une scène assez basique :
//=============================================================================
// Sphinx-Chart2EasingScene.js
//=============================================================================
/*:
* @plugindesc Scène de démonstration du plugin Sphinx-MathEasing
* @author Sphinx
*
* @help
* //==========================================================================
* // Plugin : Sphinx-Chart2EasingScene
* // Date : 30 décembre 2019
* // Auteur : Sphinx
* //==========================================================================
*
* Dépendances :
* - Sphinx-Chart2
* @param background
* @text Image d'arrière plan de la scène
* @type file
* @dir img/titles1/
* @require 1
*/
//-----------------------------------------------------------------------------
// Game_Interpreter
//
// Commandes de plugin
Sphinx_ChartEasing_Game_Interpreter_pluginCommand = Game_Interpreter.prototype.pluginCommand;
Game_Interpreter.prototype.pluginCommand = function(command, args) {
Sphinx_ChartEasing_Game_Interpreter_pluginCommand.call(this, command, args);
if(command === "DEMO_EASING_GRAPH") {
SceneManager.push(Scene_EasingChart2);
}
};
//-----------------------------------------------------------------------------
// Scene_EasingChart2
//
// Scène de démonstration du plugin Sphinx-Chart2
function Scene_EasingChart2() {
this.initialize.apply(this, arguments);
};
Scene_EasingChart2.prototype = Object.create(Scene_Base.prototype);
Scene_EasingChart2.prototype.constructor = Scene_EasingChart2;
Scene_EasingChart2.prototype.initialize = function() {
Scene_Base.prototype.initialize.call(this);
};
Scene_EasingChart2.prototype.create = function() {
Scene_Base.prototype.create.call(this);
this.createBackground();
this.createTexts();
this.createButtons();
this.listEasing = Object.keys(Math.easing);
this.easing = 0;
};
Scene_EasingChart2.prototype.start = function() {
Scene_Base.prototype.start.call(this);
this.drawGraph();
this.startFadeIn(this.fadeSpeed(), false);
};
Scene_EasingChart2.prototype.terminate = function() {
Scene_Base.prototype.terminate.call(this);
SceneManager.goto(Scene_Map);
this.startFadeOut(this.fadeSpeed(), false);
};
Scene_EasingChart2.prototype.update = function() {
Scene_Base.prototype.update.call(this);
if(Input.isTriggered("cancel")) {
SoundManager.playCancel();
this.terminate();
}
};
Scene_EasingChart2.prototype.createBackground = function() {
this._background = new Sprite_Base();
background = PluginManager.parameters("Sphinx-Chart2EasingScene")["background"];
this._background.bitmap = ImageManager.loadTitle1(background);
this.addChildAt(this._background, 0);
};
Scene_EasingChart2.prototype.createTexts = function() {
this._titleText = new Sprite_Base();
this._titleText.x = 0;
this._titleText.y = 0;
this._titleText.width = Graphics.boxWidth;
this._titleText.height = (Graphics.boxHeight - 480) / 2;
this._titleText.bitmap = new Bitmap(Graphics.boxWidth, (Graphics.boxHeight - 480) / 2);
this._titleText.bitmap.drawText("Méthodes d'accélération - Math.easing", 0, 16, Graphics.boxWidth - 32, 40, "center");
this.addChildAt(this._titleText, 1);
this._explicationText1 = new Sprite_Base();
this._explicationText1.x = 0;
this._explicationText1.y = Graphics.boxHeight - ((Graphics.boxHeight - 480) / 2);
this._explicationText1.width = Graphics.boxWidth;
this._explicationText1.height = (Graphics.boxHeight - 480) / 4;
this._explicationText1.bitmap = new Bitmap(Graphics.boxWidth, (Graphics.boxHeight - 480) / 4);
this._explicationText1.bitmap.fontSize = 18;
this._explicationText1.bitmap.drawText("Naviguez entre les graphiques grâce aux flèches.", 0, 8, Graphics.boxWidth - 32, 20, "center");
this.addChildAt(this._explicationText1, 2);
this._explicationText2 = new Sprite_Base();
this._explicationText2.x = 0;
this._explicationText2.y = Graphics.boxHeight - ((Graphics.boxHeight - 480) / 4);
this._explicationText2.width = Graphics.boxWidth;
this._explicationText2.height = (Graphics.boxHeight - 480) / 4;
this._explicationText2.bitmap = new Bitmap(Graphics.boxWidth, (Graphics.boxHeight - 480) / 4);
this._explicationText2.bitmap.fontSize = 18;
this._explicationText2.bitmap.drawText("gauche et droite de votre clavier.", 0, 8, Graphics.boxWidth - 32, 20, "center");
this.addChildAt(this._explicationText2, 3);
};
Scene_EasingChart2.prototype.createButtons = function() {
var bitmap = ImageManager.loadSystem('ButtonSet');
var buttonLeft = new Sprite_Button();
buttonLeft.bitmap = bitmap;
buttonLeft.setColdFrame(48, 0, 48, 48);
buttonLeft.setHotFrame(48, 48, 48, 48);
buttonLeft.rotation = 90 * Math.PI / 180;
buttonLeft.anchor.x = 0.5;
buttonLeft.anchor.y = 0.5;
buttonLeft.x = 16 + 24;
buttonLeft.y = (Graphics.boxHeight - 48) / 2;
buttonLeft.setClickHandler(Scene_EasingChart2.prototype.goToLeft.bind(this));
this.addChild(buttonLeft);
var buttonRight = new Sprite_Button();
buttonRight.bitmap = bitmap;
buttonRight.setColdFrame(96, 0, 48, 48);
buttonRight.setHotFrame(96, 48, 48, 48);
buttonRight.rotation = 90 * Math.PI / 180;
buttonRight.anchor.x = 0.5;
buttonRight.anchor.y = 0.5;
buttonRight.x = Graphics.boxWidth - 16 - 24;
buttonRight.y = (Graphics.boxHeight - 48) / 2;
buttonRight.setClickHandler(Scene_EasingChart2.prototype.goToRight.bind(this));
this.addChild(buttonRight);
};
Scene_EasingChart2.prototype.goToLeft = function() {
this.easing--;
if(this.easing < 0) this.easing = this.listEasing.length - 1;
this.drawGraph();
};
Scene_EasingChart2.prototype.goToRight = function() {
this.easing++;
if(this.easing >= this.listEasing.length) this.easing = 0;
this.drawGraph();
};
Scene_EasingChart2.prototype.drawGraph = function() {
categories = [ this.listEasing[this.easing] ];
xLabels = [];
datas = [ [] ];
for(i = 0; i <= 150; ++i) {
xLabels.push(i);
datas[0].push(Math.easing[this.listEasing[this.easing]](i, 0, 150, 150));
}
if(this.chart) {
this.chart.destroy();
}
console.log(this.listEasing[this.easing], datas);
this.chart = new SphinxChart2({
type: "line",
title: "Easing - " + this.listEasing[this.easing].capitalize(),
categoriesLabels: categories,
xAxisLabels: xLabels,
datas: datas,
options: {
easing: this.listEasing[this.easing],
duration: 1,
background: "transparent",
forceMinToZero: false,
position: {
x: 88,
y: (Graphics.boxHeight - 480) / 2,
width: 640,
height: 480,
},
padding: {
top: 10,
left: 25,
right: 25,
bottom: 25,
}
}
});
this.addChildAt(this.chart, 4);
};
Scene_EasingChart2.prototype.fastForwardRate = function() {
return 3;
};
Scene_EasingChart2.prototype.isFastForward = function() {
return (Input.isPressed('ok') || Input.isPressed('shift') || TouchInput.isPressed());
};
Scene_EasingChart2.prototype.updateFade = function() {
if(this._fadeDuration > 0) {
var d = this._fadeDuration;
if(this.isFastForward()) {
d -= this.fastForwardRate() - 1;
this._fadeDuration -= this.fastForwardRate();
} else {
this._fadeDuration--;
}
if(this._fadeSign > 0) {
this._fadeSprite.opacity -= this._fadeSprite.opacity / d;
} else {
this._fadeSprite.opacity += (255 - this._fadeSprite.opacity) / d;
}
}
};
Scene_EasingChart2.prototype.fadeSpeed = function(ignoreFast) {
return 30;
};
Pour fonctionner, cette scène nécessite l’installation du script Sphinx-Chart2.
Pour ouvrir cette scène, qui permet de naviguer entre les méthodes d’easing, il suffit d’appeler cette commande de plugin : DEMO_EASING_GRAPH.