-1

I am working on a 2048 game and hit a problem with saving and loading tiles position. Everyone knows how the game field looks, there are rows and columns. So, every tile has row index (indRow) and column index (indCol), which set the tile position on the game field. How can I save this indexes in the game to load it in the next start?
My GameManager Script =

using System.Collections
using System.Collections.Generic
using UnityEngine
using UnityEngine.UI
using UnityEngine.SceneManagement

public enum GameState
{
    Playing,
    GameOver,
    WaitingForMoveToEnd
}

public class GameManager : MonoBehaviour {

    //DELAYS
    public GameState State;
    [Range(0, 2f)]
    public float delay;
    private bool moveMade;
    private bool[] lineMoveComplete = new bool[4]{ true, true, true, true };

    public Text GameOverText;
    public Text GameOverScoreText;
    public GameObject GameOverPanel;

    private Tile[,] AllTiles = new Tile[4, 4];
    private List<Tile[]> columns = new List<Tile[]>();
    private List<Tile[]> rows = new List<Tile[]>();
    private List<Tile> EmptyTiles = new List<Tile>();

    // Use this for initialization
    void Start()
    {
            Tile[] AllTilesOneDim = GameObject.FindObjectsOfType<Tile>();
        foreach (Tile t in AllTilesOneDim)
        {
            t.Number = 0;
            AllTiles[t.indRow, t.indCol] = t;
            EmptyTiles.Add(t);

        }

        columns.Add (new Tile[] { AllTiles[0, 0], AllTiles[1, 0], AllTiles[2, 0], AllTiles[3, 0] });
        columns.Add (new Tile[] { AllTiles[0, 1], AllTiles[1, 1], AllTiles[2, 1], AllTiles[3, 1] });
        columns.Add (new Tile[] { AllTiles[0, 2], AllTiles[1, 2], AllTiles[2, 2], AllTiles[3, 2] });
        columns.Add (new Tile[] { AllTiles[0, 3], AllTiles[1, 3], AllTiles[2, 3], AllTiles[3, 3] });


        rows.Add (new Tile[] { AllTiles[0, 0], AllTiles[0, 1], AllTiles[0, 2], AllTiles[0, 3] });
        rows.Add (new Tile[] { AllTiles[1, 0], AllTiles[1, 1], AllTiles[1, 2], AllTiles[1, 3] });
        rows.Add (new Tile[] { AllTiles[2, 0], AllTiles[2, 1], AllTiles[2, 2], AllTiles[2, 3] });
        rows.Add (new Tile[] { AllTiles[3, 0], AllTiles[3, 1], AllTiles[3, 2], AllTiles[3, 3] });

        State = GameState.Playing;



            Generate();
        Generate();

    }

    private void GameOver()
    {
        State = GameState.GameOver;
        GameOverScoreText.text = ScoreTracker.Instance.Score.ToString();
        GameOverPanel.SetActive(true);
    }

    bool CanMove ()
    {
        if (EmptyTiles.Count > 0)
            return true;
        else
        {//check columns
            for (int i = 0; i < columns.Count; i++)
                for (int j = 0; j < rows.Count - 1; j++)
                    if (AllTiles[j, i].Number == AllTiles[j + 1, i].Number)

            return true;

            //check rows
            for (int i = 0; i < rows.Count; i++)
                for (int j = 0; j < rows.Count - 1; j++)
                    if (AllTiles[i, j].Number == AllTiles[i, j + 1].Number)

            return true;
        }
        return false;
    }

    public void NewGameButtonHandler()
    {
        Application.LoadLevel(Application.loadedLevel);
    }

    bool MakeOneMoveLeftIndex(Tile[] LineOfTiles)
    {
        for (int i = 0; i < LineOfTiles.Length - 1; i++)
        {
            //MOVE BLOCK
            if (LineOfTiles[i].Number == 0 && LineOfTiles[i + 1].Number != 0)
            {
                LineOfTiles[i].Number = LineOfTiles[i + 1].Number;
                LineOfTiles[i + 1].Number = 0;
                return true;
            }
            // MERGE BLOCK
            if (LineOfTiles[i].Number != 0 && LineOfTiles[i].Number == LineOfTiles[i + 1].Number &&
                LineOfTiles[i].mergedThisTurn == false && LineOfTiles[i + 1].mergedThisTurn == false)
            {
                LineOfTiles[i].Number *= 2;
                LineOfTiles[i + 1].Number = 0;
                LineOfTiles[i].mergedThisTurn = true;
                LineOfTiles[i].PlayMergeLeftAnimation();
                ScoreTracker.Instance.Score += LineOfTiles[i].Number;
                return true;
            }

        }
        return false;
    }

