commit 086a24d02127331da4baf3cb865101f557fd7996
Author: Leszek Koltunski <leszek@koltunski.pl>
Date:   Fri May 17 16:07:31 2019 +0100

    - simplify the Effects

diff --git a/src/main/java/org/distorted/effect/SizeChangeEffect.java b/src/main/java/org/distorted/effect/SizeChangeEffect.java
index e071c915..a77753db 100644
--- a/src/main/java/org/distorted/effect/SizeChangeEffect.java
+++ b/src/main/java/org/distorted/effect/SizeChangeEffect.java
@@ -33,24 +33,24 @@ public abstract class SizeChangeEffect implements EffectListener
 {
   public enum Type
     {
-    NONE         (SizeChangeEffectAppearNone.class        , SizeChangeEffectDisappearNone.class        ),
-    TRANSPARENCY (SizeChangeEffectAppearTransparency.class, SizeChangeEffectDisappearTransparency.class),
-    MOVE         (SizeChangeEffectAppearMove.class        , SizeChangeEffectDisappearMove.class        ),
-    ROUND        (SizeChangeEffectAppearRound.class       , SizeChangeEffectDisappearRound.class       ),
-    SCALE        (SizeChangeEffectAppearScale.class       , SizeChangeEffectDisappearScale.class       ),
+    NONE         (SizeChangeEffectNone.class        ),
+    TRANSPARENCY (SizeChangeEffectTransparency.class),
+    MOVE         (SizeChangeEffectMove.class        ),
+    ROUND        (SizeChangeEffectRound.class       ),
+    SCALE        (SizeChangeEffectScale.class       ),
     ;
 
-    final Class<? extends SizeChangeEffectAppear   > appear;
-    final Class<? extends SizeChangeEffectDisappear> disappear;
+    final Class<? extends SizeChangeEffect> effect;
 
-    Type(Class<? extends SizeChangeEffectAppear> appear, Class<? extends SizeChangeEffectDisappear> disappear )
+    Type(Class<? extends SizeChangeEffect> effect)
       {
-      this.appear    = appear;
-      this.disappear = disappear;
+      this.effect= effect;
       }
     }
 
   private static int NUM_EFFECTS = Type.values().length;
+  private static final int NUM_PHASES  = 2;
+  private static final int FAKE_EFFECT_ID  = -1;
   private static final Type[] types;
 
   static
@@ -65,22 +65,33 @@ public abstract class SizeChangeEffect implements EffectListener
     }
 
   private EffectListener mListener;
-  private int mCubeEffectNumber, mNodeEffectNumber, mEffectFinished, mEffectReturned;
-  private int mFakeEffectID;
+  private int mDuration;
+  private int[] mEffectReturned;
+  private int[] mCubeEffectNumber, mNodeEffectNumber;
+  private int[] mEffectFinished;
+  private boolean[] mPhaseActive;
 
-  RubikCube mCube;
+  RubikCube[] mCube;
   DistortedScreen mScreen;
