Kaynağa Gözat

✨ Add Tween GameObject

- Remove x from the parameters of Easing functions.
Pedro Schneider 3 yıl önce
ebeveyn
işleme
21bb6a8317
4 değiştirilmiş dosya ile 262 ekleme ve 49 silme
  1. 1 0
      index.html
  2. 191 0
      pandora/game_objects/Tween.js
  3. 54 34
      pandora/singletons/Easings.js
  4. 16 15
      src/sketch.js

+ 1 - 0
index.html

@@ -31,6 +31,7 @@
     <!-- Game Objects -->
     <script type="text/javascript" src="pandora/game_objects/GameObject.js"></script>
     <script type="text/javascript" src="pandora/game_objects/AudioPlayer.js"></script>
+    <script type="text/javascript" src="pandora/game_objects/Tween.js"></script>
     
       <!-- 2D Game Objects -->
       <script type="text/javascript" src="pandora/game_objects/2d_objects/Object2D.js"></script>

+ 191 - 0
pandora/game_objects/Tween.js

@@ -0,0 +1,191 @@
+/************************************************************************
+ * Tween.js
+ ************************************************************************
+ * Copyright (c) 2021 Pedro Tonini Rosenberg Schneider.
+ *
+ * This file is part of Pandora.
+ *
+ * Pandora is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Pandora is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *     
+ * You should have received a copy of the GNU General Public License     
+ * along with Pandora.  If not, see <https://www.gnu.org/licenses/>.
+ *************************************************************************/
+
+class TweenData
+{
+    constructor(target, property, propertyType, initVal, finalVal, duration, transType, easeType, delay)
+    {
+        this.target = target;
+        this.property = property;
+        this.propertyType = propertyType;
+        switch (this.propertyType)
+        {
+            case PROPERTY_TYPE.COLOR:
+                this.initVal = new Color(initVal.r, initVal.g, initVal.b, initVal.a);
+                this.finalVal = new Color(finalVal.r, finalVal.g, finalVal.b, finalVal.a);
+                break;
+            case PROPERTY_TYPE.VECTOR2:
+                this.initVal = new Vector2(initVal.x, initVal.y);
+                this.finalVal = new Vector2(finalVal.x, finalVal.y);
+                break;
+            case PROPERTY_TYPE.NUMBER:
+                this.initVal = initVal;
+                this.finalVal = finalVal;
+                break;
+        }
+        this.duration = duration;
+        this.transType = transType;
+        this.easeType = easeType;
+
+        this.t = -delay;
+        this.playing = false;
+        this.done = false;
+
+        this.p = [];
+        switch (this.propertyType)
+        {
+            case PROPERTY_TYPE.COLOR:
+                this.p.push("r");
+                this.p.push("g");
+                this.p.push("b");
+                break;
+            case PROPERTY_TYPE.VECTOR2:
+                this.p.push("x");
+                this.p.push("y");
+                break;
+            case PROPERTY_TYPE.NUMBER:
+                break;
+        }
+
+        this.trans = "";
+        switch (this.transType)
+        {
+            case TRANS_TYPE.LINEAR:
+                this.trans = "Linear";
+                break;
+            case TRANS_TYPE.QUAD:
+                this.trans = "Quad";
+                break;
+            case TRANS_TYPE.CUBIC:
+                this.trans = "Cubic";
+                break;
+            case TRANS_TYPE.QUART:
+                this.trans = "Quart";
+                break;
+            case TRANS_TYPE.QUINT:
+                this.trans = "Quint";
+                break;
+            case TRANS_TYPE.SINE:
+                this.trans = "Sine";
+                break;
+            case TRANS_TYPE.EXPONENTIAL:
+                this.trans = "Expo";
+                break;
+            case TRANS_TYPE.CIRCULAR:
+                this.trans = "Circ";
+                break;
+            case TRANS_TYPE.ELASTIC:
+                this.trans = "Elastic";
+                break;
+            case TRANS_TYPE.BACK:
+                this.trans = "Back";
+                break;
+            case TRANS_TYPE.BOUNCE:
+                this.trans = "Bounce";
+                break;
+        }
+
+        this.ease = "";
+        if (this.transType == TRANS_TYPE.LINEAR) this.ease = "ease";
+        else
+        {
+            switch (this.easeType)
+            {
+                case EASE_TYPE.IN:
+                    this.ease = "easeIn";
+                    break;
+                case EASE_TYPE.OUT:
+                    this.ease = "easeOut";
+                    break;
+                case EASE_TYPE.IN_OUT:
+                    this.ease = "easeInOut";
+                    break;
+            }
+        }
+    }
+}
+
+class Tween extends GameObject
+{
+    constructor(name)
+    {
+        super(name);
+
+        this.tweenData = [];
+        this.doneTweens = 0;
+        this.done = false;
+    }
+
+    interpolateProperty(target, property, propertyType, initVal, finalVal, duration, transType = 1, easeType = 3, delay = 0)
+    {
+        this.done = false;
+        this.tweenData.push(new TweenData(target, property, propertyType, initVal, finalVal, duration, transType, easeType, delay));
+    }
+
+    interpolate(td)
+    {
+        if (td.propertyType == PROPERTY_TYPE.NUMBER)
+            td.target[td.property] = Easings[td.trans][td.ease](td.t, td.initVal, td.finalVal - td.initVal, td.duration);
+        else
+        {
+            for (let i = 0; i < td.p.length; i++)
+                td.target[td.property][td.p[i]] = Easings[td.trans][td.ease](td.t, td.initVal[td.p[i]], td.finalVal[td.p[i]] - td.initVal[td.p[i]], td.duration);
+        }
+    }
+
+    play()
+    {
+        for (let i = 0; i < this.tweenData.length; i++)
+        {
+            this.tweenData[i].playing = true;
+        }
+    }
+
+    update(delta)
+    {
+        if (!this.done && this.doneTweens == this.tweenData.length) this.allDone();
+
+        for (let i = 0; i < this.tweenData.length; i++)
+        {
+            if (!this.tweenData[i].playing) continue;
+
+            if (this.tweenData[i].t >= 0)
+                this.interpolate(this.tweenData[i]);
+
+            this.tweenData[i].t = min(this.tweenData[i].t + delta, this.tweenData[i].duration);
+
+            if (!this.tweenData[i].done && this.tweenData[i].t == this.tweenData[i].duration)
+            {
+                this.tweenData[i].done = true;
+                this.doneTweens += 1;
+            }
+        }
+
+        this._update(delta);
+        for (let i = 0; i < this.children.length; i++)
+            this.children[i].update(delta);
+    }
+
+    allDone()
+    {
+        this.done = true;
+    }
+}

