简体   繁体   中英

“.txt file not found” when trying to read/write in it on local storage - Libgdx, Android studio

I am making a simple game on Android studio with Libgdx and I am recording my highscore as a simple integer in a txt file which is located in the android>assets folder. In my GameOverState my current score is compared with the score in the text file and if it is bigger it is replaced in the txt file. Also every time I am in the MenuState the High Score is read from teh file and displayed as a BitmapFont. Problem is: When I run it on the Desktop it works perfectly but when I lauch it in the emulator an error occurs:

com.badlogic.gdx.utils.GdxRuntimeException: File not found: hs.txt (Local)

And this is my GameOverState:

package com.asya.game.states;

import com.asya.game.Ozone;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.files.FileHandle;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;

public class GameOverState extends state {

public int sc;
private Texture bgr;
private BitmapFont scoreFont;

public String txtScore;
public Integer hs;
public SaveHS saving;

public GameOverState(GameStateManager gsm, int score) {
    super(gsm);
    bgr = new Texture("gameOver.png");
    sc = score;
    scoreFont = new BitmapFont();
    scoreFont.setColor(Color.WHITE);


    //write to file if score is greater than the previous score
    FileHandle file = Gdx.files.local("hs.txt");
    txtScore = file.readString();
    hs = Integer.parseInt(txtScore);
    if (score > hs){
        hs = score;
        txtScore = Integer.toString(hs);
        file.writeString(txtScore, false);
    }

    /*
    saving = new SaveHS();
    hs = saving.Load();
    if (score > hs) {
        hs = score;
        saving.Save(score);
    }
    */
    cam.setToOrtho(false, Ozone.WIDTH, Ozone.HEIGHT);
}

@Override
protected void handleInput() {
    if(Gdx.input.justTouched())
        gsm.set(new MenuState(gsm));

}

@Override
public void update(float dt) {
    handleInput();
}

@Override
public void render(SpriteBatch sb) {
    sb.begin();
    sb.setProjectionMatrix(cam.combined);
    sb.draw(bgr, cam.position.x - (cam.viewportWidth / 2), 0);
    scoreFont.draw(sb, "SCORE: " + sc, cam.position.x / 2 + 140, cam.position.y + 200);
    sb.end();
}

@Override
public void dispose() {
    bgr.dispose();
    scoreFont.dispose();
}

}

And this is my MenuState:

package com.asya.game.states;

import com.asya.game.Ozone;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.InputProcessor;
import com.badlogic.gdx.files.FileHandle;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.utils.GdxRuntimeException;

import java.io.FileNotFoundException;
import java.io.ObjectOutputStream;

public class MenuState extends state implements InputProcessor{
private Texture background;
private Texture playBtn, helpBtn;
private Vector2 posPlayBtn, posHelpBtn;
private Rectangle boundPlayBtn, boundHelpBtn;
private String highScore;
private BitmapFont hScoreFont;

public SaveHS saving;
public int s;

public MenuState(GameStateManager gsm) {
    super(gsm);
    background = new Texture("bgr.png");
    playBtn = new Texture("play.png");
    helpBtn = new Texture("help.png");

    cam.setToOrtho(false, Ozone.WIDTH, Ozone.HEIGHT);

    posPlayBtn = new Vector2((Ozone.WIDTH / 2)- (playBtn.getWidth()/2), Ozone.HEIGHT/2 +playBtn.getHeight()/2);
    posHelpBtn = new Vector2((Ozone.WIDTH / 2) - (helpBtn.getWidth() / 2), Ozone.HEIGHT / 2 - helpBtn.getHeight() / 2);

    boundPlayBtn = new Rectangle(posPlayBtn.x, posPlayBtn.y, playBtn.getWidth(), playBtn.getHeight());
    boundHelpBtn = new Rectangle(posHelpBtn.x, posHelpBtn.y, helpBtn.getWidth(), helpBtn.getHeight());

    hScoreFont = new BitmapFont();
    hScoreFont.setColor(Color.WHITE);

        FileHandle file = Gdx.files.local("hs.txt");
        highScore = file.readString();

    /*
    saving = new SaveHS();
    s = saving.Load();
    */
    Gdx.input.setInputProcessor(this);
}

@Override
public void handleInput() {
}

@Override
public void update(float dt) {
    handleInput();
}

@Override
public void render(SpriteBatch sb) {
    //open sprite batch and close when done
    sb.setProjectionMatrix(cam.combined);
    sb.begin();
    sb.draw(background, cam.position.x - (cam.viewportWidth / 2), 0); //image, starting from coordinate 0, 0 (bottom left corner) and width and heiht
    hScoreFont.draw(sb, "HIGH SCORE: " + highScore,  cam.position.x / 2 + 140, cam.position.y + 200);
    sb.draw(playBtn, posPlayBtn.x, posPlayBtn.y);
    sb.draw(helpBtn, posHelpBtn.x, posHelpBtn.y );
    sb.end();
}

@Override
public void dispose() {
    background.dispose();
    playBtn.dispose();
    helpBtn.dispose();
    hScoreFont.dispose();
    System.out.println("Menu State Disposed");
}

@Override
public boolean keyDown(int keycode) {
    return false;
}

@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) {
    if(boundPlayBtn.contains(Gdx.graphics.getWidth() - screenX, Gdx.graphics.getHeight() - screenY)){
        gsm.set(new playState(gsm));
    }
    if(boundHelpBtn.contains(Gdx.graphics.getWidth() - screenX, Gdx.graphics.getHeight() - screenY)){
        gsm.set(new helpingState(gsm));
    }
    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;
}
}

Why not use Preferences , find out more information here .

It handles all saving across all devices and is part of the libGDX API.

// Get an instance
Preferences prefs = Gdx.app.getPreferences("Highscores");

// Save a high score
prefs.putInteger("high1", 999);
// Make sure it is saved
prefs.flush();

// Get the high score (the 0 is default, in case no high1 is set yet)
int high1 = prefs.getInteger("high1", 0);

You shouldn't really be saving highscores in a .txt when the API provides a means of doing this.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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