繁体   English   中英

LibGDX And​​roid首选项-如何将数据保存到应用

[英]LibGDX Android Preferences - How to save data to app

我已经进行了一些研究,发现了很多有关如何在应用程序(LibGDX)中存储数据(例如级别,高分,选项等)的文章。 但是这些解决方案都不适合我。 我阅读了Preferences类的LibGDX描述,并在StackOverflow上搜索了如何使用它的答案。

我要做的就是保存应用程序的级别,以便用户在再次进入应用程序时不必重新开始

首选项(LibGDX)-https: //github.com/libgdx/libgdx/wiki/Preferences

但是当我输入libGDX向我显示的代码时,什么也没发生。 使用“首选项”是否足以输入此代码,或者我还需要做其他事情吗?

// LibGDX - create()
Preferences prefs = Gdx.app.getPreferences("My Preferences");

// LibGDX - render()
prefs.putString("name", "Donald Duck");
String name = prefs.getString("name", "No name stored");

prefs.putBoolean("soundOn", true);
prefs.putInteger("highscore", 10);

// bulk update your preferences
prefs.flush();

完成之后,在这种情况下,我必须获取写入“ My Preferences”文件中的数据,然后从那里获取数据? 但是,由于LibGDX显示了Windows的路径,因此在Android的哪里可以找到此文件。

%UserProfile%/.prefs/My Preferences

顺便说一句,在使用此类之前,我需要创建一个名为“我的首选项”的文件吗?还是由首选项创建文件本身?

LibGDX提供的代码是否按特定顺序放置? 我知道我必须先创建一个Preferences变量,然后创建要存储在文件中的值。 但是除此之外呢? 我是否使用错误的LibGDX方法将代码放入? (create(),render())。

我试图写代码

Preferences pref = Gdx.app.getPreferences("somefile");
pref.putString("name", "Menyo");
pref.putInteger("level", 20);

从一个链接,只是看看它是否有效。 但这似乎并非如此。 我在代码中缺少什么吗? 还是需要创建的文件?

研究链接:

将LibGDX与Android首选项结合使用

Android libgdx首选项不起作用

http://www.badlogicgames.com/forum/viewtopic.php?f=11&t=6365#p32981

应用程序如何保存数据

Android libgdx首选项不起作用

编辑:

我得到了我所要求的解释,但我需要更多信息。 在我的LibGDX应用程序中,我具有render方法,在该方法中,我具有menu(),game()。 我不应该在render方法中调用Preferences吗? 应该在哪里调用它们,因为只有在create()方法中它们才被调用一次吗?

我以为我可以在退出应用程序时调用Preferences(Prefs)方法来保存关卡数据。 但这没有用,该应用程序仍返回到第一级。 因此,我决定将代码发布在这里,以便每个人都可以看到我在做错什么。

(您可以使用CTRL + F在代码中的所有位置找到变量“ level”和“ prefs”)

package com.game.whatstheanswer;

import com.badlogic.gdx.ApplicationAdapter;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input;
import com.badlogic.gdx.InputProcessor;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.GlyphLayout;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g2d.freetype.FreeTypeFontGenerator;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;

