0

Andengine で Android 用のゲームを開発しています。レベルアンロックデータ、ハイスコアデータなどを保存するために SharedPreferences を使用することにしました。データを保存することはできましたが、ゲームを再度開くと、データが初期化データにリセットされます。そのため、ユーザーがいくつかのレベルを通過しても、すべてのレベルがロックされます。

私はこのクラスを使用します:

package com.example.aaa.extras;
import android.content.Context;
import android.content.SharedPreferences;
import android.util.Log;

public class UserData {

    private static UserData INSTANCE;

    private static final String PREFS_NAME = "GAME_USERDATA";

    /* These keys will tell the shared preferences editor which data we're trying to access */

    private static final String UNLOCKED_LEVEL_KEY = "GAME_USERDATA";
    private static final String SOUND_KEY = "soundKey";
    //private static final String LIFE = "playerHealth";
    private static final String HIGHSCORE = "GAME_USERDATA";
    private static final String EDITED[] = {"GAME_USERDATA", "GAME_USERDATA", "GAME_USERDATA", "GAME_USERDATA", "GAME_USERDATA", "GAME_USERDATA"};
    /* Create our shared preferences object and editor which will be used to save and load data */

    private SharedPreferences mSettings;
    private SharedPreferences.Editor mEditor;

    //keep track of max unlocked level
    public int mUnlockedLevel = 1;  //public int mUnlockedLevel = 5;


    //keep track of player high score
    public int mHighScore = 0;

    public boolean mEditedLevel[] = {false, false, false, false, false, false};

    //keep track of player health
    //public int health = 100;


    //keep track of whether or not not sound is enabled
    private boolean mSoundEnabled;

    UserData() {

    }

    public synchronized static UserData getInstance() {
            if (INSTANCE == null){
                    INSTANCE = new UserData();
                    Log.v("","Creates a new instance of UserData");
            }
            Log.v("","returns the instance of UserData");
            return INSTANCE;
    }

    public synchronized void init(Context pContext){
            if (mSettings == null){
                    mSettings = pContext.getSharedPreferences(PREFS_NAME, pContext.MODE_PRIVATE);

                    mEditor = mSettings.edit();

                    mUnlockedLevel = mSettings.getInt(UNLOCKED_LEVEL_KEY, 1);
                    mHighScore = mSettings.getInt(HIGHSCORE, 0);
                    mSoundEnabled = mSettings.getBoolean(SOUND_KEY, true);
                   for(int i=0;i<6;i++)
                       mEditedLevel[i] = mSettings.getBoolean(EDITED[i], false);

                    Log.v("","Set up initial values for UserData " + mUnlockedLevel + " " + mHighScore + " " + mSoundEnabled);
            }


    }

    public synchronized int getMaxUnlockedLevel() {
            return mUnlockedLevel;
    }

    public synchronized boolean isSoundMuted() {
            return mSoundEnabled;
    }

    public synchronized int getHighScore() {
            Log.v("","HighScore before increment " + mHighScore);
            return mHighScore;
    }

    public synchronized boolean getEdited(int i) {
        Log.v("","mEditedLevel before increment " + mEditedLevel[i]);
        return mEditedLevel[i];
    }

    public synchronized void unlockNextLevel() {
            mUnlockedLevel++;
            mEditor.putInt(UNLOCKED_LEVEL_KEY, mUnlockedLevel);
            mEditor.commit();
    }
    public synchronized void setSoundMuted(final boolean pEnableSound){
            mSoundEnabled = pEnableSound;
            mEditor.putBoolean(SOUND_KEY, mSoundEnabled);
            mEditor.commit();
    }
    public synchronized void setHighScore(final int newHighScore){
            mHighScore = newHighScore;
            Log.v("","mHighScore is " + mHighScore);
            mEditor.putInt(HIGHSCORE, mHighScore);
            mEditor.commit();
    }
    public synchronized void setEdited(int i, final boolean newEdited){
        mEditedLevel[i] = newEdited;
        Log.v("","mEditedLevel is " + mEditedLevel[i]);
        mEditor.putBoolean(EDITED[i], mEditedLevel[i]);
        mEditor.commit();
}
}

そして、次のように startActivity(first activity) で作成して init() します。

   public void onCreateScene(OnCreateSceneCallback pOnCreateSceneCallback) throws IOException
{
    SceneManager.getInstance().createSplashScene(pOnCreateSceneCallback);
    UserData userData = UserData.getInstance();
    userData.init(this);
}

そして、次のように使用する必要があるクラスで使用します。

    UserData.getInstance().setEdited(0, true);
    UserData.getInstance().getEdited(0));
4

2 に答える 2

1

SharedPreferences はキーと値のペアのマップであり、重複するキーを持つことはできません。多くのアイテムに同じキーを使用しているため、後で書き込まれるキーと値のペアは 1 つだけです。

private static final String UNLOCKED_LEVEL_KEY = "GAME_USERDATA";
private static final String SOUND_KEY = "soundKey";
private static final String HIGHSCORE = "GAME_USERDATA";
private static final String EDITED[] = {"GAME_USERDATA", "GAME_USERDATA", "GAME_USERDATA", "GAME_USERDATA", "GAME_USERDATA", "GAME_USERDATA"};

そして、最初の実行時に、設定をデフォルト値で初期化します - まだ書いていないので (コード内のコメントを参照):

public synchronized void init(Context pContext){
    if (mSettings == null){

        //use static Context.MODE_PRIVATE, instead pContext.MODE_PRIVATE
        //as an argument in getSharedPreferences
        mSettings = pContext.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);

        mEditor = mSettings.edit();

        //same key used for level, highscore, and editedlevel
        //which means all these variables will have the same value determined by "GAME_USERDATA" key
        mUnlockedLevel = mSettings.getInt(UNLOCKED_LEVEL_KEY, 1);
        mHighScore = mSettings.getInt(HIGHSCORE, 0);
        mSoundEnabled = mSettings.getBoolean(SOUND_KEY, true);

        for(int i=0;i<6;i++)
           mEditedLevel[i] = mSettings.getBoolean(EDITED[i], false);

        Log.v("","Set up initial values for UserData " + mUnlockedLevel + " " + mHighScore + " " + mSoundEnabled);
    }
}

後でこれらの値をコミットするコードは見当たりません。そのため、値が欠落している場合 (たとえば、mEditor.commit() を使用していない場合)、これらは常にデフォルト値を取得します。

また、最初の段落で述べたように、GAME_USERDATA を使用するアイテムの場合、設定にはキーと値のペアが 1 つしかありません。

キーを一意に変更します。

private static final String UNLOCKED_LEVEL_KEY = "unlocked_level_key";
private static final String SOUND_KEY = "soundKey";
private static final String HIGHSCORE = "highscore";
private static final String EDITED[] = {"ed1", "ed2", "ed3", "ed4", "ed5", "ed6"};

次に、各変数の異なる値を設定ファイルに保存するたびに、unlockNextLevel()、setSoundMuted()、setHighScore()、setEdited() を呼び出します。次回の init() では、保存されたとおりの値が得られます。 .

于 2013-12-07T00:01:44.367 に答える
0

内部初期化メソッド: Context.MODE_PRIVATE

mSettings = pContext.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);

edit() を読んでいるよりも削除します。書き込み専用です。

mEditor = mSettings.edit();
于 2013-12-07T00:01:32.710 に答える