我已經完成了一些研究,並且發現了很多關於如何在應用程序(LibGDX)中存儲關卡,高分,選項等數據的文章。但這些解決方案都不適合我。我閱讀了類Preferences的LibGDX描述並搜索了StackOverflow以獲取如何使用它的答案。LibGDX Android偏好 - 如何將數據保存到應用程序
所有我想要做的就是保存應用的水平,因此用戶不必再輸入應用
首選項(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();
在完成這些之後,我必須獲取寫入名爲「我的首選項」的文件的數據並從中獲取它?但是,自從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);
只是爲了看看它的工作。但它似乎並不像它那樣。我在代碼中丟失了什麼嗎?或者它是我缺少的需要創建的文件?
研究鏈接:
Using LibGDX with Android Preferences
Android libgdx preferences not working
http://www.badlogicgames.com/forum/viewtopic.php?f=11&t=6365#p32981
Android libgdx preferences not working
編輯:
我得到了我問的解釋,但我需要更多的信息。在我的LibGDX應用程序中,我有方法渲染,並且在該方法中我有menu(),game()。我不應該在渲染方法中調用首選項?它們應該在哪裏被調用,因爲如果它們在create()方法中,它們只會被調用一次?
我想我退出應用程序時可以調用Preferences(Prefs)方法來保存關卡數據。但它不起作用,應用程序仍然回到第一級。所以我決定在這裏發佈我的代碼,這樣每個人都可以看到我做錯了什麼。
(可以使用CTRL + F找到變量 「水平」 和 「首選項」 無處不在的代碼)
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()方法只調用一次偏好,因此不會保存關卡。
我瞭解首選項如何工作的基礎知識,但如果不能在render()方法中使用,我應該在哪裏調用startGame(),levelCompleted()方法?這些方法不是自動調用的嗎? 我將我的應用程序的代碼添加到StackOverflow,以便我的錯誤可以顯示出來。那麼每個人都可能更容易發現錯誤。 – kevvex
請檢查更新的答案:) – Aryan
是levelCompleted()prefs.increaseLevel()的方法,還是您稍後定義的方法? 順便說一下,當用戶回答所有問題時,纔會調用gameComplete()方法。在完成關卡後不會調用它。 這是solve()方法,它增加了level變量。 – kevvex