public class MyGdxGame extends ApplicationAdapter implements InputProcessor {
private SpriteBatch batch;

private GAME STATE;
private BitmapFont font;
private BitmapFont fontTextAdjustment;
private GlyphLayout layout;
private String message;

private Texture logo;
private Texture questionmarks;
private Texture keyboard;

private Texture btnReset;
private Texture btnMenu;

@Override
public void create () {
    batch = new SpriteBatch();

    // Configure the Android keyboard
    Gdx.input.setInputProcessor(this);
    isAndroidKeyboardShowing = true;

    // Menu logo
    logo = new Texture("logo.png");
    questionmarks = new Texture("questionmarks.png");
    //level = 1;

    STATE = GAME.MENU;
    btnPlay = new Texture("play.png");
    btnInfo = new Texture("info.png");
    btnQuit = new Texture("quit.png");

    // The game over menu
    btnMenu = new Texture("menu.png");
    btnReset = new Texture("reset.png");

    FreeTypeFontGenerator generator = new FreeTypeFontGenerator(Gdx.files.internal("Amethysta.ttf"));
    FreeTypeFontGenerator.FreeTypeFontParameter parameter = new FreeTypeFontGenerator.FreeTypeFontParameter();
    parameter.size = 66;
    font = generator.generateFont(parameter); // font size 66 pixels

    parameter.size = 28;
    fontTextAdjustment = generator.generateFont(parameter);
    generator.dispose(); // don't forget to dispose to avoid memory leaks!


    layout = new GlyphLayout();

    keyboard = new Texture("keyboard/keyboard.png");

    userInput = "";
    message = "";
    /*
    prefs = Gdx.app.getPreferences("com.game.whatstheanswer.settings");
    String name = prefs.getString("Level", "0");*/

    prefs = new Prefs();
}

private Prefs prefs;
//private static Preferences prefs;

//private String letter;
private String userInput;
private String answer;
private int level;

@Override
public void render () {
    Gdx.gl.glClearColor(255, 255, 255, 1);
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

    batch.begin();

    //STATE = GAME.OVER;
    switch (STATE) {
        case MENU: menu(); break;
        case PLAY:
            Gdx.gl.glClearColor(0, 0, 0, 1);
            Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
            game();
            break;
        case PAUSE: break;
        case RESUME: break;
        case OVER: gameComplete(); break;
    }
    batch.end();
}

private Texture btnPlay, btnInfo, btnQuit;
private void menu() {
    // Draw a colorful background
    batch.draw(logo, Gdx.graphics.getWidth()/2 - logo.getWidth()/2, Gdx.graphics.getHeight() - logo.getHeight());
    batch.draw(questionmarks, Gdx.graphics.getWidth()/2 - logo.getWidth()/2, Gdx.graphics.getHeight() - logo.getHeight() - 460);
    batch.draw(btnPlay, Gdx.graphics.getWidth() / 2 - btnPlay.getWidth() / 2, 600);
    batch.draw(btnInfo, Gdx.graphics.getWidth() / 2 - btnInfo.getWidth() / 2, 400);
    batch.draw(btnQuit, Gdx.graphics.getWidth() / 2 - btnQuit.getWidth() / 2, 200);

    // Play button
    if (Gdx.input.justTouched() &&
            Gdx.input.getX() >= Gdx.graphics.getWidth()/2 - btnPlay.getWidth()/2 &&
            Gdx.input.getX() <= (Gdx.graphics.getWidth()/2 - btnPlay.getWidth()/2) + btnPlay.getWidth() &&
            Gdx.input.getY() >= Gdx.graphics.getHeight() - 600 - btnPlay.getHeight() &&
            Gdx.input.getY() <= Gdx.graphics.getHeight() - 600) {
        STATE = GAME.PLAY;
        isAndroidKeyboardShowing = true;
        System.out.println("Main Menu: Play");
    }

    // Info button
    if (Gdx.input.justTouched() &&
            Gdx.input.getX() >= Gdx.graphics.getWidth()/2 - btnPlay.getWidth()/2 &&
            Gdx.input.getX() <= (Gdx.graphics.getWidth()/2 - btnPlay.getWidth()/2) + btnPlay.getWidth() &&
            Gdx.input.getY() >= Gdx.graphics.getHeight() - 400 - btnPlay.getHeight() &&
            Gdx.input.getY() <= Gdx.graphics.getHeight() - 400) {
        System.out.println("Main Menu: Info");
    }

    // Quit button
    if (Gdx.input.justTouched() &&
            Gdx.input.getX() >= Gdx.graphics.getWidth()/2 - btnPlay.getWidth()/2 &&
            Gdx.input.getX() <= (Gdx.graphics.getWidth()/2 - btnPlay.getWidth()/2) + btnPlay.getWidth() &&
            Gdx.input.getY() >= Gdx.graphics.getHeight() - 200 - btnPlay.getHeight() &&
            Gdx.input.getY() <= Gdx.graphics.getHeight() - 200) {
        level = prefs.getLevel();
        Gdx.app.exit();
        System.out.println("Main Menu: Quit");
    }
}

/*
public void increaseLevel() {
    prefs.putString("Level", String.valueOf(level));
    prefs.flush();
    Gdx.app.log("level", level+"");
}*/

private void game() {
    // Set the color of the text
    font.setColor(Color.WHITE);

    level = prefs.getLevel();
    /*
    font.draw(batch, "MENU", 120, Gdx.graphics.getHeight() - 80);
    font.draw(batch, "CLEAR", 420, Gdx.graphics.getHeight() - 80);
    font.draw(batch, "SOLVE", 740, Gdx.graphics.getHeight() - 80);*/

    font.draw(batch, "MENU", Gdx.graphics.getWidth()/7, Gdx.graphics.getHeight() - 80);
    font.draw(batch, "CLEAR", (((7/2)*Gdx.graphics.getWidth()/7)), Gdx.graphics.getHeight() - 80);
    font.draw(batch, "SOLVE", 5*Gdx.graphics.getWidth()/7, Gdx.graphics.getHeight() - 80);

    System.out.println(userInput);

    layout.setText(font, "Question " + level);
    font.draw(batch, "Question " + level, Gdx.graphics.getWidth()/2 - layout.width/2, 5*Gdx.graphics.getHeight()/6);

    switch (level) {
        default: break;
        // my cases are in here, removed them to shortned the code
        case 1: break;
        case 2: break;
        ...
        case n: break;
    }

    // The user input
    layout.setText(font, userInput);
    font.draw(batch, userInput, Gdx.graphics.getWidth() / 2 - layout.width / 2, 880);

    //layout.setText(font, letter = "Q");

    drawnKeyboard();
    inputKeyboard();

    ShapeRenderer shapeRenderer = new ShapeRenderer();
    shapeRenderer.begin(ShapeRenderer.ShapeType.Line);
    shapeRenderer.setColor(com.badlogic.gdx.graphics.Color.WHITE);

    // Horizontal line, user input above it
    shapeRenderer.rectLine(110, 800, Gdx.graphics.getWidth() - 110, 800, 4); // shapeRenderer.rectLine(120, 800, 940, 800, 4);

    shapeRenderer.end();

}

// Questions on one line
private void msgOneLine(String message, String answer) {
    this.message = message;
    this.answer = answer;
    layout.setText(font, message);
    font.draw(batch, message, (Gdx.graphics.getWidth() / 2) - layout.width/2, 1200);
}

private void msgTwoLines(String msg1, String msg2, String answer) {
    this.message = msg1;
    this.answer = answer;
    layout.setText(fontTextAdjustment, message);
    font.draw(batch, message, (Gdx.graphics.getWidth() / 2) - layout.width - 80, 1200);
    message = msg2;
    layout.setText(fontTextAdjustment, message);
    font.draw(batch, message, (Gdx.graphics.getWidth() / 2) - layout.width - 80, 1200 - layout.height - 50);
}

private void msgThreeLines(String msg1, String msg2, String msg3, String answer) {
    this.message = msg1;
    this.answer = answer;
    layout.setText(fontTextAdjustment, message);
    font.draw(batch, message, (Gdx.graphics.getWidth() / 2) - layout.width - 80, 1200);

    message = msg2;
    layout.setText(fontTextAdjustment, message);
    font.draw(batch, message, (Gdx.graphics.getWidth() / 2) - layout.width - 80, 1200 - layout.height - 50);

    message = msg3;
    layout.setText(fontTextAdjustment, message);
    font.draw(batch, message, (Gdx.graphics.getWidth() / 2) - layout.width - 80, 1200 - layout.height - 120);
}

private void msgFourLines(String msg1, String msg2, String msg3, String msg4, String answer) {
    this.message = msg1;
    this.answer = answer;
    layout.setText(fontTextAdjustment, message);
    font.draw(batch, message, (Gdx.graphics.getWidth() / 2) - layout.width - 80, 1200);

    message = msg2;
    layout.setText(fontTextAdjustment, message);
    font.draw(batch, message, (Gdx.graphics.getWidth() / 2) - layout.width - 80, 1200 - layout.height - 50);

    message = msg3;
    layout.setText(fontTextAdjustment, message);
    font.draw(batch, message, (Gdx.graphics.getWidth() / 2) - layout.width - 80, 1200 - layout.height - 120);

    message = msg4;
    layout.setText(fontTextAdjustment, message);
    font.draw(batch, message, (Gdx.graphics.getWidth() / 2) - layout.width - 80, 1200 - layout.height - 190);
}

private void drawnKeyboard() {

    batch.draw(keyboard, 440, 400);

}

private boolean isAndroidKeyboardShowing;
private void inputKeyboard() {
    if (Gdx.input.justTouched()) {
        System.out.println("(" + Gdx.input.getX() + ", " + Gdx.input.getY() + ")");

        // ####################### BOTTOM BUTTONS #######################

        // Menu button
        if (Gdx.input.getX() > 76 && Gdx.input.getX() < 350 && Gdx.input.getY() > 40 && Gdx.input.getY() < 116) {
            STATE = GAME.MENU;
            isAndroidKeyboardShowing = false;
        }

        // Clear button
        if (Gdx.input.getX() > 350 && Gdx.input.getX() < 676 && Gdx.input.getY() > 40 && Gdx.input.getY() < 116) {
            userInput = "";
        }

        // Solve button
        if (Gdx.input.getX() > 676 && Gdx.input.getX() < 976 && Gdx.input.getY() > 40 && Gdx.input.getY() < 116) {
            System.out.println("SOLVE");
            solve();
        }

    }

    // Android keyboard
    Gdx.input.setOnscreenKeyboardVisible(isAndroidKeyboardShowing);
}

// The solve algorithm
private void solve() {

    if (userInput.equalsIgnoreCase(answer)) {
        //level++;
        prefs.increaseLevel();
        userInput = "";
    }

    userInput = "";
}

@Override
public boolean keyDown(int keycode) {

    switch (keycode) {
        // Numbers
        case Input.Keys.NUM_0: userInput += '0'; break;
        case Input.Keys.NUM_1: userInput += '1'; break;
        case Input.Keys.NUM_2: userInput += '2'; break;
        case Input.Keys.NUM_3: userInput += '3'; break;
        case Input.Keys.NUM_4: userInput += '4'; break;
        case Input.Keys.NUM_5: userInput += '5'; break;
        case Input.Keys.NUM_6: userInput += '6'; break;
        case Input.Keys.NUM_7: userInput += '7'; break;
        case Input.Keys.NUM_8: userInput += '8'; break;
        case Input.Keys.NUM_9: userInput += '9'; break;

        // All english letters
        case Input.Keys.A: userInput += 'A'; break;
        case Input.Keys.B: userInput += 'B'; break;
        case Input.Keys.C: userInput += 'C'; break;
        case Input.Keys.D: userInput += 'D'; break;
        case Input.Keys.E: userInput += 'E'; break;
        case Input.Keys.F: userInput += 'F'; break;
        case Input.Keys.G: userInput += 'G'; break;
        case Input.Keys.H: userInput += 'H'; break;
        case Input.Keys.I: userInput += 'I'; break;
        case Input.Keys.J: userInput += 'J'; break;
        case Input.Keys.K: userInput += 'K'; break;
        case Input.Keys.L: userInput += 'L'; break;
        case Input.Keys.M: userInput += 'M'; break;
        case Input.Keys.N: userInput += 'N'; break;
        case Input.Keys.O: userInput += 'O'; break;
        case Input.Keys.P: userInput += 'P'; break;
        case Input.Keys.Q: userInput += 'Q'; break;
        case Input.Keys.R: userInput += 'R'; break;
        case Input.Keys.S: userInput += 'S'; break;
        case Input.Keys.T: userInput += 'T'; break;
        case Input.Keys.U: userInput += 'U'; break;
        case Input.Keys.V: userInput += 'V'; break;
        case Input.Keys.W: userInput += 'W'; break;
        case Input.Keys.X: userInput += 'X'; break;
        case Input.Keys.Y: userInput += 'Y'; break;
        case Input.Keys.Z: userInput += 'Z'; break;

        // Special keys
        case Input.Keys.ENTER: solve(); break;

        case Input.Keys.BACKSPACE:
            if (userInput.length() > 0)
                userInput = userInput.substring(0, userInput.length()-1);
            break;
    }

    return true;
}

private void gameComplete() {
    font.setColor(Color.BLACK);
    layout.setText(font, "Play again? Reset?");
    font.draw(batch, "Play again? Reset?", Gdx.graphics.getWidth()/2 - layout.width/2, Gdx.graphics.getHeight() - 400);

    batch.draw(btnMenu, Gdx.graphics.getWidth() / 2 - btnMenu.getWidth() / 2, 600);
    batch.draw(btnReset, Gdx.graphics.getWidth() / 2 - btnReset.getWidth() / 2, 400);
    batch.draw(btnQuit, Gdx.graphics.getWidth() / 2 - btnQuit.getWidth() / 2, 200);

    // Menu button
    if (Gdx.input.justTouched() &&
            Gdx.input.getX() >= Gdx.graphics.getWidth()/2 - btnMenu.getWidth()/2 &&
            Gdx.input.getX() <= (Gdx.graphics.getWidth()/2 - btnMenu.getWidth()/2) + btnMenu.getWidth() &&
            Gdx.input.getY() >= Gdx.graphics.getHeight() - 600 - btnMenu.getHeight() &&
            Gdx.input.getY() <= Gdx.graphics.getHeight() - 600) {
        STATE = GAME.MENU;
        System.out.println("Game Over Menu: Menu");
    }

    // Reset button
    if (Gdx.input.justTouched() &&
            Gdx.input.getX() >= Gdx.graphics.getWidth()/2 - btnReset.getWidth()/2 &&
            Gdx.input.getX() <= (Gdx.graphics.getWidth()/2 - btnReset.getWidth()/2) + btnReset.getWidth() &&
            Gdx.input.getY() >= Gdx.graphics.getHeight() - 400 - btnReset.getHeight() &&
            Gdx.input.getY() <= Gdx.graphics.getHeight() - 400) {
        level = 1;
        System.out.println("Game Over Menu: Reset");
    }

    // Quit button
    if (Gdx.input.justTouched() &&
            Gdx.input.getX() >= Gdx.graphics.getWidth()/2 - btnQuit.getWidth()/2 &&
            Gdx.input.getX() <= (Gdx.graphics.getWidth()/2 - btnQuit.getWidth()/2) + btnQuit.getWidth() &&
            Gdx.input.getY() >= Gdx.graphics.getHeight() - 200 - btnQuit.getHeight() &&
            Gdx.input.getY() <= Gdx.graphics.getHeight() - 200) {
        Gdx.app.exit();
        System.out.println("Game Over Menu: Quit");
    }
}

// Usual input
@Override
public boolean keyUp(int keycode) {
    return false;
}

@Override
public boolean keyTyped(char character) {
    return false;
}

@Override
public boolean touchDown(int screenX, int screenY, int pointer, int button) {
    return false;
}

@Override
public boolean touchUp(int screenX, int screenY, int pointer, int button) {
    return false;
}

@Override
public boolean touchDragged(int screenX, int screenY, int pointer) {
    return false;
}

@Override
public boolean mouseMoved(int screenX, int screenY) {
    return false;
}

@Override
public boolean scrolled(int amount) {
    return false;
}

}