+ 54 - 34
pandora/singletons/Easings.js

@@ -61,7 +61,7 @@ const Easings = {
 
     Linear:
     {
-        ease: function(x, t, b, c, d)
+        ease: function(t, b, c, d)
         {
             return b + (c * t / d);
         }
@@ -69,15 +69,17 @@ const Easings = {
 
     Quad:
     {
-        easeIn: function(x, t, b, c, d)
+        easeIn: function(t, b, c, d)
         {
             return c * (t /= d) * t + b;
         },
-        easeOut: function(x, t, b, c, d)
+
+        easeOut: function(t, b, c, d)
         {
             return -c * (t /= d) * (t - 2) + b;
         },
-        easeInOut: function(x, t, b, c, d)
+
+        easeInOut: function(t, b, c, d)
         {
             if ((t /= d / 2) < 1) return c / 2 * t * t + b;
             return -c / 2 * ((--t) * (t - 2) - 1) + b;
@@ -86,15 +88,17 @@ const Easings = {
 
     Cubic:
     {
-        easeIn: function(x, t, b, c, d)
+        easeIn: function(t, b, c, d)
         {
             return c * (t /= d) * t * t + b;
         },
-        easeOut: function(x, t, b, c, d)
+
+        easeOut: function(t, b, c, d)
         {
             return c * ((t = t / d - 1) * t * t + 1) + b;
         },
-        easeInOut: function(x, t, b, c, d)
+
+        easeInOut: function(t, b, c, d)
         {
             if ((t /= d / 2) < 1) return c / 2 * t * t * t + b;
             return c / 2 * ((t -= 2) * t * t + 2) + b;
@@ -103,15 +107,17 @@ const Easings = {
 
     Quart:
     {
-        easeIn: function(x, t, b, c, d)
+        easeIn: function(t, b, c, d)
         {
             return c * (t /= d) * t * t * t + b;
         },
-        easeOut: function(x, t, b, c, d)
+
+        easeOut: function(t, b, c, d)
         {
             return -c * ((t = t / d - 1) * t * t * t - 1) + b;
         },
-        easeInOut: function(x, t, b, c, d)
+
+        easeInOut: function(t, b, c, d)
         {
             if ((t /= d / 2) < 1) return c / 2 * t * t * t * t + b;
             return -c / 2 * ((t -= 2) * t * t * t - 2) + b;
@@ -120,15 +126,17 @@ const Easings = {
 
     Quint:
     {
-        easeIn: function(x, t, b, c, d)
+        easeIn: function(t, b, c, d)
         {
             return c * (t /= d) * t * t * t * t + b;
         },
-        easeOut: function(x, t, b, c, d)
+
+        easeOut: function(t, b, c, d)
         {
             return c * ((t = t / d - 1) * t * t * t * t + 1) + b;
         },
-        easeInOut: function(x, t, b, c, d)
+
+        easeInOut: function(t, b, c, d)
         {
             if ((t /= d / 2) < 1) return c / 2 * t * t * t * t * t + b;
             return c / 2 * ((t -= 2) * t * t * t * t + 2) + b;
@@ -137,15 +145,17 @@ const Easings = {
 
     Sine:
     {
-        easeIn: function(x, t, b, c, d)
+        easeIn: function(t, b, c, d)
         {
             return -c * Math.cos(t / d * (Math.PI / 2)) + c + b;
         },
-        easeOut: function(x, t, b, c, d)
+
+        easeOut: function(t, b, c, d)
         {
             return c * Math.sin(t / d * (Math.PI / 2)) + b;
         },
-        easeInOut: function(x, t, b, c, d)
+
+        easeInOut: function(t, b, c, d)
         {
             return -c / 2 * (Math.cos(Math.PI * t / d) - 1) + b;
         }
@@ -153,15 +163,17 @@ const Easings = {
 
     Expo:
     {
-        easeIn: function(x, t, b, c, d)
+        easeIn: function(t, b, c, d)
         {
             return (t == 0) ? b : c * Math.pow(2, 10 * (t / d - 1)) + b;
         },
-        easeOut: function(x, t, b, c, d)
+
+        easeOut: function(t, b, c, d)
         {
             return (t == d) ? b + c : c * (-Math.pow(2, -10 * t / d) + 1) + b;
         },
-        easeInOut: function(x, t, b, c, d)
+
+        easeInOut: function(t, b, c, d)
         {
             if (t == 0) return b;
             if (t == d) return b + c;
@@ -172,15 +184,17 @@ const Easings = {
 
     Circ:
     {
-        easeIn: function(x, t, b, c, d)
+        easeIn: function(t, b, c, d)
         {
             return -c * (Math.sqrt(1 - (t /= d) * t) - 1) + b;
         },
-        easeOut: function(x, t, b, c, d)
+
+        easeOut: function(t, b, c, d)
         {
             return c * Math.sqrt(1 - (t = t / d - 1) * t) + b;
         },
-        easeInOut: function(x, t, b, c, d)
+        
+        easeInOut: function(t, b, c, d)
         {
             if ((t /= d / 2) < 1) return -c / 2 * (Math.sqrt(1 - t * t) - 1) + b;
             return c / 2 * (Math.sqrt(1 - (t -= 2) * t) + 1) + b;
@@ -189,7 +203,7 @@ const Easings = {
 
     Elastic:
     {
-        easeIn: function(x, t, b, c, d)
+        easeIn: function(t, b, c, d)
         {
             var s = 1.70158;
             var p = 0;
@@ -205,7 +219,8 @@ const Easings = {
             else var s = p / (2 * Math.PI) * Math.asin(c / a);
             return -(a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p)) + b;
         },
-        easeOut: function(x, t, b, c, d)
+
+        easeOut: function(t, b, c, d)
         {
             var s = 1.70158;
             var p = 0;
@@ -221,7 +236,8 @@ const Easings = {
             else var s = p / (2 * Math.PI) * Math.asin(c / a);
             return a * Math.pow(2, -10 * t) * Math.sin((t * d - s) * (2 * Math.PI) / p) + c + b;
         },
-        easeInOut: function(x, t, b, c, d)
+
+        easeInOut: function(t, b, c, d)
         {
             var s = 1.70158;
             var p = 0;
@@ -242,17 +258,19 @@ const Easings = {
 
     Back:
     {
-        easeIn: function(x, t, b, c, d, s)
+        easeIn: function(t, b, c, d, s)
         {
             if (s == undefined) s = 1.70158;
             return c * (t /= d) * t * ((s + 1) * t - s) + b;
         },
-        easeOut: function(x, t, b, c, d, s)
+
+        easeOut: function(t, b, c, d, s)
         {
             if (s == undefined) s = 1.70158;
             return c * ((t = t / d - 1) * t * ((s + 1) * t + s) + 1) + b;
         },
-        easeInOut: function(x, t, b, c, d, s)
+
+        easeInOut: function(t, b, c, d, s)
         {
             if (s == undefined) s = 1.70158;
             if ((t /= d / 2) < 1) return c / 2 * (t * t * (((s *= (1.525)) + 1) * t - s)) + b;
@@ -262,11 +280,12 @@ const Easings = {
 
     Bounce:
     {
-        easeIn: function(x, t, b, c, d)
+        easeIn: function(t, b, c, d)
         {
-            return c - Easings.Bounce.easeOut(x, d - t, 0, c, d) + b;
+            return c - Easings.Bounce.easeOut(d - t, 0, c, d) + b;
         },
-        easeOut: function(x, t, b, c, d)
+
+        easeOut: function(t, b, c, d)
         {
             if ((t /= d) < (1 / 2.75))
                 return c * (7.5625 * t * t) + b;
@@ -277,10 +296,11 @@ const Easings = {
             else
                 return c * (7.5625 * (t -= (2.625 / 2.75)) * t + .984375) + b;
         },
-        easeInOut: function(x, t, b, c, d)
+        
+        easeInOut: function(t, b, c, d)
         {
-            if (t < d / 2) return Easings.Bounce.easeIn(x, t * 2, 0, c, d) * .5 + b;
-            return Easings.Bounce.easeOut(x, t * 2 - d, 0, c, d) * .5 + c * .5 + b;
+            if (t < d / 2) return Easings.Bounce.easeIn(t * 2, 0, c, d) * .5 + b;
+            return Easings.Bounce.easeOut(t * 2 - d, 0, c, d) * .5 + c * .5 + b;
         }
     },
 }

+ 16 - 15
src/sketch.js

@@ -6,25 +6,27 @@ class TestObject extends Object2D
     {
         this.currTime = 0;
         this.duration = 3;
-        this.position.y = 100;
-        this.position.x = 0;
-        this.targetXPos = 200;
+        this.position.y = 300;
+        this.position.x = 100;
 
-        this.playing = false;
+        this.tween = new Tween("myTween");
+        this.tween.interpolateProperty(this.position, "x", PROPERTY_TYPE.NUMBER, this.position.x, 400, 2, TRANS_TYPE.LINEAR, EASE_TYPE.OUT, 0);
+        // this.tween.interpolateProperty(this.position, "y", PROPERTY_TYPE.NUMBER, this.position.y, 100, 2, TRANS_TYPE.LINEAR, EASE_TYPE.OUT, 0);
+        // this.tween.interpolateProperty(this.position, "y", PROPERTY_TYPE.NUMBER, this.position.y, 100, 2, TRANS_TYPE.SINE, EASE_TYPE.OUT, 0);
+        this.tween.interpolateProperty(this.position, "y", PROPERTY_TYPE.NUMBER, this.position.y, 100, 3, TRANS_TYPE.CUBIC, EASE_TYPE.IN_OUT, 0);
+        // this.tween.interpolateProperty(this.position, "y", PROPERTY_TYPE.NUMBER, this.position.y, 100, 2, TRANS_TYPE.BOUNCE, EASE_TYPE.OUT, 0);
+        // this.tween.interpolateProperty(this.position, "y", PROPERTY_TYPE.NUMBER, this.position.y, 100, 2, TRANS_TYPE.ELASTIC, EASE_TYPE.OUT, 0);
+        this.addChild(this.tween);
     }
 
     _update(delta)
     {
-        if (this.playing)
-        {
-            this.currTime = min(this.currTime + delta, this.duration);
-        }
-        this.position.x = Easings.Elastic.easeOut(0, this.currTime, 0, 300, this.duration);
+        // console.log(this.color)
     }
 
-    _draw()
+    _draw(delta)
     {
-        ellipse(0, 0, 20);
+        ellipse(0, 0, 20, 20);
     }
 }
 
@@ -32,8 +34,7 @@ class TestButton extends Button
 {
     _onMousePressed()
     {
-        this.getParent().playing = true;
-        this.getParent().currTime = 0;
+        this.getParent().tween.play();
     }
 }
 
@@ -47,7 +48,7 @@ function preload()
 
 function setup()
 {
-    GameHandler.drawDebugFPS(true);
+    // GameHandler.drawDebugFPS(true);
     GameHandler.setRenderMode(RENDER_MODES.WEBGL);
     GameHandler.init();
     textFont(AssetHandler.getP5FontByName("Lato"));
@@ -57,11 +58,11 @@ function setup()
     but.setPosition(0, 200);
     test.addChild(but);
     GameHandler.addRootObject(test);
+    background(220);
 }
 
 function draw()
 {
-    background(220);
     GameHandler.update();
     GameHandler.draw();
 }