Revision 0e5ad27c
Added by Leszek Koltunski over 5 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.