编辑对不起的人,我曾经试图实施你给我,但我还是做错事的代码。 我所有的方法game(),menu(),gameComplete()都位于batch.begin()和batch.end()之间的render()方法中。 关闭应用程序时,我需要保存级别。

但是,如何检查实际发生的事情,以便使我知道自己的偏好已创建? 此外,如果不建议在render()方法中调用首选项,应该在哪里调用它们? create()方法仅调用一次首选项,因此不会保存级别。

无需创建My Preferences ,它可以自行创建。 与首选项相关的工作不应在render方法中完成。

在Android上,使用系统的[SharedPreferences] [1]类。 这意味着首选项将在应用程序更新后保留下来,但在卸载应用程序时将被删除。 SharedPreferences将私有原始数据存储在键值对中。

public class TestGame2 extends Game {

    public Prefs prefs;

    @Override
    public void create() {

        prefs=new Prefs();

        System.out.printf("Current Sound Status"+prefs.hasSound());

        // I need to to change sound Status
        prefs.setSound(false);

        //Now sound is off

    }

    public void playSound(){

        if(prefs.hasSound()) {
            Sound sound=Gdx.audio.newSound("....");
            sound.play();
        }
    }

    public void startGame(){

        //what is my previous highest saved game level, last time

        int level=prefs.getLevel();
    }

    public void levelCompleted(){

        // wow last Level completed so now i need to increase level
        prefs.increaseLevel();
    }
}

Prefs是:

public class Prefs {

    private Preferences pref ;
    private boolean hasSound;
    private int completedLevel;

    public Prefs(){
        pref = Gdx.app.getPreferences("My Preferences");
        hasSound = pref.getBoolean("hasSound",true);
        completedLevel=pref.getInteger("level",0);

    }

    public void setSound(boolean hasSound){
        this.hasSound=hasSound;
        pref.putBoolean("hasSound",hasSound);
        pref.flush();
    }

    public boolean hasSound(){
        return hasSound;
    }

    //should be called once when we need to increase my level
    public void increaseLevel(){
        completedLevel++;
        pref.putInteger("level",completedLevel);
        pref.flush();
    }

    public int getLevel(){
        return completedLevel;
    }
}

编辑

使用相同的计数器。

boolean isDataSaved;

private void gameComplete() {   // your method

  if(!isDataSaved){
      levelCompleted();
      isDataSaved=true;
  }

  font.setColor(Color.BLACK);
  layout.setText(font, "Play again? Reset?");
}

private void menu() {
    isDataSaved=false;
}

并且您已经在game方法中使用了startGame()代码。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM