Как сохранить и загрузить прогресс в моей игре? - PullRequest
0 голосов
/ 02 февраля 2019

Я работаю над игрой 2048 и столкнулся с проблемой сохранения и загрузки позиции тайлов.Все знают, как выглядит игровое поле, есть строки и столбцы.Таким образом, каждая плитка имеет индекс строки (indRow) и индекс столбца (indCol), которые задают положение плитки на игровом поле.Как я могу сохранить эти индексы в игре, чтобы загрузить их при следующем запуске?
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();
    }
}

1 Ответ

0 голосов
/ 02 февраля 2019

.NET Framework содержит несколько полезных классов для Сериализация .

Несколько общих классов: XMLSerializer , DataContractJsonSerializer и BinaryFormatter .

Пример с XMLSerializer может выглядеть следующим образом:

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; }
    }
}

...