Revision 0e5ad27c
Added by Leszek Koltunski over 4 years ago
src/main/java/org/distorted/main/RubikSurfaceView.java | ||
---|---|---|
74 | 74 |
private float mAxisX, mAxisY; |
75 | 75 |
private float mRotationFactor; |
76 | 76 |
private int mLastCubitColor, mLastCubitFace, mLastCubit; |
77 |
private int mCurrentAxis, mCurrentRow; |
|
78 |
private float mCurrentAngle; |
|
77 | 79 |
|
78 | 80 |
private static Static4D mQuatCurrent = new Static4D(0,0,0,1); |
79 | 81 |
private static Static4D mQuatAccumulated= new Static4D(-0.25189602f,0.3546389f,0.009657208f,0.90038127f); |
... | ... | |
363 | 365 |
Static2D res = mMovement.newRotation(rotatedTouchPoint2); |
364 | 366 |
RubikObject object = mPostRender.getObject(); |
365 | 367 |
|
366 |
int axis = (int)res.get0();
|
|
368 |
mCurrentAxis = (int)res.get0();
|
|
367 | 369 |
float offset = res.get1(); |
368 |
computeCurrentAxis( object.getRotationAxis()[axis] ); |
|
370 |
mCurrentRow = (int)(object.returnMultiplier()*offset); |
|
371 |
computeCurrentAxis( object.getRotationAxis()[mCurrentAxis] ); |
|
369 | 372 |
mRotationFactor = object.returnRotationFactor(offset); |
370 | 373 |
|
371 |
object.beginNewRotation( axis, (int)(object.returnMultiplier()*offset) );
|
|
374 |
object.beginNewRotation( mCurrentAxis, mCurrentRow );
|
|
372 | 375 |
|
373 | 376 |
if( RubikState.getCurrentState()==RubikState.SOLV ) |
374 | 377 |
{ |
... | ... | |
383 | 386 |
else if( mContinuingRotation ) |
384 | 387 |
{ |
385 | 388 |
float angle = continueRotation(x-mStartRotX,y-mStartRotY); |
386 |
mPostRender.getObject().continueRotation(SWIPING_SENSITIVITY*angle); |
|
389 |
mCurrentAngle = SWIPING_SENSITIVITY*angle; |
|
390 |
mPostRender.getObject().continueRotation(mCurrentAngle); |
|
387 | 391 |
} |
388 | 392 |
else if( mDragging ) |
389 | 393 |
{ |
... | ... | |
416 | 420 |
if( mContinuingRotation ) |
417 | 421 |
{ |
418 | 422 |
mPostRender.finishRotation(); |
423 |
|
|
424 |
if( RubikState.getCurrentState()==RubikState.SOLV ) |
|
425 |
{ |
|
426 |
RubikStateSolving solving = (RubikStateSolving)RubikState.SOLV.getStateClass(); |
|
427 |
|
|
428 |
int angle = mPostRender.getObject().computeNearestAngle(mCurrentAngle); |
|
429 |
|
|
430 |
if( angle!=0 ) |
|
431 |
solving.addMove(mCurrentAxis, mCurrentRow, angle); |
|
432 |
} |
|
419 | 433 |
} |
420 | 434 |
if( mLastCubitColor>=0 ) |
421 | 435 |
{ |
src/main/java/org/distorted/objects/Cubit.java | ||
---|---|---|
120 | 120 |
quat.set(x,y,z,w); |
121 | 121 |
} |
122 | 122 |
|
123 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
124 |
|
|
125 |
private int computeNearestAngle(float angle) |
|
126 |
{ |
|
127 |
final int NEAREST = 360/mParent.getBasicAngle(); |
|
128 |
|
|
129 |
int tmp = (int)((angle+NEAREST/2)/NEAREST); |
|
130 |
if( angle< -(NEAREST*0.5) ) tmp-=1; |
|
131 |
|
|
132 |
return NEAREST*tmp; |
|
133 |
} |
|
134 |
|
|
135 | 123 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
136 | 124 |
|
137 | 125 |
private void modifyCurrentPosition(Static4D quat) |
... | ... | |
317 | 305 |
if( pointNum>=1 ) |
318 | 306 |
{ |
319 | 307 |
float startingAngle = mRotationAngle.getPoint(pointNum-1).get0(); |
320 |
int nearestAngleInDegrees = computeNearestAngle(startingAngle); |
|
308 |
int nearestAngleInDegrees = mParent.computeNearestAngle(startingAngle);
|
|
321 | 309 |
mParent.mRotationAngleStatic.set0(startingAngle); |
322 | 310 |
mParent.mRotationAngleFinal.set0(nearestAngleInDegrees); |
323 | 311 |
mParent.mRotationAngleMiddle.set0( nearestAngleInDegrees + (nearestAngleInDegrees-startingAngle)*0.2f ); |
... | ... | |
340 | 328 |
float axisZ = mParent.ROTATION_AXIS[axis].get2(); |
341 | 329 |
|
342 | 330 |
float startingAngle = mRotationAngle.getPoint(pointNum-1).get0(); |
343 |
int nearestAngleInDegrees = computeNearestAngle(startingAngle); |
|
331 |
int nearestAngleInDegrees = mParent.computeNearestAngle(startingAngle);
|
|
344 | 332 |
double nearestAngleInRadians = nearestAngleInDegrees*Math.PI/180; |
345 | 333 |
float sinA =-(float)Math.sin(nearestAngleInRadians*0.5); |
346 | 334 |
float cosA = (float)Math.cos(nearestAngleInRadians*0.5); |
src/main/java/org/distorted/objects/RubikObject.java | ||
---|---|---|
567 | 567 |
return currentBest; |
568 | 568 |
} |
569 | 569 |
|
570 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
571 |
|
|
572 |
public int computeNearestAngle(float angle) |
|
573 |
{ |
|
574 |
final int NEAREST = 360/getBasicAngle(); |
|
575 |
|
|
576 |
int tmp = (int)((angle+NEAREST/2)/NEAREST); |
|
577 |
if( angle< -(NEAREST*0.5) ) tmp-=1; |
|
578 |
|
|
579 |
return NEAREST*tmp; |
|
580 |
} |
|
581 |
|
|
570 | 582 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
571 | 583 |
|
572 | 584 |
public RubikObjectList getObjectList() |
src/main/java/org/distorted/states/RubikStateSolving.java | ||
---|---|---|
24 | 24 |
import android.view.LayoutInflater; |
25 | 25 |
import android.view.View; |
26 | 26 |
import android.widget.Button; |
27 |
import android.widget.ImageButton; |
|
27 | 28 |
import android.widget.LinearLayout; |
28 | 29 |
import android.widget.TextView; |
29 | 30 |
|
30 | 31 |
import org.distorted.main.R; |
31 | 32 |
import org.distorted.main.RubikActivity; |
33 |
import org.distorted.main.RubikPostRender; |
|
34 |
import org.distorted.objects.RubikObject; |
|
32 | 35 |
import org.distorted.objects.RubikObjectList; |
33 | 36 |
import org.distorted.scores.RubikScores; |
34 | 37 |
|
38 |
import java.util.ArrayList; |
|
35 | 39 |
import java.util.Timer; |
36 | 40 |
import java.util.TimerTask; |
37 | 41 |
|
38 | 42 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
39 | 43 |
|
40 |
public class RubikStateSolving extends RubikStateAbstract |
|
44 |
public class RubikStateSolving extends RubikStateAbstract implements RubikPostRender.ActionFinishedListener
|
|
41 | 45 |
{ |
46 |
private static final int DURATION_MILLIS = 750; |
|
47 |
|
|
42 | 48 |
private TextView mTime; |
43 | 49 |
private Timer mTimer; |
44 | 50 |
private long mStartTime; |
45 | 51 |
private boolean mRunning; |
46 | 52 |
private RubikScores mScores; |
47 | 53 |
private Button mBack; |
54 |
private ImageButton mPrevButton; |
|
55 |
private boolean mCanPrevMove; |
|
56 |
private ArrayList<Move> mMoves; |
|
57 |
|
|
58 |
private static class Move |
|
59 |
{ |
|
60 |
private int mAxis, mRow, mAngle; |
|
61 |
|
|
62 |
Move(int axis, int row, int angle) |
|
63 |
{ |
|
64 |
mAxis = axis; |
|
65 |
mRow = row; |
|
66 |
mAngle= angle; |
|
67 |
} |
|
68 |
} |
|
48 | 69 |
|
49 | 70 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
50 | 71 |
|
... | ... | |
64 | 85 |
|
65 | 86 |
void enterState(final RubikActivity act) |
66 | 87 |
{ |
88 |
mCanPrevMove = true; |
|
89 |
|
|
90 |
if( mMoves==null ) mMoves = new ArrayList<>(); |
|
91 |
else mMoves.clear(); |
|
92 |
|
|
67 | 93 |
LayoutInflater inflater = act.getLayoutInflater(); |
94 |
DisplayMetrics metrics = act.getResources().getDisplayMetrics(); |
|
95 |
float scale = metrics.density; |
|
68 | 96 |
|
69 | 97 |
// TOP //////////////////////////// |
70 | 98 |
LinearLayout layoutTop = act.findViewById(R.id.upperBar); |
... | ... | |
76 | 104 |
// BOT //////////////////////////// |
77 | 105 |
LinearLayout layoutLeft = act.findViewById(R.id.mainBarLeft); |
78 | 106 |
layoutLeft.removeAllViews(); |
107 |
|
|
108 |
if( mPrevButton==null ) setupPrevMoveButtom(act,scale); |
|
109 |
layoutLeft.addView(mPrevButton); |
|
110 |
|
|
79 | 111 |
LinearLayout layoutRight = act.findViewById(R.id.mainBarRight); |
80 | 112 |
layoutRight.removeAllViews(); |
81 | 113 |
|
82 |
DisplayMetrics metrics = act.getResources().getDisplayMetrics(); |
|
83 |
float scale = metrics.density; |
|
84 | 114 |
int padding = (int)(5*scale + 0.5f); |
85 | 115 |
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.MATCH_PARENT); |
86 | 116 |
|
... | ... | |
101 | 131 |
layoutRight.addView(mBack); |
102 | 132 |
} |
103 | 133 |
|
134 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
135 |
|
|
136 |
private void setupPrevMoveButtom(final RubikActivity act, float scale) |
|
137 |
{ |
|
138 |
int padding = (int)( 3*scale + 0.5f); |
|
139 |
int width = (int)(60*scale + 0.5f); |
|
140 |
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(width,LinearLayout.LayoutParams.MATCH_PARENT); |
|
141 |
mPrevButton = new ImageButton(act); |
|
142 |
mPrevButton.setLayoutParams(params); |
|
143 |
mPrevButton.setPadding(padding,0,padding,0); |
|
144 |
mPrevButton.setImageResource(R.drawable.left); |
|
145 |
mPrevButton.setEnabled(false); |
|
146 |
|
|
147 |
mPrevButton.setOnClickListener( new View.OnClickListener() |
|
148 |
{ |
|
149 |
@Override |
|
150 |
public void onClick(View v) |
|
151 |
{ |
|
152 |
RubikPostRender post = act.getPostRender(); |
|
153 |
backMove(post); |
|
154 |
} |
|
155 |
}); |
|
156 |
} |
|
157 |
|
|
158 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
159 |
|
|
160 |
private void backMove(RubikPostRender post) |
|
161 |
{ |
|
162 |
if( mCanPrevMove ) |
|
163 |
{ |
|
164 |
int numMoves = mMoves.size(); |
|
165 |
|
|
166 |
if( numMoves>0 ) |
|
167 |
{ |
|
168 |
Move move = mMoves.remove(numMoves-1); |
|
169 |
RubikObject object = post.getObject(); |
|
170 |
|
|
171 |
int axis = move.mAxis; |
|
172 |
int row = (1<<move.mRow); |
|
173 |
int angle = move.mAngle; |
|
174 |
int numRot= Math.abs(angle*object.getBasicAngle()/360); |
|
175 |
|
|
176 |
if( angle!=0 ) |
|
177 |
{ |
|
178 |
mCanPrevMove = false; |
|
179 |
post.addRotation(this, axis, row, -angle, numRot*DURATION_MILLIS); |
|
180 |
|
|
181 |
if( numMoves==1 ) |
|
182 |
{ |
|
183 |
mPrevButton.setEnabled(false); |
|
184 |
} |
|
185 |
} |
|
186 |
else |
|
187 |
{ |
|
188 |
android.util.Log.e("solution", "error: trying to back move of angle 0"); |
|
189 |
} |
|
190 |
} |
|
191 |
else |
|
192 |
{ |
|
193 |
android.util.Log.e("solv", "error: no moves to back!"); |
|
194 |
} |
|
195 |
} |
|
196 |
} |
|
197 |
|
|
198 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
199 |
|
|
200 |
public void addMove(int axis, int row, int angle) |
|
201 |
{ |
|
202 |
mMoves.add(new Move(axis,row,angle)); |
|
203 |
|
|
204 |
if( mMoves.size()==1 ) |
|
205 |
{ |
|
206 |
mPrevButton.setEnabled(true); |
|
207 |
} |
|
208 |
} |
|
209 |
|
|
104 | 210 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
105 | 211 |
|
106 | 212 |
public void savePreferences(SharedPreferences.Editor editor) |
... | ... | |
182 | 288 |
|
183 | 289 |
return 0; |
184 | 290 |
} |
291 |
|
|
292 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
293 |
|
|
294 |
public void onActionFinished(final long effectID) |
|
295 |
{ |
|
296 |
mCanPrevMove = true; |
|
297 |
} |
|
185 | 298 |
} |
Also available in: Unified diff
Add a 'withdraw move' button to the Solving UI state.