読者です 読者をやめる 読者になる 読者になる

がりらぼ

WindowsRuntimeの応援ブログ

MonoGameWindowsRuntimeゲームプログラミング入門vol12:セーブデータを保存する

ゲームのセーブデータ

ゲームにおいて獲得したスコアや最高記録などはセーブデータとしてストレージに保存します。

そして次回以降の起動でセーブデータを復元します。

 

WindowsRuntimeにおけるデータ保存方法

WindowsRuntimeでは設定データとファイルデータの2つのデータ保存方法があります。

単純な設定データなどは設定データとして~Settingに保存します。 大きいデータやファイル単位で保存したいデータは~Folder内にファイルを作って保存します。

設定データは、ApplicationDataContainerクラスで作られていて、キーそれに対応する値のセットでつくられます。

ファイルデータは、StorageFolderクラスとして保存するフォルダーを取得することができるのでそこにファイルとして書き込みます。

具体的には、ApplicationDataクラスの中に、

設定データ(ApplicationDataContainer型)

  • LocalSetting - ローカルの設定データ
  • RoamingSetting - ローミング設定データ

ファイルデータを入れるフォルダー(StorageFolder型)

  • LocalFolder - ローカルファイルフォルダー
  • RoamingFolder - ローミングファイルフォルダー
  • TemporaryFolder - 一時的なデータを保存するファイルフォルダー
  • LocalCacheFolder - 一時データ?

の6つのプロパティがあり、そこにデータを入れることになります。

20140714130709

 

ローカルデータとローミングデータ

さらに、WindowsRuntimeでは複数のデバイス間でデータを同期できるようにデータローミングという概念を採用しています。 Roamingがつく設定やフォルダーにデータを入れると、データはOneDriveで同期され、別のデバイスでも同じデータを扱うことができます。 ユニバーサルアプリの場合、「アプリをストアに関連付ける」をした後、WindowsアプリとWindowsPhoneアプリ間でデータがローミングされます。

 

別のデバイスでゲームをプレイしても、自分のスコアを引き継ぐことができるため、データローミングは非常に重要です。

20140714130531

 

ローカル設定データ

以下の名前空間を追加します。

using Windows.Storage;

 

ローカル設定データは、LocalSettingというコンテナーにキーと値をセットにしてデータを保存します。

public void SaveTextToLocalSetting(string key,string value)
{
    ApplicationDataContainer container = ApplicationData.Current.LocalSettings;
    container.Values[key] = value;
}

データを復元するときは、ContainsKeyを使ってキーがすでにあるかどうかを判定しましょう。

public string LoadTextFromLocalSetting(string key)
{
    ApplicationDataContainer container = ApplicationData.Current.LocalSettings;
    if (container.Values.ContainsKey(key))
    {
        return container.Values[key].ToString();
    }
    else
    {
        return null;
    }
}

 ローミング設定データ

データが同期される設定データは、RoamingSettingに保存します。 保存方法はLocalSettingと同じですが、この設定データは異なるデバイス間の同じアプリで同期されます。

public void SaveTextToRoamingSetting(string key, string value)
{
    ApplicationDataContainer container = ApplicationData.Current.RoamingSettings;
    container.Values[key] = value;
}

データ復元

public string LoadTextFromRoamingSetting(string key)
{

    ApplicationDataContainer container = ApplicationData.Current.RoamingSettings;
    if (container.Values.ContainsKey(key))
    {
        return container.Values[key].ToString();
    }
    else
    {
        return null;
    }
}

 ローカルファイルデータ

大きいファイルを保存する場合は、LocalFolderにStorageFolderを作って保存しましょう。

StorageFildeのCreateFileAsyncメソッドを使ってファイルを作ります。

今回はFileIOクラスのWriteTextAsyncでテキストデータを書き込みます。

public async Task SaveTextFileToLocalFolderAsync(string fileName, string value)
{
    StorageFolder folder = ApplicationData.Current.LocalFolder;
    StorageFile file = await folder.CreateFileAsync(fileName, CreationCollisionOption.ReplaceExisting);
    await FileIO.WriteTextAsync(file,value);
    
}

 

データ復元は、GetFileAsyncでデータを取得します。

その前に、GetFilesAsyncでファイル一覧を取得し、データが保存されているかどうかを判定します。

public async Task<string> LoadTextFileFromLocalFolderAsync(string fileName)
{
    StorageFolder folder = ApplicationData.Current.LocalFolder;
    if ((await folder.GetFilesAsync()).Where(q => q.Name == fileName).Any())
    {
        StorageFile file = await folder.GetFileAsync(fileName);
        return await FileIO.ReadTextAsync(file);
    }
    else
    {
        return null;
    }
}

 

ローミングファイルデータ

ファイルもデータローミングすることができます。

RoamingFolderに先ほどと同じようにファイルをつくり、書き込みます。

public async Task SaveTextFileToRoamingFolderAsync(string fileName, string value)
{
    StorageFolder folder = ApplicationData.Current.RoamingFolder;
    StorageFile file = await folder.CreateFileAsync(fileName, CreationCollisionOption.ReplaceExisting);
    await FileIO.WriteTextAsync(file, value);

}

データ復元

public async Task<string> LoadTextFileFromRoamingFolderAsync(string fileName)
{
    StorageFolder folder = ApplicationData.Current.RoamingFolder;
    if ((await folder.GetFilesAsync()).Where(q => q.Name == fileName).Any())
    {
        StorageFile file = await folder.GetFileAsync(fileName);
        return await FileIO.ReadTextAsync(file);
    }
    else
    {
        return null;
    }
}

 

サンプル

public class Game1 : Game
{
    GraphicsDeviceManager graphics;
    SpriteBatch spriteBatch;

    SpriteFont font;
    string text;

    bool isPressed;
    int score;
    ApplicationDataContainer container;

    public Game1()
    {
        graphics = new GraphicsDeviceManager(this);
        Content.RootDirectory = "Content";

    }


    protected override void Initialize()
    {
        text = "no state";
        isPressed = false;
        score = 0;
        container = ApplicationData.Current.LocalSettings;
        base.Initialize();
    }


    protected override void LoadContent()
    {
        spriteBatch = new SpriteBatch(GraphicsDevice);
        font = Content.Load<SpriteFont>("TestFont");

        if (container.Values.ContainsKey("score"))
        {
            score = int.Parse(container.Values["score"].ToString());
        }
    }

    protected override void UnloadContent()
    {
        
        
    }


    protected override void Update(GameTime gameTime)
    {
        KeyboardState state=Keyboard.GetState();
        if (state.IsKeyDown(Keys.Space) && isPressed == false)
        {
            container.Values["score"] = 100;

            isPressed = true;
            
        }
        if (state.IsKeyUp(Keys.Space))
        {
            isPressed = false;
        }

        text = "Score=" + score.ToString();
        base.Update(gameTime);
    }


    protected override void Draw(GameTime gameTime)
    {
        GraphicsDevice.Clear(Color.CornflowerBlue);

        spriteBatch.Begin();

        spriteBatch.DrawString(font,text,new Vector2(0,10),Color.White);

        spriteBatch.End();

        base.Draw(gameTime);
    }
}

スペースキーを押すと、スコアが保存され、次回以降の起動でスコアがロードされます。

104

 

 

サンプルコード

SampleGameMono_10_SaveData.zip

 

セーブデータを保存する | garicchi.com

目次