Project

General

Profile

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

magiccube / src / main / java / org / distorted / effects / scramble / ScrambleEffect.java @ 771f6dfa

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