    bool MakeOneMoveDownIndex(Tile[] LineOfTiles)
    {
        for (int i = 0; i< LineOfTiles.Length-1; i++)
        {
            //MOVE BLOCK
            if (LineOfTiles[i].Number == 0 && LineOfTiles[i + 1].Number != 0)
            {
                LineOfTiles[i].Number = LineOfTiles[i + 1].Number;
                LineOfTiles[i + 1].Number = 0;
                return true;
            }
            // MERGE BLOCK
            if (LineOfTiles[i].Number!= 0 && LineOfTiles[i].Number == LineOfTiles[i+1].Number && 
                LineOfTiles[i].mergedThisTurn == false && LineOfTiles[i+1].mergedThisTurn ==false)
            {
                LineOfTiles[i].Number *= 2;
                LineOfTiles[i + 1].Number = 0;
                LineOfTiles[i].mergedThisTurn = true;
                LineOfTiles[i].PlayMergeDownAnimation();
                ScoreTracker.Instance.Score += LineOfTiles[i].Number;
                return true;
            }

        }
        return false;
    }

    bool MakeOneMoveRightIndex(Tile[] LineOfTiles)
    {
        for (int i = LineOfTiles.Length - 1; i > 0; i--)
        {
            //MOVE BLOCK
            if (LineOfTiles[i].Number == 0 && LineOfTiles[i - 1].Number != 0)
            {
                LineOfTiles[i].Number = LineOfTiles[i - 1].Number;
                LineOfTiles[i - 1].Number = 0;
                return true;
            }
            // MERGE BLOCK
            if (LineOfTiles[i].Number != 0 && LineOfTiles[i].Number == LineOfTiles[i - 1].Number &&
                LineOfTiles[i].mergedThisTurn == false && LineOfTiles[i - 1].mergedThisTurn == false)
            {
                LineOfTiles[i].Number *= 2;
                LineOfTiles[i - 1].Number = 0;
                LineOfTiles[i].mergedThisTurn = true;
                LineOfTiles[i].PlayMergeRightAnimation();
                ScoreTracker.Instance.Score += LineOfTiles[i].Number;
                return true;
            }

        }
        return false;
    }

    bool MakeOneMoveUpIndex(Tile[] LineOfTiles)
    {
        for (int i = LineOfTiles.Length-1; i > 0; i--)
        {
            //MOVE BLOCK
            if (LineOfTiles[i].Number == 0 && LineOfTiles[i-1].Number !=0)
            {
                LineOfTiles[i].Number = LineOfTiles[i - 1].Number;
                LineOfTiles[i - 1].Number = 0;
                return true;
            }
            // MERGE BLOCK
            if (LineOfTiles[i].Number != 0 && LineOfTiles[i].Number == LineOfTiles[i - 1].Number &&
                LineOfTiles[i].mergedThisTurn == false && LineOfTiles[i - 1].mergedThisTurn == false)
            {
                LineOfTiles[i].Number *= 2;
                LineOfTiles[i - 1].Number = 0;
                LineOfTiles[i].mergedThisTurn = true;
                LineOfTiles[i].PlayMergeUpAnimation();
                ScoreTracker.Instance.Score += LineOfTiles[i].Number;
                return true;
            }

        }
        return false;     
    }

    void Generate()
    {
        if (EmptyTiles.Count > 0)
        {
            int indexForNewNumber = Random.Range(0, EmptyTiles.Count);
            int randomNum = Random.Range(0, 10);
            if (randomNum == 0)
                EmptyTiles[indexForNewNumber].Number = 2;
            else
                EmptyTiles[indexForNewNumber].Number = 4;

            EmptyTiles[indexForNewNumber].PlayAppearAnimation();

                EmptyTiles.RemoveAt(indexForNewNumber);
        }
    }


    private void ResetMergedFlags()
    {
        foreach (Tile t in AllTiles)
            t.mergedThisTurn = false;
    }

    private void UpdateEmptyTiles()
    {
        EmptyTiles.Clear();
        foreach (Tile t in AllTiles)
        {
            if (t.Number == 0)
                EmptyTiles.Add(t);
        }
    }

    public void Move (MoveDirection md)
    {
        Debug.Log(md.ToString() + " move.");
        moveMade = false;
        ResetMergedFlags ();
        if (delay > 0)
            StartCoroutine(MoveCoroutine(md));
        else
        {
            for (int i = 0; i < rows.Count; i++)
            {
                switch (md)
                {
                    case MoveDirection.Down:
                        while (MakeOneMoveUpIndex(columns[i]))
                        {

                            moveMade = true;
                        }
                        break;
                    case MoveDirection.Left:
                        while (MakeOneMoveLeftIndex(rows[i]))
                        {
                            moveMade = true;
                        }
                        break;
                    case MoveDirection.Right:
                        while (MakeOneMoveRightIndex(rows[i]))
                        {
                            moveMade = true;
                        }
                        break;
                    case MoveDirection.Up:
                        while (MakeOneMoveDownIndex(columns[i]))
                        {
                            moveMade = true;
                        }
                        break;
                }
            }
            if (moveMade)
            {
                UpdateEmptyTiles();
                Generate();

                if (!CanMove())
                {
                    GameOver();
                }
            }

        }

    }

    IEnumerator MoveOneLineRightIndexCoroutine(Tile[] line, int index)
    {
        lineMoveComplete[index] = false;
        while (MakeOneMoveRightIndex(line))
        {
            moveMade = true;
            yield return new WaitForSeconds(delay);
        }
        lineMoveComplete[index] = true;
    }

    IEnumerator MoveOneLineUpIndexCoroutine(Tile[] line, int index)
    {
        lineMoveComplete[index] = false;
        while (MakeOneMoveUpIndex(line))
        {
            moveMade = true;
            yield return new WaitForSeconds(delay);
        }
        lineMoveComplete[index] = true;
    }

    IEnumerator MoveOneLineDownIndexCoroutine(Tile[] line, int index)
    {
        lineMoveComplete[index] = false;
        while (MakeOneMoveDownIndex(line))
        {
            moveMade = true;
            yield return new WaitForSeconds(delay);
        }
        lineMoveComplete[index] = true;
    }
        IEnumerator MoveOneLineLeftIndexCoroutine(Tile[] line, int index)
    {
        lineMoveComplete[index] = false;
        while (MakeOneMoveLeftIndex(line))
        {
            moveMade = true;
            yield return new WaitForSeconds(delay);
        }
        lineMoveComplete[index] = true;
    }

    IEnumerator MoveCoroutine(MoveDirection md)
    {
        State = GameState.WaitingForMoveToEnd;

        // start moving each line with delays depending on MoveDirection md
        switch (md)
        {
            case MoveDirection.Down:
                for (int i = 0; i < columns.Count; i++)
                    StartCoroutine(MoveOneLineUpIndexCoroutine(columns[i], i));
                break;
            case MoveDirection.Left:
                for (int i = 0; i < rows.Count; i++)
                    StartCoroutine(MoveOneLineLeftIndexCoroutine(rows[i], i));
                break;
            case MoveDirection.Right:
                for (int i = 0; i < rows.Count; i++)
                    StartCoroutine(MoveOneLineRightIndexCoroutine(rows[i], i));
                break;
            case MoveDirection.Up:
                for (int i = 0; i < columns.Count; i++)
                    StartCoroutine(MoveOneLineDownIndexCoroutine(columns[i], i));
                break;
        }
        // Wait until the move is over in all lines
        while (!(lineMoveComplete[0] && lineMoveComplete[1] && lineMoveComplete[2] && lineMoveComplete[3]))
            yield return null;

        if (moveMade)
        {
            UpdateEmptyTiles ();
            Generate();



            if (!CanMove())
            {
                GameOver();
            }


        }
        State = GameState.Playing;
            StopAllCoroutines();
    }
    public void ShowLeaderboards()
    {
        PlayGamesScript.ShowLeaderboardsUI();
    }
}
Wai Ha Lee
  • 8,598
  • 83
  • 57
  • 92

1 Answers1

0

.NET Framework contains a few useful classes for Serialization.

A few common classes are XMLSerializer, DataContractJsonSerializer and BinaryFormatter.

An example with XMLSerializer could look like this:

using System.IO;
using System.Xml.Serialization;

namespace Serialization
{
    class Program
    {
        static string file = @"C:\employees.xml"; // Path to our XML file. Could be anything else.
        static void Main(string[] args)
        {
            Person[] people;
            XmlSerializer xmlser = new XmlSerializer(typeof(Person[])); // Our XML serializer!
            if (File.Exists(file)) // If the file exists read it
            {
                using (Stream s = File.OpenRead(file)) // We need a stream for our serializer
                {
                    people = (Person[])xmlser.Deserialize(s); // Don't forget to cast the result.
                }
            }
            else // If the file doesn't exist we generate new data
            {
                people = new Person[] { new Person("John", "Doe"), new Person("Joe", "Swanson") };

                using (Stream s = File.OpenWrite(file)) // And then we save our new data.
                {
                    xmlser.Serialize(s, people);
                }
            }
        }

        // And now that we have something in people you can use it as you wish to.
    }

    public class Person // Our data class. Has to be public.
    {
        public Person() { } // Parameterless constructor used by XmlSerializer. IMPORTANT!!!
        public Person(string firstName, string surName)
        {
            FirstName = firstName;
            SurName = surName;
        }

        public string FirstName { get; set; }
        public string SurName { get; set; }
    }
}

user78403
  • 352
  • 2
  • 11