Project

General

Profile

Download (9.93 KB) Statistics
| Branch: | Tag: | Revision:

magiccube / src / main / java / org / distorted / effects / scramble / ScrambleEffect.java @ 1dd8d3af

1 3b12e641 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2019 Leszek Koltunski                                                               //
3
//                                                                                               //
4 fdec60a3 Leszek Koltunski
// This file is part of Magic Cube.                                                              //
5 3b12e641 Leszek Koltunski
//                                                                                               //
6 fdec60a3 Leszek Koltunski
// Magic Cube is free software: you can redistribute it and/or modify                            //
7 3b12e641 Leszek Koltunski
// it under the terms of the GNU General Public License as published by                          //
8
// the Free Software Foundation, either version 2 of the License, or                             //
9
// (at your option) any later version.                                                           //
10
//                                                                                               //
11 fdec60a3 Leszek Koltunski
// Magic Cube is distributed in the hope that it will be useful,                                 //
12 3b12e641 Leszek Koltunski
// but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
13
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
14
// GNU General Public License for more details.                                                  //
15
//                                                                                               //
16
// You should have received a copy of the GNU General Public License                             //
17 fdec60a3 Leszek Koltunski
// along with Magic Cube.  If not, see <http://www.gnu.org/licenses/>.                           //
18 3b12e641 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
19
20 1f9772f3 Leszek Koltunski
package org.distorted.effects.scramble;
21 3b12e641 Leszek Koltunski
22 1f9772f3 Leszek Koltunski
import org.distorted.effects.BaseEffect;
23 55e6be1d Leszek Koltunski
import org.distorted.helpers.MovesFinished;
24 3b12e641 Leszek Koltunski
import org.distorted.library.effect.Effect;
25
import org.distorted.library.main.DistortedEffects;
26 8becce57 Leszek Koltunski
import org.distorted.library.main.DistortedScreen;
27 3b12e641 Leszek Koltunski
import org.distorted.library.message.EffectListener;
28 5a4d4fba Leszek Koltunski
import org.distorted.main.RubikPreRender;
29 af88bf2e Leszek Koltunski
import org.distorted.effects.EffectController;
30 5043d5d0 Leszek Koltunski
import org.distorted.objects.ObjectList;
31 9c2f0c91 Leszek Koltunski
import org.distorted.objects.TwistyObject;
32 3b12e641 Leszek Koltunski
33
import java.lang.reflect.Method;
34 e8764a49 Leszek Koltunski
import java.util.Random;
35 3b12e641 Leszek Koltunski
36
///////////////////////////////////////////////////////////////////////////////////////////////////
37
38 55e6be1d Leszek Koltunski
public abstract class ScrambleEffect extends BaseEffect implements EffectListener, MovesFinished
39 3b12e641 Leszek Koltunski
{
40
  public enum Type
41
    {
42
    NONE         (ScrambleEffectNone.class        ),
43 a62aa9d7 Leszek Koltunski
    ROTATIONS    (ScrambleEffectRotations.class   ),
44 3b12e641 Leszek Koltunski
    ;
45
46
    final Class<? extends ScrambleEffect> effect;
47
48
    Type(Class<? extends ScrambleEffect> effect)
49
      {
50
      this.effect= effect;
51
      }
52
    }
53
54 bbc6471c Leszek Koltunski
  private static final int NUM_EFFECTS = Type.values().length;
55 3b12e641 Leszek Koltunski
  private static final int FAKE_EFFECT_ID  = -3;
56
  private static final Type[] types;
57
58
  static
59
    {
60
    int i=0;
61
    types = new Type[NUM_EFFECTS];
62
63
    for(Type type: Type.values())
64
      {
65
      types[i++] = type;
66
      }
67
    }
68
69 af88bf2e Leszek Koltunski
  private EffectController mController;
70 e8764a49 Leszek Koltunski
  private int mEffectReturned;
71 542ec777 Leszek Koltunski
  private int mNumScramblesLeft;
72
  private long mDurationPerDegree;
73 bbc6471c Leszek Koltunski
  private final Random mRnd;
74 925ed78f Leszek Koltunski
  private int[] mBasicAngle;
75 20dea800 Leszek Koltunski
  private boolean mRotReady, mPluginReady;
76 3b12e641 Leszek Koltunski
77 9c2f0c91 Leszek Koltunski
  TwistyObject mObject;
78 e8764a49 Leszek Koltunski
  Effect[] mNodeEffects;
79
  int[] mNodeEffectPosition;
80
  Effect[] mCubeEffects;
81
  int[] mCubeEffectPosition;
82
  int mCubeEffectNumber, mNodeEffectNumber;
83 bbc6471c Leszek Koltunski
  int mNumScrambles;
84 5043d5d0 Leszek Koltunski
  int[][] mScrambles;
85 3b12e641 Leszek Koltunski
86
///////////////////////////////////////////////////////////////////////////////////////////////////
87
88
  ScrambleEffect()
89
    {
90 e8764a49 Leszek Koltunski
    mRnd = new Random( System.currentTimeMillis() );
91 0a7aa15b Leszek Koltunski
    mScrambles = new int[ObjectList.MAX_SCRAMBLE][3];
92 3b12e641 Leszek Koltunski
    }
93
94
///////////////////////////////////////////////////////////////////////////////////////////////////
95
96 e4db5995 Leszek Koltunski
  abstract void createEffects(int duration, int numScrambles);
97 a62aa9d7 Leszek Koltunski
  abstract void effectFinishedPlugin(final long effectID);
98 3b12e641 Leszek Koltunski
99
///////////////////////////////////////////////////////////////////////////////////////////////////
100 e8764a49 Leszek Koltunski
101 a62aa9d7 Leszek Koltunski
  private void createBaseEffects(int duration, int numScrambles)
102 3b12e641 Leszek Koltunski
    {
103 e8764a49 Leszek Koltunski
    mNumScramblesLeft = numScrambles;
104 542ec777 Leszek Koltunski
    int absAngle, angle, axis, basicDegrees, totalDegrees = 0;
105 e8764a49 Leszek Koltunski
106 5043d5d0 Leszek Koltunski
    for(int scramble=0; scramble<mNumScramblesLeft; scramble++)
107 e8764a49 Leszek Koltunski
      {
108 9f171eba Leszek Koltunski
      mObject.randomizeNewScramble(mScrambles, mRnd, scramble, numScrambles);
109 542ec777 Leszek Koltunski
      axis  = mScrambles[scramble][0];
110
      angle = mScrambles[scramble][2];
111
      absAngle = (angle<0 ? -angle : angle);
112
      basicDegrees = 360/mBasicAngle[axis];
113
      totalDegrees += absAngle*basicDegrees;
114 e8764a49 Leszek Koltunski
      }
115
116 542ec777 Leszek Koltunski
    mDurationPerDegree = duration/totalDegrees;
117 bbc6471c Leszek Koltunski
    mNumScrambles = 0;
118 e8764a49 Leszek Koltunski
119 20dea800 Leszek Koltunski
    mRotReady    = false;
120
    mPluginReady = false;
121
122 e8764a49 Leszek Koltunski
    addNewScramble();
123 a62aa9d7 Leszek Koltunski
    }
124 3b12e641 Leszek Koltunski
125 a62aa9d7 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
126 3b12e641 Leszek Koltunski
127 e8764a49 Leszek Koltunski
  private void addNewScramble()
128 a62aa9d7 Leszek Koltunski
    {
129 e8764a49 Leszek Koltunski
    if( mNumScramblesLeft>0 )
130
      {
131 5043d5d0 Leszek Koltunski
      int axis = mScrambles[mNumScrambles][0];
132
      int row  = mScrambles[mNumScrambles][1];
133
      int angle= mScrambles[mNumScrambles][2];
134 5cf34c5f Leszek Koltunski
135 542ec777 Leszek Koltunski
      int rowBitmap= (1<<row);
136 e8764a49 Leszek Koltunski
      int absAngle = (angle<0 ? -angle : angle);
137 542ec777 Leszek Koltunski
      int basicDegrees  = 360/mBasicAngle[axis];
138
      long durationMillis = absAngle*basicDegrees*mDurationPerDegree;
139 e8764a49 Leszek Koltunski
140
      mNumScramblesLeft--;
141 542ec777 Leszek Koltunski
      mController.addRotation(this, axis, rowBitmap, angle*basicDegrees, durationMillis);
142 5043d5d0 Leszek Koltunski
      mNumScrambles++;
143 e8764a49 Leszek Koltunski
      }
144
    else
145
      {
146 542ec777 Leszek Koltunski
      mRotReady = true;
147
      if( mPluginReady ) mController.effectFinished(FAKE_EFFECT_ID);
148 e8764a49 Leszek Koltunski
      }
149
    }
150
151 47ba5ddc Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
152
153
  private void assignEffects()
154
    {
155
    for(int i=0; i<mCubeEffectNumber; i++)
156
      {
157 27a70eae Leszek Koltunski
      mObject.apply(mCubeEffects[i],mCubeEffectPosition[i]);
158 47ba5ddc Leszek Koltunski
      mCubeEffects[i].notifyWhenFinished(this);
159
      }
160
161 27a70eae Leszek Koltunski
    DistortedEffects nodeEffects = mObject.getEffects();
162 47ba5ddc Leszek Koltunski
163
    for(int i=0; i<mNodeEffectNumber; i++)
164
      {
165
      nodeEffects.apply(mNodeEffects[i],mNodeEffectPosition[i]);
166
      mNodeEffects[i].notifyWhenFinished(this);
167
      }
168
    }
169
170
///////////////////////////////////////////////////////////////////////////////////////////////////
171
172
  private void disassignEffects()
173
    {
174
    for(int i=0; i<mCubeEffectNumber; i++)
175
      {
176 27a70eae Leszek Koltunski
      mObject.remove(mCubeEffects[i].getID());
177 47ba5ddc Leszek Koltunski
      }
178
179 27a70eae Leszek Koltunski
    DistortedEffects nodeEffects = mObject.getEffects();
180 47ba5ddc Leszek Koltunski
181
    for(int i=0; i<mNodeEffectNumber; i++)
182
      {
183
      nodeEffects.abortById(mNodeEffects[i].getID());
184
      }
185
    }
186
187
///////////////////////////////////////////////////////////////////////////////////////////////////
188
// PUBLIC API
189
///////////////////////////////////////////////////////////////////////////////////////////////////
190
191
  @SuppressWarnings("unused")
192
  public static String[] getNames()
193
    {
194
    String[] names = new String[NUM_EFFECTS];
195
196
    for( int i=0; i<NUM_EFFECTS; i++)
197
      {
198
      names[i] = types[i].name();
199
      }
200
201
    return names;
202
    }
203
204
///////////////////////////////////////////////////////////////////////////////////////////////////
205
206
  @SuppressWarnings("unused")
207
  public static ScrambleEffect create(int ordinal) throws InstantiationException, IllegalAccessException
208
    {
209
    return types[ordinal].effect.newInstance();
210
    }
211
212 3b12e641 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
213
214 8becce57 Leszek Koltunski
  public void onActionFinished(final long effectID)
215 3b12e641 Leszek Koltunski
    {
216 8becce57 Leszek Koltunski
    addNewScramble();
217
    }
218 e8764a49 Leszek Koltunski
219 20dea800 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
220
221
  private void effectFinishedAction(final long effectID, final long id)
222
    {
223
    mEffectReturned++;
224
    effectFinishedPlugin(effectID);
225
226
    if( mEffectReturned == mCubeEffectNumber+mNodeEffectNumber )
227
      {
228
      disassignEffects();
229
230 916f5dda Leszek Koltunski
      mPluginReady = true;
231
      if( mRotReady ) mController.effectFinished(FAKE_EFFECT_ID);
232 20dea800 Leszek Koltunski
      }
233
    }
234
235 8becce57 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
236
237
  public void effectFinished(final long effectID)
238
    {
239 e8764a49 Leszek Koltunski
    for(int i=0; i<mCubeEffectNumber; i++)
240 3b12e641 Leszek Koltunski
      {
241 e8764a49 Leszek Koltunski
      long id = mCubeEffects[i].getID();
242
243
      if( effectID == id )
244 a62aa9d7 Leszek Koltunski
        {
245 20dea800 Leszek Koltunski
        effectFinishedAction(effectID,id);
246 e8764a49 Leszek Koltunski
        return;
247
        }
248
      }
249 a62aa9d7 Leszek Koltunski
250 e8764a49 Leszek Koltunski
    for(int i=0; i<mNodeEffectNumber; i++)
251
      {
252
      long id = mNodeEffects[i].getID();
253 a62aa9d7 Leszek Koltunski
254 e8764a49 Leszek Koltunski
      if( effectID == id )
255 a62aa9d7 Leszek Koltunski
        {
256 20dea800 Leszek Koltunski
        effectFinishedAction(effectID,id);
257 e8764a49 Leszek Koltunski
        return;
258 a62aa9d7 Leszek Koltunski
        }
259 3b12e641 Leszek Koltunski
      }
260
    }
261
262
///////////////////////////////////////////////////////////////////////////////////////////////////
263
264 47ba5ddc Leszek Koltunski
  @SuppressWarnings("unused")
265 af88bf2e Leszek Koltunski
  public long start(int duration, DistortedScreen screen, EffectController cont)
266 3b12e641 Leszek Koltunski
    {
267 af88bf2e Leszek Koltunski
    mObject    = cont.getObject();
268
    mController= cont;
269 a62aa9d7 Leszek Koltunski
270 27a70eae Leszek Koltunski
    mObject.solve();
271 beb325a0 Leszek Koltunski
272 e844c116 Leszek Koltunski
    mBasicAngle = mObject.getBasicAngle();
273
274 af88bf2e Leszek Koltunski
    int numScrambles = cont.getNumScrambles();
275 3ca97293 Leszek Koltunski
    int dura = (int)(duration*Math.pow(numScrambles,0.66f));
276 e4db5995 Leszek Koltunski
    createBaseEffects(dura,numScrambles);
277
    createEffects    (dura,numScrambles);
278 a62aa9d7 Leszek Koltunski
279 e8764a49 Leszek Koltunski
    if( mCubeEffectNumber==0 && mNodeEffectNumber==0 )
280 a62aa9d7 Leszek Koltunski
      {
281
      throw new RuntimeException("Cube and Node Plugin Effects not created!");
282
      }
283
284 e8764a49 Leszek Koltunski
    assignEffects();
285 3b12e641 Leszek Koltunski
286
    return FAKE_EFFECT_ID;
287
    }
288
289
///////////////////////////////////////////////////////////////////////////////////////////////////
290
291
  @SuppressWarnings("unused")
292
  public static void enableEffects()
293
    {
294
    Method method;
295
296
    for(Type type: Type.values())
297
      {
298
      try
299
        {
300
        method = type.effect.getDeclaredMethod("enable"); // enable not public, thus getDeclaredMethod
301
        }
302
      catch(NoSuchMethodException ex)
303
        {
304
        android.util.Log.e("ScrambleEffect", type.effect.getSimpleName()+": exception getting method: "+ex.getMessage());
305
        method = null;
306
        }
307
308
      try
309
        {
310
        if( method!=null ) method.invoke(null);
311
        }
312
      catch(Exception ex)
313
        {
314
        android.util.Log.e("ScrambleEffect", type.effect.getSimpleName()+": exception invoking method: "+ex.getMessage());
315
        }
316
      }
317
    }
318
}