@@ -98,7 +98,16 @@ public boolean onTouch(View v, MotionEvent event) {
9898 } else if (event .getActionMasked () == MotionEvent .ACTION_UP ) {
9999 // reload the motion descriptors in case of position change.
100100 currentMotionDescriptors = getTilesBetweenEmptyTileAndTile (movedTile );
101- animateCurrentMovedTilesToEmptySpace ();
101+ // if last move was a dragging move and the move was over half way to the empty tile
102+ if (lastDragPoint != null && lastDragMovedAtLeastHalfWay ()) {
103+ animateCurrentMovedTilesToEmptySpace ();
104+ // otherwise, if it wasn't a drag, do the move
105+ } else if (lastDragPoint == null ) {
106+ animateCurrentMovedTilesToEmptySpace ();
107+ // Animate tiles back to origin
108+ } else {
109+ animateMovedTilesBackToOrigin ();
110+ }
102111 currentMotionDescriptors = null ;
103112 lastDragPoint = null ;
104113 movedTile = null ;
@@ -110,6 +119,16 @@ public boolean onTouch(View v, MotionEvent event) {
110119 }
111120 }
112121
122+ protected boolean lastDragMovedAtLeastHalfWay () {
123+ if (currentMotionDescriptors != null && currentMotionDescriptors .size () > 0 ) {
124+ GameTileMotionDescriptor firstMotionDescriptor = currentMotionDescriptors .get (0 );
125+ if (firstMotionDescriptor .axialDelta > tileSize .width /2 ) {
126+ return true ;
127+ }
128+ }
129+ return false ;
130+ }
131+
113132 protected void moveDraggedTilesByMotionEventDelta (MotionEvent event ) {
114133 boolean impossibleMove ;
115134 float dxTile , dyTile ;
@@ -145,8 +164,6 @@ protected boolean pointCollidesWithAnyNonMovedTile(PointF point) {
145164 return false ;
146165 }
147166
148-
149-
150167 protected boolean currentMovedTilesContainTile (GameTile otherTile ) {
151168 for (GameTileMotionDescriptor motionDescriptor : currentMotionDescriptors ) {
152169 if (otherTile == motionDescriptor .tile ) {
@@ -186,28 +203,58 @@ public void onAnimationEnd(Animator animation) {
186203 animator .start ();
187204 }
188205 }
206+
207+ protected void animateMovedTilesBackToOrigin () {
208+ ObjectAnimator animator ;
209+ if (currentMotionDescriptors != null ) {
210+ for (final GameTileMotionDescriptor motionDescriptor : currentMotionDescriptors ) {
211+ Ln .d ("Moving %s back" , motionDescriptor .tile );
212+ animator = ObjectAnimator .ofObject (
213+ motionDescriptor .tile ,
214+ motionDescriptor .property ,
215+ new FloatEvaluator (),
216+ motionDescriptor .currentPosition (),
217+ motionDescriptor .originalPosition ());
218+ animator .setDuration (16 );
219+ animator .addListener (new AnimatorListener () {
220+
221+ public void onAnimationStart (Animator animation ) { }
222+ public void onAnimationCancel (Animator animation ) { }
223+ public void onAnimationRepeat (Animator animation ) { }
224+ public void onAnimationEnd (Animator animation ) {
225+ Ln .d ("Animation complete: %s" , motionDescriptor );
226+ }
227+ });
228+ animator .start ();
229+ }
230+ }
231+ }
189232
190233 private ArrayList <GameTileMotionDescriptor > getTilesBetweenEmptyTileAndTile (GameTile tile ) {
191234 ArrayList <GameTileMotionDescriptor > descriptors = new ArrayList <GameTileMotionDescriptor >();
192235 Coordinate coordinate , finalCoordinate ;
193236 GameTile foundTile ;
194237 GameTileMotionDescriptor motionDescriptor ;
195- Rect rect ;
238+ Rect finalRect , currentRect ;
239+ float axialDelta ;
196240 if (tile .isToRightOf (emptyTile )) {
197241 Ln .d ("To right of empty tile" );
198242 for (int i = tile .coordinate .column ; i > emptyTile .coordinate .column ; i --) {
199243 coordinate = new Coordinate (tile .coordinate .row , i );
200244 foundTile = (tile .coordinate .matches (coordinate )) ? tile : getTileAtCoordinate (coordinate ) ;
201245 finalCoordinate = new Coordinate (tile .coordinate .row , i -1 );
202- rect = rectForCoordinate (finalCoordinate );
246+ currentRect = rectForCoordinate (foundTile .coordinate );
247+ finalRect = rectForCoordinate (finalCoordinate );
248+ axialDelta = Math .abs (foundTile .getX () - currentRect .left );
203249 motionDescriptor = new GameTileMotionDescriptor (
204250 foundTile ,
205251 "x" ,
206252 foundTile .getX (),
207- rect .left
253+ finalRect .left
208254 );
209255 motionDescriptor .finalCoordinate = finalCoordinate ;
210- motionDescriptor .finalRect = rect ;
256+ motionDescriptor .finalRect = finalRect ;
257+ motionDescriptor .axialDelta = axialDelta ;
211258 descriptors .add (motionDescriptor );
212259 }
213260 } else if (tile .isToLeftOf (emptyTile )) {
@@ -216,15 +263,18 @@ private ArrayList<GameTileMotionDescriptor> getTilesBetweenEmptyTileAndTile(Game
216263 coordinate = new Coordinate (tile .coordinate .row , i );
217264 foundTile = (tile .coordinate .matches (coordinate )) ? tile : getTileAtCoordinate (coordinate ) ;
218265 finalCoordinate = new Coordinate (tile .coordinate .row , i +1 );
219- rect = rectForCoordinate (finalCoordinate );
266+ currentRect = rectForCoordinate (foundTile .coordinate );
267+ finalRect = rectForCoordinate (finalCoordinate );
268+ axialDelta = Math .abs (foundTile .getX () - currentRect .left );
220269 motionDescriptor = new GameTileMotionDescriptor (
221270 foundTile ,
222271 "x" ,
223272 foundTile .getX (),
224- rect .left
273+ finalRect .left
225274 );
226275 motionDescriptor .finalCoordinate = finalCoordinate ;
227- motionDescriptor .finalRect = rect ;
276+ motionDescriptor .finalRect = finalRect ;
277+ motionDescriptor .axialDelta = axialDelta ;
228278 descriptors .add (motionDescriptor );
229279 }
230280 } else if (tile .isAbove (emptyTile )) {
@@ -233,15 +283,18 @@ private ArrayList<GameTileMotionDescriptor> getTilesBetweenEmptyTileAndTile(Game
233283 coordinate = new Coordinate (i , tile .coordinate .column );
234284 foundTile = (tile .coordinate .matches (coordinate )) ? tile : getTileAtCoordinate (coordinate ) ;
235285 finalCoordinate = new Coordinate (i +1 , tile .coordinate .column );
236- rect = rectForCoordinate (finalCoordinate );
286+ currentRect = rectForCoordinate (foundTile .coordinate );
287+ finalRect = rectForCoordinate (finalCoordinate );
288+ axialDelta = Math .abs (foundTile .getY () - currentRect .top );
237289 motionDescriptor = new GameTileMotionDescriptor (
238290 foundTile ,
239291 "y" ,
240292 foundTile .getY (),
241- rect .top
293+ finalRect .top
242294 );
243295 motionDescriptor .finalCoordinate = finalCoordinate ;
244- motionDescriptor .finalRect = rect ;
296+ motionDescriptor .finalRect = finalRect ;
297+ motionDescriptor .axialDelta = axialDelta ;
245298 descriptors .add (motionDescriptor );
246299 }
247300 } else if (tile .isBelow (emptyTile )) {
@@ -250,15 +303,18 @@ private ArrayList<GameTileMotionDescriptor> getTilesBetweenEmptyTileAndTile(Game
250303 coordinate = new Coordinate (i , tile .coordinate .column );
251304 foundTile = (tile .coordinate .matches (coordinate )) ? tile : getTileAtCoordinate (coordinate ) ;
252305 finalCoordinate = new Coordinate (i -1 , tile .coordinate .column );
253- rect = rectForCoordinate (finalCoordinate );
306+ currentRect = rectForCoordinate (foundTile .coordinate );
307+ finalRect = rectForCoordinate (finalCoordinate );
308+ axialDelta = Math .abs (foundTile .getY () - currentRect .top );
254309 motionDescriptor = new GameTileMotionDescriptor (
255310 foundTile ,
256311 "y" ,
257312 foundTile .getY (),
258- rect .top
313+ finalRect .top
259314 );
260315 motionDescriptor .finalCoordinate = finalCoordinate ;
261- motionDescriptor .finalRect = rect ;
316+ motionDescriptor .finalRect = finalRect ;
317+ motionDescriptor .axialDelta = axialDelta ;
262318 descriptors .add (motionDescriptor );
263319 }
264320 }
@@ -363,7 +419,7 @@ public class GameTileMotionDescriptor {
363419 public Rect finalRect ;
364420 public String property ;
365421 public GameTile tile ;
366- public float from , to ;
422+ public float from , to , axialDelta ;
367423 public Coordinate finalCoordinate ;
368424
369425 public GameTileMotionDescriptor (GameTile tile , String property , float from , float to ) {
@@ -374,6 +430,25 @@ public GameTileMotionDescriptor(GameTile tile, String property, float from, floa
374430 this .property = property ;
375431 }
376432
433+ public float currentPosition () {
434+ if (property .equals ("x" )) {
435+ return tile .getX ();
436+ } else if (property .equals ("y" )) {
437+ return tile .getY ();
438+ }
439+ return 0 ;
440+ }
441+
442+ public float originalPosition () {
443+ Rect originalRect = rectForCoordinate (tile .coordinate );
444+ if (property .equals ("x" )) {
445+ return originalRect .left ;
446+ } else if (property .equals ("y" )) {
447+ return originalRect .top ;
448+ }
449+ return 0 ;
450+ }
451+
377452 @ Override
378453 public String toString () {
379454 return "GameTileMotionDescriptor [property=" + property + ", tile="
0 commit comments