Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

How to fix my tile-based game's tile movement code ? (like a CandyCrush Style)

Discussion in 'Scripting' started by D3ntrax, Mar 8, 2016.

  1. D3ntrax

    D3ntrax

    Joined:
    Mar 21, 2014
    Posts:
    35
    'm currently creating a tile-based game like a CandyCrush style direction movement (no problem on only down movement) trying to smooth, not laggy tile movement with a board piece, and I'm writing a report about it now.

    However, I found it hard to properly describe it. I am having some weird issues with my tile movement code. I am trying to make it so it is a smoothly, in order, and tileses not sorted, buggy, bla bla. Need more optimization...

    -I removed DiagonallyMover on code, now It's simply. -But, Vector3 fallDestination is always get lastest null piece. Not sorted.
    -I added my movement codes here.
    -When moveDirection's x and y not 0, It's moving transversely.

    My code working like this ;



    What I wan't ;




    Can someone fix this code, please ?

    My Movement Code :

    Code (CSharp):
    1. public bool UpdateTilePhysics(DestructionBoardPiece curPiece) {
    2.     this.UpdateFallingTilePosition(curPiece);
    3.     bool hasTileReachedFallDestination = this.HasTileReachedFallDestination(ref this.fallDestination);
    4.     if (!hasTileReachedFallDestination) {
    5.         this.moveVelocity = Mathf.Min(this.moveVelocity + this.acceleration * Time.smoothDeltaTime, this.maxVelocity);
    6.     } else {
    7.         if (this.isSpawnedFromBehindMask) {
    8.             this.distanceSinceSpawned = Mathf.Max(1f, this.distanceSinceSpawned);
    9.             this.CheckDistanceSinceSpawnedTriggers();
    10.         }
    11.         base.LocalPosition = this.fallDestination;
    12.     }
    13.     return hasTileReachedFallDestination;
    14. }
    15.  
    16. protected void UpdateFallingTilePosition(DestructionBoardPiece curPiece) {
    17.     if (this.isSpawnedFromBehindMask) {
    18.         Vector3 a = this.fallDestination;
    19.         a.z = base.LocalPosition.z;
    20.         this.moveDirection = (a - base.LocalPosition).normalized;
    21.         base.LocalPosition += this.moveDirection * this.moveVelocity * Time.deltaTime;
    22.         this.distanceSinceSpawned += this.moveVelocity * Time.deltaTime;
    23.         this.CheckDistanceSinceSpawnedTriggers();
    24.         return;
    25.     }
    26.  
    27.     this.moveDirection = (this.fallDestination - base.LocalPosition).normalized;
    28.     base.LocalPosition += this.moveDirection * this.moveVelocity * Time.deltaTime;
    29. }


    My Gravity Checker Code (4-direction checker):

    Code (CSharp):
    1. protected IEnumerator ActiveGravityChecker() {
    2.     DestructionBoardPiece destructionBoardPiece = null;
    3.     DestructionBoardPiece destructionBoardPiece2 = null;
    4.     DestructionBoardPiece destructionBoardPiece3 = null;
    5.     while (this.GravityUpdateEnabled) {
    6.         if (!base.enabled || !this.GravityEnabled || base.BoardPiece == null) {
    7.             yield return null;
    8.         } else {
    9.             this.debugActiveGravity = true;
    10.             destructionBoardPiece = (base.BoardPiece as DestructionBoardPiece);
    11.             if (destructionBoardPiece3 == null) destructionBoardPiece3 = destructionBoardPiece;
    12.             this.fallDestination = destructionBoardPiece.LocalPosition;
    13.             bool canMoveDown = false;
    14.             if (destructionBoardPiece.LockCount <= 0 && destructionBoardPiece.BottomLink != null && !destructionBoardPiece.BottomLink.IsBlocked && ((this.tileMovedDiagonally && this.HasReachedBoardPieceArea()) || !this.tileMovedDiagonally)) {
    15.                 if (destructionBoardPiece.BottomLink.Tile == null) {
    16.                     destructionBoardPiece2 = destructionBoardPiece.BottomLink;
    17.                     canMoveDown = true;
    18.                     this.tileMovedDiagonally = false;
    19.                 } else if (destructionBoardPiece.BottomLink.Tile.IsMoving && this.HasTileInArea(destructionBoardPiece.BottomLink.Tile as DestructionTile)) {
    20.                     this.moveVelocity = (destructionBoardPiece.BottomLink.Tile as DestructionTile).moveVelocity;
    21.                 }
    22.             }
    23.             if (destructionBoardPiece.LockCount <= 0 && !canMoveDown && this.HasReachedBoardPieceArea()) {
    24.  
    25.               //Removed DiagonallyMover Code
    26.             }
    27.             if (canMoveDown) {
    28.                 this.fallDestination = destructionBoardPiece2.LocalPosition;
    29.                 if (destructionBoardPiece.Tile == this) {
    30.                     destructionBoardPiece.MoveTileTo(destructionBoardPiece2);
    31.                 }
    32.                 destructionBoardPiece.UpdateOrphanState();
    33.             }
    34.             if (!canMoveDown && this.UpdateTilePhysics(destructionBoardPiece) && (destructionBoardPiece2 == null || (destructionBoardPiece2.Tile != null && !destructionBoardPiece2.Tile.IsMoving) || destructionBoardPiece == destructionBoardPiece2 || destructionBoardPiece.LockCount > 0)) {
    35.                 destructionBoardPiece.Tile = this;
    36.                 destructionBoardPiece.ResetTilePosition();
    37.                 this.TileStoppedMoving(ref destructionBoardPiece3);
    38.                 base.IsMoving = false;
    39.                 this.RaiseEventTileFinishedActiveGravity(destructionBoardPiece3);
    40.                 this.moveVelocity = 0f;
    41.                 break;
    42.             }
    43.             yield return null;
    44.         }
    45.     }
    46.     this.debugActiveGravity = false;
    47.     yield break;
    48. }
     
  2. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,735
    So basically, you need them to round the corner correctly, yes?

    I think your best strategy would be to use a float value to represent each tile's position - how far along the path the tile is - and then translate that value into a position. Rather than moving from position X1, Y1 to position X2, Y2, you would move the distance-along-path variable from D1 to D2.

    The part that becomes hard work here becomes translating "D" to "X,Y" after the fact. However, you could make this easy using animations. If you make an AnimationClip that represents the path that a tile takes, making sure to time the animation so that it moves one tile-length per second, you can simply set the animation's time to D and be done with it!

    (This strategy would also make it really easy to create new levels, and you could even easily do wacky stuff like making the tiles rotate or resize at certain points, or have diagonal or curved paths.)
     
    D3ntrax likes this.
  3. D3ntrax

    D3ntrax

    Joined:
    Mar 21, 2014
    Posts:
    35
    @StarManta

    Thank you for answer.

    I am using json files for parse the levels to map. I think, animation clip system will be difficult and complex than my system. I already using unity's localPosition system, distance, collinear ... etc. for move the tile. The problem is fallDestination coordinate. It get lastes board piece if boardPiece.Tile == null.
     
  4. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,735
    You can use a similar technique without using the animation system, you'd just have to implement your own "convert-distance-to-position-along-path" algorithm - that's the key.
     
  5. D3ntrax

    D3ntrax

    Joined:
    Mar 21, 2014
    Posts:
    35
    I think, It's not distance problem.

    I put this code in "UpdateFallingTilePosition" void. It's return value = 0.

    Code (CSharp):
    1.  float debugDist = Vector3.Distance(curPiece.LocalPosition, this.fallDestination);
    2.  Debug.Log(debugDist);
    3.  //Debug : 0
    4.