-  Effect[] mCubeEffects;
-  int[] mCubeEffectPosition;
-  Effect[] mNodeEffects;
-  int[] mNodeEffectPosition;
+  Effect[][] mCubeEffects;
+  int[][] mCubeEffectPosition;
+  Effect[][] mNodeEffects;
+  int[][] mNodeEffectPosition;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  SizeChangeEffect(int id)
+  SizeChangeEffect()
     {
-    mEffectReturned = 0;
-    mFakeEffectID   = id;
+    mPhaseActive        = new boolean[NUM_PHASES];
+    mEffectReturned     = new int[NUM_PHASES];
+    mCubeEffectNumber   = new int[NUM_PHASES];
+    mNodeEffectNumber   = new int[NUM_PHASES];
+    mEffectFinished     = new int[NUM_PHASES];
+    mCubeEffectPosition = new int[NUM_PHASES][];
+    mNodeEffectPosition = new int[NUM_PHASES][];
+    mCubeEffects        = new Effect[NUM_PHASES][];
+    mNodeEffects        = new Effect[NUM_PHASES][];
+    mCube               = new RubikCube[NUM_PHASES];
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -106,95 +117,136 @@ public abstract class SizeChangeEffect implements EffectListener
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  abstract int createEffects(int duration);
-  abstract void effectsEnd();
-  abstract void startEnd();
+  public static SizeChangeEffect create(Type type) throws InstantiationException, IllegalAccessException
+    {
+    return type.effect.newInstance();
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  abstract int createEffectsPhase0(int duration);
+  abstract int createEffectsPhase1(int duration);
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
   public void effectFinished(final long effectID)
     {
-    for(int i=0; i<mCubeEffectNumber; i++)
+    if( mPhaseActive[0] ) effectFinishedPhase(effectID,0);
+    if( mPhaseActive[1] ) effectFinishedPhase(effectID,1);
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  private void effectFinishedPhase(final long effectID, int phase)
+    {
+    for(int i=0; i<mCubeEffectNumber[phase]; i++)
       {
-      long id = mCubeEffects[i].getID();
+      long id = mCubeEffects[phase][i].getID();
 
       if( effectID == id )
         {
-        mEffectReturned++;
-
-        if( mEffectReturned == mEffectFinished )
-          {
-          mListener.effectFinished(mFakeEffectID);
-          }
-
-        if( mEffectReturned == mCubeEffectNumber+mNodeEffectNumber )
-          {
-          effectsEnd();
-          }
-
-        mCube.remove(id);
-        break;
+        effectReturned(phase);
+        mCube[phase].remove(id);
+        return;
         }
       }
-    for(int i=0; i<mNodeEffectNumber; i++)
+    for(int i=0; i<mNodeEffectNumber[phase]; i++)
       {
-      long id = mNodeEffects[i].getID();
+      long id = mNodeEffects[phase][i].getID();
 
       if( effectID == id )
         {
-        mEffectReturned++;
+        effectReturned(phase);
+        mCube[phase].getEffects().abortById(id);
+        return;
+        }
+      }
+    }
 
-        if( mEffectReturned == mEffectFinished )
-          {
-          mListener.effectFinished(mFakeEffectID);
-          }
+///////////////////////////////////////////////////////////////////////////////////////////////////
 
-        if( mEffectReturned == mCubeEffectNumber+mNodeEffectNumber )
-          {
-          effectsEnd();
-          }
+  private void effectReturned(int phase)
+    {
+    mEffectReturned[phase]++;
 
-        mCube.getEffects().abortById(id);
-        break;
+    if( mEffectReturned[phase] == mEffectFinished[phase] )
+      {
+      switch(phase)
+        {
+        case 0: mPhaseActive[1] = true;
+                mEffectFinished[1] = createEffectsPhase1(mDuration);
+                assignEffects(1);
+                mScreen.attach(mCube[1]);
+                break;
+        case 1: mListener.effectFinished(FAKE_EFFECT_ID);
+                break;
+        }
+      }
+    if( mEffectReturned[phase] == mCubeEffectNumber[phase]+mNodeEffectNumber[phase] )
+      {
+      switch(phase)
+        {
+        case 0: mPhaseActive[0] = false;
+                mScreen.detach(mCube[0]);
+                break;
+        case 1: mPhaseActive[1] = false;
+                break;
         }
       }
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  public long start(int duration, DistortedScreen screen, RubikCube cube, EffectListener listener)
+  public long start(int duration, DistortedScreen screen, RubikCube oldcube, RubikCube newcube, EffectListener listener)
     {
     mScreen   = screen;
-    mCube     = cube;
+    mCube[0]  = oldcube;
+    mCube[1]  = newcube;
     mListener = listener;
+    mDuration = duration;
+
+    if( oldcube!=null )
+      {
+      mPhaseActive[0] = true;
+      mEffectFinished[0] = createEffectsPhase0(mDuration);
+      assignEffects(0);
+      }
+    else
+      {
+      mPhaseActive[1] = true;
+      mEffectFinished[1] = createEffectsPhase1(mDuration);
+      assignEffects(1);
+      mScreen.attach(mCube[1]);
+      }
 
-    mEffectFinished = createEffects(duration);
+    return FAKE_EFFECT_ID;
+    }
 
-    mCubeEffectNumber = ( mCubeEffects!=null ) ? mCubeEffects.length : 0;
-    mNodeEffectNumber = ( mNodeEffects!=null ) ? mNodeEffects.length : 0;
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  private void assignEffects(int phase)
+    {
+    mCubeEffectNumber[phase] = ( mCubeEffects[phase]!=null ) ? mCubeEffects[phase].length : 0;
+    mNodeEffectNumber[phase] = ( mNodeEffects[phase]!=null ) ? mNodeEffects[phase].length : 0;
 
-    if( mCubeEffectNumber==0 && mNodeEffectNumber==0 )
+    if( mCubeEffectNumber[phase]==0 && mNodeEffectNumber[phase]==0 )
       {
-      throw new RuntimeException("Cube and Node Effects both not created!");
+      throw new RuntimeException("Cube and Node Effects ("+phase+" phase) both not created!");
       }
 
-    for(int i=0; i<mCubeEffectNumber; i++)
+    for(int i=0; i<mCubeEffectNumber[phase]; i++)
       {
-      mCube.apply(mCubeEffects[i],mCubeEffectPosition[i]);
-      mCubeEffects[i].notifyWhenFinished(this);
+      mCube[phase].apply(mCubeEffects[phase][i],mCubeEffectPosition[phase][i]);
+      mCubeEffects[phase][i].notifyWhenFinished(this);
       }
 
-    DistortedEffects nodeEffects = mCube.getEffects();
+    DistortedEffects nodeEffects = mCube[phase].getEffects();
 
-    for(int i=0; i<mNodeEffectNumber; i++)
+    for(int i=0; i<mNodeEffectNumber[phase]; i++)
       {
-      nodeEffects.apply(mNodeEffects[i],mNodeEffectPosition[i]);
-      mNodeEffects[i].notifyWhenFinished(this);
+      nodeEffects.apply(mNodeEffects[phase][i],mNodeEffectPosition[phase][i]);
+      mNodeEffects[phase][i].notifyWhenFinished(this);
       }
-
-    startEnd();
-
-    return mFakeEffectID;
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -207,25 +259,7 @@ public abstract class SizeChangeEffect implements EffectListener
       {
       try
         {
-        method = type.appear.getMethod("enable");
-        }
-      catch(NoSuchMethodException ex)
-        {
-        android.util.Log.e("SizeChangeEffect", "exception getting method: "+ex.getMessage());
-        }
-
-      try
-        {
-        method.invoke(null);
-        }
-      catch(Exception ex)
-        {
-        android.util.Log.e("SizeChangeEffect", "exception invoking method: "+ex.getMessage());
-        }
-
-      try
-        {
-        method = type.disappear.getMethod("enable");
+        method = type.effect.getMethod("enable");
         }
       catch(NoSuchMethodException ex)
         {
diff --git a/src/main/java/org/distorted/effect/SizeChangeEffectAppear.java b/src/main/java/org/distorted/effect/SizeChangeEffectAppear.java
deleted file mode 100644
index 2a797ba1..00000000
--- a/src/main/java/org/distorted/effect/SizeChangeEffectAppear.java
+++ /dev/null
@@ -1,51 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Copyright 2019 Leszek Koltunski                                                               //
-//                                                                                               //
-// This file is part of Distorted.                                                               //
-//                                                                                               //
-// Distorted 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 2 of the License, or                             //
-// (at your option) any later version.                                                           //
-//                                                                                               //
-// Distorted 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 Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-package org.distorted.effect;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-public abstract class SizeChangeEffectAppear extends SizeChangeEffect
-  {
-  SizeChangeEffectAppear()
-    {
-    super(-1);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public static SizeChangeEffectAppear create(Type type) throws InstantiationException, IllegalAccessException
-    {
-    return type.appear.newInstance();
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  void effectsEnd()
-    {
-
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  void startEnd()
-    {
-    mScreen.attach(mCube);
-    }
-  }
diff --git a/src/main/java/org/distorted/effect/SizeChangeEffectAppearMove.java b/src/main/java/org/distorted/effect/SizeChangeEffectAppearMove.java
deleted file mode 100644
index bbb9cc33..00000000
--- a/src/main/java/org/distorted/effect/SizeChangeEffectAppearMove.java
+++ /dev/null
@@ -1,58 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Copyright 2019 Leszek Koltunski                                                               //
-//                                                                                               //
-// This file is part of Distorted.                                                               //
-//                                                                                               //
-// Distorted 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 2 of the License, or                             //
-// (at your option) any later version.                                                           //
-//                                                                                               //
-// Distorted 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 Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-package org.distorted.effect;
-
-import org.distorted.library.effect.Effect;
-import org.distorted.library.effect.MatrixEffectMove;
-import org.distorted.library.type.Dynamic3D;
-import org.distorted.library.type.Static3D;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-class SizeChangeEffectAppearMove extends SizeChangeEffectAppear
-  {
-  public int createEffects(int duration)
-    {
-    int w = mScreen.getWidth();
-    int h = mScreen.getHeight();
-    int xmove = w/2 + (w<h?w:h)/2;
-
-    mNodeEffectPosition = new int[] {1};
-    mNodeEffects        = new Effect[mNodeEffectPosition.length];
-
-    Dynamic3D d0 = new Dynamic3D(duration, 0.5f);
-    d0.add(new Static3D(-xmove,0,0));
-    d0.add(new Static3D(     0,0,0));
-    mNodeEffects[0] = new MatrixEffectMove(d0);
-
-    return 1;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Enable all effects used in this Appear. Called by reflection from the parent class.
-// Matrix Effects do not have to be enabled.
-
-  @SuppressWarnings("unused")
-  static void enable()
-    {
-
-    }
-  }
-
diff --git a/src/main/java/org/distorted/effect/SizeChangeEffectAppearNone.java b/src/main/java/org/distorted/effect/SizeChangeEffectAppearNone.java
deleted file mode 100644
index a0a4c9f4..00000000
--- a/src/main/java/org/distorted/effect/SizeChangeEffectAppearNone.java
+++ /dev/null
@@ -1,51 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Copyright 2019 Leszek Koltunski                                                               //
-//                                                                                               //
-// This file is part of Distorted.                                                               //
-//                                                                                               //
-// Distorted 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 2 of the License, or                             //
-// (at your option) any later version.                                                           //
-//                                                                                               //
-// Distorted 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 Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-package org.distorted.effect;
-
-import org.distorted.library.effect.Effect;
-import org.distorted.library.effect.MatrixEffectMove;
-import org.distorted.library.type.Dynamic3D;
-import org.distorted.library.type.Static3D;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-class SizeChangeEffectAppearNone extends SizeChangeEffectAppear
-  {
-  public int createEffects(int duration)
-    {
-    mCubeEffectPosition = new int[] {-1};
-    mCubeEffects        = new Effect[mCubeEffectPosition.length];
-
-    Dynamic3D d0 = new Dynamic3D(1,0.5f);
-    d0.add(new Static3D(0,0,0));
-    mCubeEffects[0] = new MatrixEffectMove(d0);
-
-    return 1;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// enable all effects used in this Appear (here: none).  Called by reflection from the parent class.
-
-  @SuppressWarnings("unused")
-  static void enable()
-    {
-
-    }
-  }
diff --git a/src/main/java/org/distorted/effect/SizeChangeEffectAppearRound.java b/src/main/java/org/distorted/effect/SizeChangeEffectAppearRound.java
deleted file mode 100644
index 74733514..00000000
--- a/src/main/java/org/distorted/effect/SizeChangeEffectAppearRound.java
+++ /dev/null
@@ -1,67 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Copyright 2019 Leszek Koltunski                                                               //
-//                                                                                               //
-// This file is part of Distorted.                                                               //
-//                                                                                               //
-// Distorted 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 2 of the License, or                             //
-// (at your option) any later version.                                                           //
-//                                                                                               //
-// Distorted 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 Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-package org.distorted.effect;
-
-import org.distorted.library.effect.Effect;
-import org.distorted.library.effect.MatrixEffectMove;
-import org.distorted.library.effect.MatrixEffectScale;
-import org.distorted.library.type.Dynamic;
-import org.distorted.library.type.Dynamic3D;
-import org.distorted.library.type.Static3D;
-
-import static org.distorted.magic.RubikRenderer.TEXTURE_SIZE;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-class SizeChangeEffectAppearRound extends SizeChangeEffectAppear
-  {
-  public int createEffects(int duration)
-    {
-    float X = TEXTURE_SIZE/3;
-
-    mCubeEffectPosition = new int[] {6,7};
-    mCubeEffects        = new Effect[mCubeEffectPosition.length];
-
-    Dynamic3D d0 = new Dynamic3D(duration, 0.5f);
-    d0.add(new Static3D( 0.01f, 0.01f, 0.01f));
-    d0.add(new Static3D( 1.00f, 1.00f, 1.00f));
-    mCubeEffects[0] = new MatrixEffectScale(d0);
-
-    Dynamic3D d1 = new Dynamic3D(duration, 0.5f);
-    d1.setMode(Dynamic.MODE_PATH);
-    d1.add(new Static3D( 0, 0, 0));
-    d1.add(new Static3D(-X, 0, 0));
-    d1.add(new Static3D( 0, 0, 0));
-    mCubeEffects[1] = new MatrixEffectMove(d1);
-
-    return 2;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Enable all effects used in this Appear. Called by reflection from the parent class.
-// Matrix Effects do not have to be enabled.
-
-  @SuppressWarnings("unused")
-  static void enable()
-    {
-
-    }
-  }
-
diff --git a/src/main/java/org/distorted/effect/SizeChangeEffectAppearScale.java b/src/main/java/org/distorted/effect/SizeChangeEffectAppearScale.java
deleted file mode 100644
index 315235bf..00000000
--- a/src/main/java/org/distorted/effect/SizeChangeEffectAppearScale.java
+++ /dev/null
@@ -1,54 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Copyright 2019 Leszek Koltunski                                                               //
-//                                                                                               //
-// This file is part of Distorted.                                                               //
-//                                                                                               //
-// Distorted 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 2 of the License, or                             //
-// (at your option) any later version.                                                           //
-//                                                                                               //
-// Distorted 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 Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-package org.distorted.effect;
-
-import org.distorted.library.effect.Effect;
-import org.distorted.library.effect.MatrixEffectScale;
-import org.distorted.library.type.Dynamic3D;
-import org.distorted.library.type.Static3D;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-class SizeChangeEffectAppearScale extends SizeChangeEffectAppear
-  {
-  public int createEffects(int duration)
-    {
-    mCubeEffectPosition = new int[] {6};
-    mCubeEffects        = new Effect[mCubeEffectPosition.length];
-
-    Dynamic3D d0 = new Dynamic3D(duration, 0.5f);
-    d0.add(new Static3D(0.01f, 0.01f, 0.01f));
-    d0.add(new Static3D(1.00f, 1.00f, 1.00f));
-    mCubeEffects[0] = new MatrixEffectScale(d0);
-
-    return 1;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Enable all effects used in this Appear. Called by reflection from the parent class.
-// Matrix Effects do not have to be enabled.
-
-  @SuppressWarnings("unused")
-  static void enable()
-    {
-
-    }
-  }
-
diff --git a/src/main/java/org/distorted/effect/SizeChangeEffectAppearTransparency.java b/src/main/java/org/distorted/effect/SizeChangeEffectAppearTransparency.java
deleted file mode 100644
index 7084ea2a..00000000
--- a/src/main/java/org/distorted/effect/SizeChangeEffectAppearTransparency.java
+++ /dev/null
@@ -1,78 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Copyright 2019 Leszek Koltunski                                                               //
-//                                                                                               //
-// This file is part of Distorted.                                                               //
-//                                                                                               //
-// Distorted 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 2 of the License, or                             //
-// (at your option) any later version.                                                           //
-//                                                                                               //
-// Distorted 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 Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-package org.distorted.effect;
-
-import org.distorted.library.effect.Effect;
-import org.distorted.library.effect.FragmentEffectAlpha;
-import org.distorted.library.effect.VertexEffectWave;
-import org.distorted.library.type.Dynamic1D;
-import org.distorted.library.type.Dynamic5D;
-import org.distorted.library.type.Static1D;
-import org.distorted.library.type.Static3D;
-import org.distorted.library.type.Static5D;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-class SizeChangeEffectAppearTransparency extends SizeChangeEffectAppear
-  {
-  public int createEffects(int duration)
-    {
-    mCubeEffectPosition = new int[] {-1};
-    mCubeEffects        = new Effect[mCubeEffectPosition.length];
-
-    Dynamic1D d0 = new Dynamic1D(duration, 0.5f);
-    d0.add(new Static1D(0.0f));
-    d0.add(new Static1D(1.0f));
-    mCubeEffects[0] = new FragmentEffectAlpha(d0);
-
-    mNodeEffectPosition = new int[] {-1};
-    mNodeEffects        = new Effect[mNodeEffectPosition.length];
-
-    int w = mScreen.getWidth();
-    int h = mScreen.getHeight();
-    int min = w<h ? w:h;
-
-    float init_amplitude = min/15.0f;
-    float end_amplitude  = 0.0f;
-    float length         = min/15.0f;
-    float init_phase     = 0.0f;
-    float end_phase      = 360.0f;
-    float alpha          = 30.0f;
-    float beta           = 90.0f;
-
-    Dynamic5D d1 = new Dynamic5D(duration, 0.5f);
-    d1.add(new Static5D( init_amplitude, length, init_phase, alpha, beta) );
-    d1.add(new Static5D( end_amplitude , length, end_phase , alpha, beta) );
-    Static3D center = new Static3D(min*0.5f,min*0.5f,0);
-    mNodeEffects[0] = new VertexEffectWave(d1, center, null);
-
-    return 2;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Enable all effects used in this Appear. Called by reflection from the parent class.
-
-  @SuppressWarnings("unused")
-  static void enable()
-    {
-    FragmentEffectAlpha.enable();
-    VertexEffectWave.enable();
-    }
-  }
diff --git a/src/main/java/org/distorted/effect/SizeChangeEffectDisappear.java b/src/main/java/org/distorted/effect/SizeChangeEffectDisappear.java
deleted file mode 100644
index 99f8c2d7..00000000
--- a/src/main/java/org/distorted/effect/SizeChangeEffectDisappear.java
+++ /dev/null
@@ -1,51 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Copyright 2019 Leszek Koltunski                                                               //
-//                                                                                               //
-// This file is part of Distorted.                                                               //
-//                                                                                               //
-// Distorted 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 2 of the License, or                             //
-// (at your option) any later version.                                                           //
-//                                                                                               //
-// Distorted 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 Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-package org.distorted.effect;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-public abstract class SizeChangeEffectDisappear extends SizeChangeEffect
-  {
-  SizeChangeEffectDisappear()
-    {
-    super(-2);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public static SizeChangeEffectDisappear create(Type type) throws InstantiationException, IllegalAccessException
-    {
-    return type.disappear.newInstance();
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  void effectsEnd()
-    {
-    mScreen.detach(mCube);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  void startEnd()
-    {
-
-    }
-  }
diff --git a/src/main/java/org/distorted/effect/SizeChangeEffectDisappearMove.java b/src/main/java/org/distorted/effect/SizeChangeEffectDisappearMove.java
deleted file mode 100644
index 7b42c0b2..00000000
--- a/src/main/java/org/distorted/effect/SizeChangeEffectDisappearMove.java
+++ /dev/null
@@ -1,58 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Copyright 2019 Leszek Koltunski                                                               //
-//                                                                                               //
-// This file is part of Distorted.                                                               //
-//                                                                                               //
-// Distorted 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 2 of the License, or                             //
-// (at your option) any later version.                                                           //
-//                                                                                               //
-// Distorted 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 Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-package org.distorted.effect;
-
-import org.distorted.library.effect.Effect;
-import org.distorted.library.effect.MatrixEffectMove;
-import org.distorted.library.type.Dynamic3D;
-import org.distorted.library.type.Static3D;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-class SizeChangeEffectDisappearMove extends SizeChangeEffectDisappear
-  {
-  public int createEffects(int duration)
-    {
-    int w = mScreen.getWidth();
-    int h = mScreen.getHeight();
-    int xmove = w/2 + (w<h?w:h)/2;
-
-    mNodeEffectPosition = new int[] {1};
-    mNodeEffects        = new Effect[mNodeEffectPosition.length];
-
-    Dynamic3D d0 = new Dynamic3D(duration, 0.5f);
-    d0.add(new Static3D(    0,0,0));
-    d0.add(new Static3D(xmove,0,0));
-    mNodeEffects[0] = new MatrixEffectMove(d0);
-
-    return 1;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Enable all effects used in this Appear. Called by reflection from the parent class.
-// Matrix Effects do not have to be enabled.
-
-  @SuppressWarnings("unused")
-  static void enable()
-    {
-
-    }
-  }
-
diff --git a/src/main/java/org/distorted/effect/SizeChangeEffectDisappearNone.java b/src/main/java/org/distorted/effect/SizeChangeEffectDisappearNone.java
deleted file mode 100644
index b4056a97..00000000
--- a/src/main/java/org/distorted/effect/SizeChangeEffectDisappearNone.java
+++ /dev/null
@@ -1,51 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Copyright 2019 Leszek Koltunski                                                               //
-//                                                                                               //
-// This file is part of Distorted.                                                               //
-//                                                                                               //
-// Distorted 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 2 of the License, or                             //
-// (at your option) any later version.                                                           //
-//                                                                                               //
-// Distorted 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 Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-package org.distorted.effect;
-
-import org.distorted.library.effect.Effect;
-import org.distorted.library.effect.MatrixEffectMove;
-import org.distorted.library.type.Dynamic3D;
-import org.distorted.library.type.Static3D;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-class SizeChangeEffectDisappearNone extends SizeChangeEffectDisappear
-  {
-  public int createEffects(int duration)
-    {
-    mCubeEffectPosition = new int[] {-1};
-    mCubeEffects        = new Effect[mCubeEffectPosition.length];
-
-    Dynamic3D d0 = new Dynamic3D(1,0.5f);
-    d0.add(new Static3D(0,0,0));
-    mCubeEffects[0] = new MatrixEffectMove(d0);
-
-    return 1;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// enable all effects used in this Appear (here: none).  Called by reflection from the parent class.
-
-  @SuppressWarnings("unused")
-  static void enable()
-    {
-
-    }
-  }
diff --git a/src/main/java/org/distorted/effect/SizeChangeEffectDisappearRound.java b/src/main/java/org/distorted/effect/SizeChangeEffectDisappearRound.java
deleted file mode 100644
index 67ab1fd1..00000000
--- a/src/main/java/org/distorted/effect/SizeChangeEffectDisappearRound.java
+++ /dev/null
@@ -1,67 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Copyright 2019 Leszek Koltunski                                                               //
-//                                                                                               //
-// This file is part of Distorted.                                                               //
-//                                                                                               //
-// Distorted 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 2 of the License, or                             //
-// (at your option) any later version.                                                           //
-//                                                                                               //
-// Distorted 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 Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-package org.distorted.effect;
-
-import org.distorted.library.effect.Effect;
-import org.distorted.library.effect.MatrixEffectMove;
-import org.distorted.library.effect.MatrixEffectScale;
-import org.distorted.library.type.Dynamic;
-import org.distorted.library.type.Dynamic3D;
-import org.distorted.library.type.Static3D;
-
-import static org.distorted.magic.RubikRenderer.TEXTURE_SIZE;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-class SizeChangeEffectDisappearRound extends SizeChangeEffectDisappear
-  {
-  public int createEffects(int duration)
-    {
-    float X = TEXTURE_SIZE/3;
-
-    mCubeEffectPosition = new int[] {6,7};
-    mCubeEffects        = new Effect[mCubeEffectPosition.length];
-
-    Dynamic3D d0 = new Dynamic3D(duration, 0.5f);
-    d0.add(new Static3D( 1.00f, 1.00f, 1.00f));
-    d0.add(new Static3D( 0.01f, 0.01f, 0.01f));
-    mCubeEffects[0] = new MatrixEffectScale(d0);
-
-    Dynamic3D d1 = new Dynamic3D(duration, 0.5f);
-    d1.setMode(Dynamic.MODE_PATH);
-    d1.add(new Static3D( 0, 0, 0));
-    d1.add(new Static3D(+X, 0, 0));
-    d1.add(new Static3D( 0, 0, 0));
-    mCubeEffects[1] = new MatrixEffectMove(d1);
-
-    return 2;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Enable all effects used in this Appear. Called by reflection from the parent class.
-// Matrix Effects do not have to be enabled.
-
-  @SuppressWarnings("unused")
-  static void enable()
-    {
-
-    }
-  }
-
diff --git a/src/main/java/org/distorted/effect/SizeChangeEffectDisappearScale.java b/src/main/java/org/distorted/effect/SizeChangeEffectDisappearScale.java
deleted file mode 100644
index 1e6a740b..00000000
--- a/src/main/java/org/distorted/effect/SizeChangeEffectDisappearScale.java
+++ /dev/null
@@ -1,54 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Copyright 2019 Leszek Koltunski                                                               //
-//                                                                                               //
-// This file is part of Distorted.                                                               //
-//                                                                                               //
-// Distorted 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 2 of the License, or                             //
-// (at your option) any later version.                                                           //
-//                                                                                               //
-// Distorted 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 Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-package org.distorted.effect;
-
-import org.distorted.library.effect.Effect;
-import org.distorted.library.effect.MatrixEffectScale;
-import org.distorted.library.type.Dynamic3D;
-import org.distorted.library.type.Static3D;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-class SizeChangeEffectDisappearScale extends SizeChangeEffectDisappear
-  {
-  public int createEffects(int duration)
-    {
-    mCubeEffectPosition = new int[] {6};
-    mCubeEffects        = new Effect[mCubeEffectPosition.length];
-
-    Dynamic3D d0 = new Dynamic3D(duration, 0.5f);
-    d0.add(new Static3D(1.00f, 1.00f, 1.00f));
-    d0.add(new Static3D(0.01f, 0.01f, 0.01f));
-    mCubeEffects[0] = new MatrixEffectScale(d0);
-
-    return 1;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Enable all effects used in this Appear. Called by reflection from the parent class.
-// Matrix Effects do not have to be enabled.
-
-  @SuppressWarnings("unused")
-  static void enable()
-    {
-
-    }
-  }
-
diff --git a/src/main/java/org/distorted/effect/SizeChangeEffectDisappearTransparency.java b/src/main/java/org/distorted/effect/SizeChangeEffectDisappearTransparency.java
deleted file mode 100644
index a844559c..00000000
--- a/src/main/java/org/distorted/effect/SizeChangeEffectDisappearTransparency.java
+++ /dev/null
@@ -1,78 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Copyright 2019 Leszek Koltunski                                                               //
-//                                                                                               //
-// This file is part of Distorted.                                                               //
-//                                                                                               //
-// Distorted 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 2 of the License, or                             //
-// (at your option) any later version.                                                           //
-//                                                                                               //
-// Distorted 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 Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-package org.distorted.effect;
-
-import org.distorted.library.effect.Effect;
-import org.distorted.library.effect.FragmentEffectAlpha;
-import org.distorted.library.effect.VertexEffectWave;
-import org.distorted.library.type.Dynamic1D;
-import org.distorted.library.type.Dynamic5D;
-import org.distorted.library.type.Static1D;
-import org.distorted.library.type.Static3D;
-import org.distorted.library.type.Static5D;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-class SizeChangeEffectDisappearTransparency extends SizeChangeEffectDisappear
-  {
-  public int createEffects(int duration)
-    {
-    mCubeEffectPosition = new int[] {-1};
-    mCubeEffects        = new Effect[mCubeEffectPosition.length];
-
-    Dynamic1D d0 = new Dynamic1D(duration, 0.5f);
-    d0.add(new Static1D(1.0f));
-    d0.add(new Static1D(0.0f));
-    mCubeEffects[0] = new FragmentEffectAlpha(d0);
-
-    mNodeEffectPosition = new int[] {-1};
-    mNodeEffects        = new Effect[mNodeEffectPosition.length];
-
-    int w = mScreen.getWidth();
-    int h = mScreen.getHeight();
-    int min = w<h ? w:h;
-
-    float init_amplitude = 0.0f;
-    float end_amplitude  = min/15.0f;
-    float length         = min/15.0f;
-    float init_phase     = 360.0f;
-    float end_phase      = 0.0f;
-    float alpha          = 30.0f;
-    float beta           = 90.0f;
-
-    Dynamic5D d1 = new Dynamic5D(duration, 0.5f);
-    d1.add(new Static5D( init_amplitude, length, init_phase, alpha, beta) );
-    d1.add(new Static5D( end_amplitude , length, end_phase , alpha, beta) );
-    Static3D center = new Static3D(min*0.5f,min*0.5f,0);
-    mNodeEffects[0] = new VertexEffectWave(d1, center, null);
-
-    return 2;
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Enable all effects used in this Appear. Called by reflection from the parent class.
-
-  @SuppressWarnings("unused")
-  static void enable()
-    {
-    FragmentEffectAlpha.enable();
-    VertexEffectWave.enable();
-    }
-  }
diff --git a/src/main/java/org/distorted/effect/SizeChangeEffectMove.java b/src/main/java/org/distorted/effect/SizeChangeEffectMove.java
new file mode 100644
index 00000000..0de8d68b
--- /dev/null
+++ b/src/main/java/org/distorted/effect/SizeChangeEffectMove.java
@@ -0,0 +1,77 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Copyright 2019 Leszek Koltunski                                                               //
+//                                                                                               //
+// This file is part of Distorted.                                                               //
+//                                                                                               //
+// Distorted 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 2 of the License, or                             //
+// (at your option) any later version.                                                           //
+//                                                                                               //
+// Distorted 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 Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+package org.distorted.effect;
+
+import org.distorted.library.effect.Effect;
+import org.distorted.library.effect.MatrixEffectMove;
+import org.distorted.library.type.Dynamic3D;
+import org.distorted.library.type.Static3D;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+class SizeChangeEffectMove extends SizeChangeEffect
+  {
+  public int createEffectsPhase0(int duration)
+    {
+    int w = mScreen.getWidth();
+    int h = mScreen.getHeight();
+    int xmove = w/2 + (w<h?w:h)/2;
+
+    mNodeEffectPosition[0] = new int[] {1};
+    mNodeEffects[0]        = new Effect[mNodeEffectPosition[0].length];
+
+    Dynamic3D d0 = new Dynamic3D(duration, 0.5f);
+    d0.add(new Static3D(    0,0,0));
+    d0.add(new Static3D(xmove,0,0));
+    mNodeEffects[0][0] = new MatrixEffectMove(d0);
+
+    return 1;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  public int createEffectsPhase1(int duration)
+    {
+    int w = mScreen.getWidth();
+    int h = mScreen.getHeight();
+    int xmove = w/2 + (w<h?w:h)/2;
+
+    mNodeEffectPosition[1] = new int[] {1};
+    mNodeEffects[1]        = new Effect[mNodeEffectPosition[1].length];
+
+    Dynamic3D d0 = new Dynamic3D(duration, 0.5f);
+    d0.add(new Static3D(-xmove,0,0));
+    d0.add(new Static3D(     0,0,0));
+    mNodeEffects[1][0] = new MatrixEffectMove(d0);
+
+    return 1;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Enable all effects used in this Appear. Called by reflection from the parent class.
+// Matrix Effects do not have to be enabled.
+
+  @SuppressWarnings("unused")
+  static void enable()
+    {
+
+    }
+  }
+
diff --git a/src/main/java/org/distorted/effect/SizeChangeEffectNone.java b/src/main/java/org/distorted/effect/SizeChangeEffectNone.java
new file mode 100644
index 00000000..4e47791c
--- /dev/null
+++ b/src/main/java/org/distorted/effect/SizeChangeEffectNone.java
@@ -0,0 +1,65 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Copyright 2019 Leszek Koltunski                                                               //
+//                                                                                               //
+// This file is part of Distorted.                                                               //
+//                                                                                               //
+// Distorted 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 2 of the License, or                             //
+// (at your option) any later version.                                                           //
+//                                                                                               //
+// Distorted 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 Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+package org.distorted.effect;
+
+import org.distorted.library.effect.Effect;
+import org.distorted.library.effect.MatrixEffectMove;
+import org.distorted.library.type.Dynamic3D;
+import org.distorted.library.type.Static3D;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+class SizeChangeEffectNone extends SizeChangeEffect
+  {
+  public int createEffectsPhase0(int duration)
+    {
+    mCubeEffectPosition[0] = new int[] {-1};
+    mCubeEffects[0]        = new Effect[mCubeEffectPosition[0].length];
+
+    Dynamic3D d0 = new Dynamic3D(1,0.5f);
+    d0.add(new Static3D(0,0,0));
+    mCubeEffects[0][0] = new MatrixEffectMove(d0);
+
+    return 1;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  public int createEffectsPhase1(int duration)
+    {
+    mCubeEffectPosition[1] = new int[] {-1};
+    mCubeEffects[1]        = new Effect[mCubeEffectPosition[1].length];
+
+    Dynamic3D d0 = new Dynamic3D(1,0.5f);
+    d0.add(new Static3D(0,0,0));
+    mCubeEffects[1][0] = new MatrixEffectMove(d0);
+
+    return 1;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// enable all effects used in this Appear (here: none).  Called by reflection from the parent class.
+
+  @SuppressWarnings("unused")
+  static void enable()
+    {
+
+    }
+  }
diff --git a/src/main/java/org/distorted/effect/SizeChangeEffectRound.java b/src/main/java/org/distorted/effect/SizeChangeEffectRound.java
new file mode 100644
index 00000000..c51d186a
--- /dev/null
+++ b/src/main/java/org/distorted/effect/SizeChangeEffectRound.java
@@ -0,0 +1,91 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Copyright 2019 Leszek Koltunski                                                               //
+//                                                                                               //
+// This file is part of Distorted.                                                               //
+//                                                                                               //
+// Distorted 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 2 of the License, or                             //
+// (at your option) any later version.                                                           //
+//                                                                                               //
+// Distorted 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 Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+package org.distorted.effect;
+
+import org.distorted.library.effect.Effect;
+import org.distorted.library.effect.MatrixEffectMove;
+import org.distorted.library.effect.MatrixEffectScale;
+import org.distorted.library.type.Dynamic;
+import org.distorted.library.type.Dynamic3D;
+import org.distorted.library.type.Static3D;
+
+import static org.distorted.magic.RubikRenderer.TEXTURE_SIZE;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+class SizeChangeEffectRound extends SizeChangeEffect
+  {
+  public int createEffectsPhase0(int duration)
+    {
+    float X = TEXTURE_SIZE/3;
+
+    mCubeEffectPosition[0] = new int[] {6,7};
+    mCubeEffects[0]        = new Effect[mCubeEffectPosition[0].length];
+
+    Dynamic3D d0 = new Dynamic3D(duration, 0.5f);
+    d0.add(new Static3D( 1.00f, 1.00f, 1.00f));
+    d0.add(new Static3D( 0.01f, 0.01f, 0.01f));
+    mCubeEffects[0][0] = new MatrixEffectScale(d0);
+
+    Dynamic3D d1 = new Dynamic3D(duration, 0.5f);
+    d1.setMode(Dynamic.MODE_PATH);
+    d1.add(new Static3D( 0, 0, 0));
+    d1.add(new Static3D(+X, 0, 0));
+    d1.add(new Static3D( 0, 0, 0));
+    mCubeEffects[0][1] = new MatrixEffectMove(d1);
+
+    return 2;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  public int createEffectsPhase1(int duration)
+    {
+    float X = TEXTURE_SIZE/3;
+
+    mCubeEffectPosition[1] = new int[] {6,7};
+    mCubeEffects[1]        = new Effect[mCubeEffectPosition[1].length];
+
+    Dynamic3D d0 = new Dynamic3D(duration, 0.5f);
+    d0.add(new Static3D( 0.01f, 0.01f, 0.01f));
+    d0.add(new Static3D( 1.00f, 1.00f, 1.00f));
+    mCubeEffects[1][0] = new MatrixEffectScale(d0);
+
+    Dynamic3D d1 = new Dynamic3D(duration, 0.5f);
+    d1.setMode(Dynamic.MODE_PATH);
+    d1.add(new Static3D( 0, 0, 0));
+    d1.add(new Static3D(-X, 0, 0));
+    d1.add(new Static3D( 0, 0, 0));
+    mCubeEffects[1][1] = new MatrixEffectMove(d1);
+
+    return 2;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Enable all effects used in this Appear. Called by reflection from the parent class.
+// Matrix Effects do not have to be enabled.
+
+  @SuppressWarnings("unused")
+  static void enable()
+    {
+
+    }
+  }
+
diff --git a/src/main/java/org/distorted/effect/SizeChangeEffectScale.java b/src/main/java/org/distorted/effect/SizeChangeEffectScale.java
new file mode 100644
index 00000000..ce6e34aa
--- /dev/null
+++ b/src/main/java/org/distorted/effect/SizeChangeEffectScale.java
@@ -0,0 +1,69 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Copyright 2019 Leszek Koltunski                                                               //
+//                                                                                               //
+// This file is part of Distorted.                                                               //
+//                                                                                               //
+// Distorted 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 2 of the License, or                             //
+// (at your option) any later version.                                                           //
+//                                                                                               //
+// Distorted 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 Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+package org.distorted.effect;
+
+import org.distorted.library.effect.Effect;
+import org.distorted.library.effect.MatrixEffectScale;
+import org.distorted.library.type.Dynamic3D;
+import org.distorted.library.type.Static3D;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+class SizeChangeEffectScale extends SizeChangeEffect
+  {
+  public int createEffectsPhase0(int duration)
+    {
+    mCubeEffectPosition[0] = new int[] {6};
+    mCubeEffects[0]        = new Effect[mCubeEffectPosition[0].length];
+
+    Dynamic3D d0 = new Dynamic3D(duration, 0.5f);
+    d0.add(new Static3D(1.00f, 1.00f, 1.00f));
+    d0.add(new Static3D(0.01f, 0.01f, 0.01f));
+    mCubeEffects[0][0] = new MatrixEffectScale(d0);
+
+    return 1;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  public int createEffectsPhase1(int duration)
+    {
+    mCubeEffectPosition[1] = new int[] {6};
+    mCubeEffects[1]        = new Effect[mCubeEffectPosition[1].length];
+
+    Dynamic3D d0 = new Dynamic3D(duration, 0.5f);
+    d0.add(new Static3D(0.01f, 0.01f, 0.01f));
+    d0.add(new Static3D(1.00f, 1.00f, 1.00f));
+    mCubeEffects[1][0] = new MatrixEffectScale(d0);
+
+    return 1;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Enable all effects used in this Appear. Called by reflection from the parent class.
+// Matrix Effects do not have to be enabled.
+
+  @SuppressWarnings("unused")
+  static void enable()
+    {
+
+    }
+  }
+
diff --git a/src/main/java/org/distorted/effect/SizeChangeEffectTransparency.java b/src/main/java/org/distorted/effect/SizeChangeEffectTransparency.java
new file mode 100644
index 00000000..63d7cb5e
--- /dev/null
+++ b/src/main/java/org/distorted/effect/SizeChangeEffectTransparency.java
@@ -0,0 +1,114 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Copyright 2019 Leszek Koltunski                                                               //
+//                                                                                               //
+// This file is part of Distorted.                                                               //
+//                                                                                               //
+// Distorted 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 2 of the License, or                             //
+// (at your option) any later version.                                                           //
+//                                                                                               //
+// Distorted 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 Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+package org.distorted.effect;
+
+import org.distorted.library.effect.Effect;
+import org.distorted.library.effect.FragmentEffectAlpha;
+import org.distorted.library.effect.VertexEffectWave;
+import org.distorted.library.type.Dynamic1D;
+import org.distorted.library.type.Dynamic5D;
+import org.distorted.library.type.Static1D;
+import org.distorted.library.type.Static3D;
+import org.distorted.library.type.Static5D;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+class SizeChangeEffectTransparency extends SizeChangeEffect
+  {
+  public int createEffectsPhase0(int duration)
+    {
+    mCubeEffectPosition[0] = new int[] {-1};
+    mCubeEffects[0]        = new Effect[mCubeEffectPosition[0].length];
+
+    Dynamic1D d0 = new Dynamic1D(duration, 0.5f);
+    d0.add(new Static1D(1.0f));
+    d0.add(new Static1D(0.0f));
+    mCubeEffects[0][0] = new FragmentEffectAlpha(d0);
+
+    mNodeEffectPosition[0] = new int[] {-1};
+    mNodeEffects[0]        = new Effect[mNodeEffectPosition[0].length];
+
+    int w = mScreen.getWidth();
+    int h = mScreen.getHeight();
+    int min = w<h ? w:h;
+
+    float init_amplitude = 0.0f;
+    float end_amplitude  = min/15.0f;
+    float length         = min/15.0f;
+    float init_phase     = 360.0f;
+    float end_phase      = 0.0f;
+    float alpha          = 30.0f;
+    float beta           = 90.0f;
+
+    Dynamic5D d1 = new Dynamic5D(duration, 0.5f);
+    d1.add(new Static5D( init_amplitude, length, init_phase, alpha, beta) );
+    d1.add(new Static5D( end_amplitude , length, end_phase , alpha, beta) );
+    Static3D center = new Static3D(min*0.5f,min*0.5f,0);
+    mNodeEffects[0][0] = new VertexEffectWave(d1, center, null);
+
+    return 2;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  public int createEffectsPhase1(int duration)
+    {
+    mCubeEffectPosition[1] = new int[] {-1};
+    mCubeEffects[1]        = new Effect[mCubeEffectPosition[1].length];
+
+    Dynamic1D d0 = new Dynamic1D(duration, 0.5f);
+    d0.add(new Static1D(0.0f));
+    d0.add(new Static1D(1.0f));
+    mCubeEffects[1][0] = new FragmentEffectAlpha(d0);
+
+    mNodeEffectPosition[1] = new int[] {-1};
+    mNodeEffects[1]        = new Effect[mNodeEffectPosition[1].length];
+
+    int w = mScreen.getWidth();
+    int h = mScreen.getHeight();
+    int min = w<h ? w:h;
+
+    float init_amplitude = min/15.0f;
+    float end_amplitude  = 0.0f;
+    float length         = min/15.0f;
+    float init_phase     = 0.0f;
+    float end_phase      = 360.0f;
+    float alpha          = 30.0f;
+    float beta           = 90.0f;
+
+    Dynamic5D d1 = new Dynamic5D(duration, 0.5f);
+    d1.add(new Static5D( init_amplitude, length, init_phase, alpha, beta) );
+    d1.add(new Static5D( end_amplitude , length, end_phase , alpha, beta) );
+    Static3D center = new Static3D(min*0.5f,min*0.5f,0);
+    mNodeEffects[1][0] = new VertexEffectWave(d1, center, null);
+
+    return 2;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Enable all effects used in this Appear. Called by reflection from the parent class.
+
+  @SuppressWarnings("unused")
+  static void enable()
+    {
+    FragmentEffectAlpha.enable();
+    VertexEffectWave.enable();
+    }
+  }
diff --git a/src/main/java/org/distorted/effect/UnscrambleEffect.java b/src/main/java/org/distorted/effect/UnscrambleEffect.java
index bd5052e0..97b41811 100644
--- a/src/main/java/org/distorted/effect/UnscrambleEffect.java
+++ b/src/main/java/org/distorted/effect/UnscrambleEffect.java
@@ -45,7 +45,9 @@ public abstract class UnscrambleEffect implements EffectListener
       }
     }
 
-  private static int NUM_EFFECTS = Type.values().length;
+  private static final int NUM_EFFECTS = Type.values().length;
+  private static final int NUM_PHASES  = 2;
+  private static final int FAKE_EFFECT_ID = -2;
   private static final Type[] types;
 
   static
@@ -60,23 +62,30 @@ public abstract class UnscrambleEffect implements EffectListener
     }
 
   private EffectListener mListener;
-  private int mCubeEffectNumberBefore, mCubeEffectNumberAfter, mNodeEffectNumberBefore, mNodeEffectNumberAfter, mEffectReturned;
-  private int mFakeEffectID;
-  private boolean mPhaseBefore;
+  private int mDuration;
+  private int mEffectReturned;
+  private int[] mCubeEffectNumber, mNodeEffectNumber;
+  private int mPhase;
 
   RubikCube mCube;
   DistortedScreen mScreen;
-  Effect[] mCubeEffectsBefore, mCubeEffectsAfter;
-  int[] mCubeEffectPositionBefore, mCubeEffectPositionAfter;
-  Effect[] mNodeEffectsBefore, mNodeEffectsAfter;
-  int[] mNodeEffectPositionBefore, mNodeEffectPositionAfter;
+  Effect[][] mCubeEffects;
+  int[][] mCubeEffectPosition;
+  Effect[][] mNodeEffects;
+  int[][] mNodeEffectPosition;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
   UnscrambleEffect()
     {
-    mFakeEffectID = -3;
-    mPhaseBefore  = true;
+    mPhase        =  0;
+
+    mCubeEffectNumber   = new int[NUM_PHASES];
+    mNodeEffectNumber   = new int[NUM_PHASES];
+    mCubeEffectPosition = new int[NUM_PHASES][];
+    mNodeEffectPosition = new int[NUM_PHASES][];
+    mCubeEffects        = new Effect[NUM_PHASES][];
+    mNodeEffects        = new Effect[NUM_PHASES][];
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -109,91 +118,53 @@ public abstract class UnscrambleEffect implements EffectListener
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  abstract void createEffects(int duration);
+  abstract void createEffectsPhase0(int duration);
+  abstract void createEffectsPhase1(int duration);
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
   public void effectFinished(final long effectID)
     {
-    if( mPhaseBefore ) effectFinishedBefore(effectID);
-    else               effectFinishedAfter (effectID);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
+    int total = mCubeEffectNumber[mPhase]+mNodeEffectNumber[mPhase];
 
-  private void effectFinishedBefore(final long effectID)
-    {
-    for(int i=0; i<mCubeEffectNumberBefore; i++)
+    for(int i=0; i<mCubeEffectNumber[mPhase]; i++)
       {
-      long id = mCubeEffectsBefore[i].getID();
+      long id = mCubeEffects[mPhase][i].getID();
 
       if( effectID == id )
         {
-        if( ++mEffectReturned == mCubeEffectNumberBefore+mNodeEffectNumberBefore )
-          {
-          mEffectReturned = 0;
-          mPhaseBefore    = false;
-          mCube.unscramble();
-          assignEffectsAfter();
-          }
-
+        if( ++mEffectReturned == total ) effectAction(mPhase);
         mCube.remove(id);
-        break;
+        return;
         }
       }
-    for(int i=0; i<mNodeEffectNumberBefore; i++)
+    for(int i=0; i<mNodeEffectNumber[mPhase]; i++)
       {
-      long id = mNodeEffectsBefore[i].getID();
+      long id = mNodeEffects[mPhase][i].getID();
 
       if( effectID == id )
         {
-        if( ++mEffectReturned == mCubeEffectNumberBefore+mNodeEffectNumberBefore )
-          {
-          mEffectReturned = 0;
-          mPhaseBefore    = false;
-          mCube.unscramble();
-          assignEffectsAfter();
-          }
-
+        if( ++mEffectReturned == total ) effectAction(mPhase);
         mCube.getEffects().abortById(id);
-        break;
+        return;
         }
       }
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  private void effectFinishedAfter(final long effectID)
+  private void effectAction(int phase)
     {
-    for(int i=0; i<mCubeEffectNumberAfter; i++)
+    switch(phase)
       {
-      long id = mCubeEffectsAfter[i].getID();
-
-      if( effectID == id )
-        {
-        if( ++mEffectReturned == mCubeEffectNumberAfter+mNodeEffectNumberAfter )
-          {
-          mListener.effectFinished(mFakeEffectID);
-          }
-
-        mCube.remove(id);
-        break;
-        }
-      }
-    for(int i=0; i<mNodeEffectNumberAfter; i++)
-      {
-      long id = mNodeEffectsAfter[i].getID();
-
-      if( effectID == id )
-        {
-        if( ++mEffectReturned == mCubeEffectNumberAfter+mNodeEffectNumberAfter )
-          {
-          mListener.effectFinished(mFakeEffectID);
-          }
-
-        mCube.getEffects().abortById(id);
-        break;
-        }
+      case 0: mEffectReturned = 0;
+              mPhase          = 1;
+              mCube.unscramble();
+              createEffectsPhase1(mDuration);
+              assignEffects(mPhase);
+              break;
+      case 1: mListener.effectFinished(FAKE_EFFECT_ID);
+              break;
       }
     }
 
@@ -204,68 +175,44 @@ public abstract class UnscrambleEffect implements EffectListener
     mScreen   = screen;
     mCube     = cube;
     mListener = listener;
+    mDuration = duration;
 
-    createEffects(duration);
-    assignEffectsBefore();
+    createEffectsPhase0(mDuration);
+    assignEffects(mPhase);
 
-    return mFakeEffectID;
+    return FAKE_EFFECT_ID;
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  private void assignEffectsBefore()
+  private void assignEffects(int phase)
     {
-    mCubeEffectNumberBefore = ( mCubeEffectsBefore!=null ) ? mCubeEffectsBefore.length : 0;
-    mNodeEffectNumberBefore = ( mNodeEffectsBefore!=null ) ? mNodeEffectsBefore.length : 0;
+    mCubeEffectNumber[phase] = ( mCubeEffects[phase]!=null ) ? mCubeEffects[phase].length : 0;
+    mNodeEffectNumber[phase] = ( mNodeEffects[phase]!=null ) ? mNodeEffects[phase].length : 0;
 
-    if( mCubeEffectNumberBefore==0 && mNodeEffectNumberBefore==0 )
+    if( mCubeEffectNumber[phase]==0 && mNodeEffectNumber[phase]==0 )
       {
-      throw new RuntimeException("Cube and Node Effects ('Before' phase) both not created!");
+      throw new RuntimeException("Cube and Node Effects ("+phase+" phase) both not created!");
       }
 
-    for(int i=0; i<mCubeEffectNumberBefore; i++)
+    for(int i=0; i<mCubeEffectNumber[phase]; i++)
       {
-      mCube.apply(mCubeEffectsBefore[i],mCubeEffectPositionBefore[i]);
-      mCubeEffectsBefore[i].notifyWhenFinished(this);
+      mCube.apply(mCubeEffects[phase][i],mCubeEffectPosition[phase][i]);
+      mCubeEffects[phase][i].notifyWhenFinished(this);
       }
 
     DistortedEffects nodeEffects = mCube.getEffects();
 
-    for(int i=0; i<mNodeEffectNumberBefore; i++)
+    for(int i=0; i<mNodeEffectNumber[phase]; i++)
       {
-      nodeEffects.apply(mNodeEffectsBefore[i],mNodeEffectPositionBefore[i]);
-      mNodeEffectsBefore[i].notifyWhenFinished(this);
+      nodeEffects.apply(mNodeEffects[phase][i],mNodeEffectPosition[phase][i]);
+      mNodeEffects[phase][i].notifyWhenFinished(this);
       }
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  private void assignEffectsAfter()
-    {
-    mCubeEffectNumberAfter = ( mCubeEffectsAfter!=null ) ? mCubeEffectsAfter.length : 0;
-    mNodeEffectNumberAfter = ( mNodeEffectsAfter!=null ) ? mNodeEffectsAfter.length : 0;
-
-    if( mCubeEffectNumberAfter==0 && mNodeEffectNumberAfter==0 )
-      {
-      throw new RuntimeException("Cube and Node Effects ('After' phase) both not created!");
-      }
-
-    for(int i=0; i<mCubeEffectNumberAfter; i++)
-      {
-      mCube.apply(mCubeEffectsAfter[i],mCubeEffectPositionAfter[i]);
-      mCubeEffectsAfter[i].notifyWhenFinished(this);
-      }
-
-    DistortedEffects nodeEffects = mCube.getEffects();
-
-    for(int i=0; i<mNodeEffectNumberAfter; i++)
-      {
-      nodeEffects.apply(mNodeEffectsAfter[i],mNodeEffectPositionAfter[i]);
-      mNodeEffectsAfter[i].notifyWhenFinished(this);
-      }
-    }
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
+  @SuppressWarnings("unused")
   public static void enableEffects()
     {
     Method method=null;
diff --git a/src/main/java/org/distorted/effect/UnscrambleEffectNone.java b/src/main/java/org/distorted/effect/UnscrambleEffectNone.java
index 8d6463c8..1913e5ba 100644
--- a/src/main/java/org/distorted/effect/UnscrambleEffectNone.java
+++ b/src/main/java/org/distorted/effect/UnscrambleEffectNone.java
@@ -28,18 +28,26 @@ import org.distorted.library.type.Static3D;
 
 public class UnscrambleEffectNone extends UnscrambleEffect
   {
-  public void createEffects(int duration)
+  public void createEffectsPhase0(int duration)
     {
     Dynamic3D d0 = new Dynamic3D(1,0.5f);
     d0.add(new Static3D(0,0,0));
 
-    mCubeEffectPositionBefore = new int[] {-1};
-    mCubeEffectsBefore        = new Effect[mCubeEffectPositionBefore.length];
-    mCubeEffectsBefore[0]     = new MatrixEffectMove(d0);
+    mCubeEffectPosition[0] = new int[] {-1};
+    mCubeEffects[0]        = new Effect[mCubeEffectPosition[0].length];
+    mCubeEffects[0][0]     = new MatrixEffectMove(d0);
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  public void createEffectsPhase1(int duration)
+    {
+    Dynamic3D d0 = new Dynamic3D(1,0.5f);
+    d0.add(new Static3D(0,0,0));
 
-    mCubeEffectPositionAfter  = new int[] {-1};
-    mCubeEffectsAfter         = new Effect[mCubeEffectPositionAfter.length];
-    mCubeEffectsAfter[0]      = new MatrixEffectMove(d0);
+    mCubeEffectPosition[1]  = new int[] {-1};
+    mCubeEffects[1]         = new Effect[mCubeEffectPosition[1].length];
+    mCubeEffects[1][0]      = new MatrixEffectMove(d0);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/effect/UnscrambleEffectSpin.java b/src/main/java/org/distorted/effect/UnscrambleEffectSpin.java
index 54f69fbf..af18641d 100644
--- a/src/main/java/org/distorted/effect/UnscrambleEffectSpin.java
+++ b/src/main/java/org/distorted/effect/UnscrambleEffectSpin.java
@@ -28,23 +28,28 @@ import org.distorted.library.type.Static3D;
 
 public class UnscrambleEffectSpin extends UnscrambleEffect
   {
-  public void createEffects(int duration)
+  public void createEffectsPhase0(int duration)
     {
-    mCubeEffectPositionBefore = new int[] {6};
-    mCubeEffectsBefore        = new Effect[mCubeEffectPositionBefore.length];
+    mCubeEffectPosition[0] = new int[] {6};
+    mCubeEffects[0]        = new Effect[mCubeEffectPosition[0].length];
 
     Dynamic3D d0 = new Dynamic3D(duration, 0.5f);
     d0.add(new Static3D(1.00f, 1.00f, 1.00f));
     d0.add(new Static3D(0.01f, 0.01f, 0.01f));
-    mCubeEffectsBefore[0] = new MatrixEffectScale(d0);
+    mCubeEffects[0][0] = new MatrixEffectScale(d0);
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
 
-    mCubeEffectPositionAfter = new int[] {6};
-    mCubeEffectsAfter        = new Effect[mCubeEffectPositionAfter.length];
+  public void createEffectsPhase1(int duration)
+    {
+    mCubeEffectPosition[1] = new int[] {6};
+    mCubeEffects[1]        = new Effect[mCubeEffectPosition[1].length];
 
     Dynamic3D d1 = new Dynamic3D(duration, 0.5f);
     d1.add(new Static3D(0.01f, 0.01f, 0.01f));
     d1.add(new Static3D(1.00f, 1.00f, 1.00f));
-    mCubeEffectsAfter[0] = new MatrixEffectScale(d1);
+    mCubeEffects[1][0] = new MatrixEffectScale(d1);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/magic/RubikActivity.java b/src/main/java/org/distorted/magic/RubikActivity.java
index e85b6722..1f96ef47 100644
--- a/src/main/java/org/distorted/magic/RubikActivity.java
+++ b/src/main/java/org/distorted/magic/RubikActivity.java
@@ -30,8 +30,7 @@ import android.support.v7.app.AppCompatActivity;
 import android.view.View;
 
 import org.distorted.component.HorizontalNumberPicker;
-import org.distorted.effect.SizeChangeEffectAppear;
-import org.distorted.effect.SizeChangeEffectDisappear;
+import org.distorted.effect.SizeChangeEffect;
 import org.distorted.effect.UnscrambleEffect;
 import org.distorted.library.main.DistortedLibrary;
 
@@ -251,7 +250,7 @@ public class RubikActivity extends AppCompatActivity implements RubikSettings.On
 
      renderer.setSizeChangeDuration(translateDuration(mSizeChangePos)+1);
      renderer.setUnscrambleDuration(translateDuration(mUnscramblePos)+1);
-     renderer.setSizeChangeType(SizeChangeEffectAppear.getType(mSizeChangeType));
+     renderer.setSizeChangeType(SizeChangeEffect.getType(mSizeChangeType));
      renderer.setUnscrambleType(UnscrambleEffect.getType(mUnscrambleType));
      }
 
diff --git a/src/main/java/org/distorted/magic/RubikRenderer.java b/src/main/java/org/distorted/magic/RubikRenderer.java
index 79bbb6a3..5ead8672 100644
--- a/src/main/java/org/distorted/magic/RubikRenderer.java
+++ b/src/main/java/org/distorted/magic/RubikRenderer.java
@@ -22,8 +22,6 @@ package org.distorted.magic;
 import android.opengl.GLSurfaceView;
 
 import org.distorted.effect.SizeChangeEffect;
-import org.distorted.effect.SizeChangeEffectAppear;
-import org.distorted.effect.SizeChangeEffectDisappear;
 import org.distorted.effect.UnscrambleEffect;
 import org.distorted.library.effect.VertexEffectSink;
 import org.distorted.library.main.DistortedEffects;
@@ -51,7 +49,7 @@ public class RubikRenderer implements GLSurfaceView.Renderer, EffectListener
     private Static4D mTempCurrent, mTempAccumulated;
     private float mCubeSizeInScreenSpace;
     private int mNextCubeSize;
-    private long mRotationFinishedID, mDisappearEffectID, mAppearEffectID, mUnscrambleEffectID;
+    private long mRotationFinishedID, mSizeChangeEffectID, mUnscrambleEffectID;
     private boolean mFinishRotation, mRemoveRotation, mFinishDragCurrent, mFinishDragAccumulated, mSolveCube;
     private boolean mCanRotate, mCanDrag;
     private RubikCube mOldCube, mNewCube;
@@ -140,8 +138,7 @@ public class RubikRenderer implements GLSurfaceView.Renderer, EffectListener
         mCanRotate = false;
         mNextCubeSize = 0;
 
-        if( mOldCube!=null ) disappearCube();
-        else                    appearCube();
+        sizeChangeEffect();
         }
 
       if( mSolveCube )
@@ -200,11 +197,7 @@ public class RubikRenderer implements GLSurfaceView.Renderer, EffectListener
        {
        mRemoveRotation = true;
        }
-     else if( effectID == mDisappearEffectID )
-       {
-       appearCube();
-       }
-     else if( effectID == mAppearEffectID    )
+     else if( effectID == mSizeChangeEffectID    )
        {
        mCanRotate = true;
        mCanDrag   = true;
@@ -218,35 +211,21 @@ public class RubikRenderer implements GLSurfaceView.Renderer, EffectListener
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-   private void disappearCube()
-     {
-     try
-       {
-       SizeChangeEffectDisappear effect = SizeChangeEffectDisappear.create(mSizeChangeType);
-       mDisappearEffectID = effect.start(mSizeChangeDuration,mScreen,mOldCube,this);
-       }
-     catch(Exception ex)
-       {
-       android.util.Log.e("Renderer", "failed to create SizeChangeEffectDisappear, exception: "+ex.getMessage());
-       }
-     }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-   private void appearCube()
+   private void sizeChangeEffect()
      {
      try
        {
-       SizeChangeEffectAppear effect = SizeChangeEffectAppear.create(mSizeChangeType);
-       mAppearEffectID = effect.start(mSizeChangeDuration,mScreen,mNewCube,this);
+       SizeChangeEffect effect = SizeChangeEffect.create(mSizeChangeType);
+       mSizeChangeEffectID = effect.start(mSizeChangeDuration,mScreen,mOldCube,mNewCube,this);
        }
      catch(Exception ex)
        {
-       android.util.Log.e("Renderer", "failed to create SizeChangeEffectAppear, exception: "+ex.getMessage());
+       android.util.Log.e("Renderer", "failed to create SizeChangeEffect, exception: "+ex.getMessage());
 
-       mScreen.attach(mNewCube); //
-       mCanRotate = true;        // just appear the cube
-       mCanDrag   = true;        //
+       if( mOldCube!=null ) mScreen.detach(mOldCube);
+       mScreen.attach(mNewCube);
+       mCanRotate = true;
+       mCanDrag   = true;
        }
      }
 
@@ -282,7 +261,7 @@ public class RubikRenderer implements GLSurfaceView.Renderer, EffectListener
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-   void setSizeChangeType(SizeChangeEffectAppear.Type type)
+   void setSizeChangeType(SizeChangeEffect.Type type)
      {
      mSizeChangeType = type;
      }
