Концепция автоматического сохранения и автоматической загрузки игр в играх для Android и сохранение во внутренней памяти по сравнению с другими. Внешний (также известный как SD-карта)

У меня вопрос по поводу автоматического сохранения и загрузки игры. В этом примере, подобно Temple Run, он автоматически сохраняет игру на всем (записи, полученные деньги и разблокированные вкусности), как бы просто это ни казалось. По сравнению с игрой для PlayStation 1, скажем, Abe's Exodus, в ней нет функции автоматического сохранения/загрузки, но она может сохранять игру в точном местоположении области внутри уровня игру, где ушел Эйб, и когда вы загружаете игру, она автоматически запускает игру на последней локации, оставшейся на этом уровне.

Теперь я пытаюсь протестировать эту функцию автоматической загрузки и сохранения игры с помощью этого простого приложения, которое я сделал, вот последовательность, в которой я ожидаю успеха:

  1. Откройте приложение в первый раз, и если это новое приложение, подвижный спрайт по умолчанию будет начинаться в центре.
  2. Далее я попытался переместить спрайт, наклонив устройство и поместив его не сверху.
  3. Затем, когда я закрываю приложение, используя клавишу BACK, а не клавишу HOME, чтобы закрыть приложение путем утилизации.
  4. Наконец, когда я снова открываю приложение, всякий раз, когда эта координата, которую я поместил на спрайт, будет новой отправной точкой.

В моей программе есть ошибки. Вместо спрайта сверху, и это место должно сохранять эту координату, спрайт возвращается в центр, когда я снова открываю! Я попробовал ключевое слово Preferences в методе render() непосредственно в рабочей области кода, чтобы проверить возможность сохранения игры, но сбивает с толку, поскольку кажется, что он только считывает значение.

Вот мои несколько вопросов по этой теме выше:

  1. Стоит ли использовать SQL Lite для Java в LibGDX для сохранения игры?
  2. Android-смартфоны, такие как Samsung Galaxy SIII, имеют слот для SD-карты, но не в Google Nexus Tablet, и основная проблема заключается в следующем: действительно ли в планшетах Android есть внешний диск? ? Могу ли я сохранить игру во внутреннюю память вместо того, чтобы закодировать ее?
  3. Является ли использование настроек единственным способом автоматически сохранить все (то есть персонажей, записи, предметы, настройки, уровни и т. д.) и автоматически загрузить все, только если после закрытия приложения и его повторного открытия?

Надеюсь, вы можете мне помочь.

Вот мой код:

Сохранить_Загрузить_Test.java

package com.test.save_and_load_test;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Preferences;
import com.badlogic.gdx.Screen;
import com.badlogic.gdx.Input.Keys;
import com.badlogic.gdx.graphics.GL10;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.Texture.TextureFilter;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.utils.GdxRuntimeException;

public class Save_and_Load_Test implements Screen 
{

private OrthographicCamera camera;
private Texture texture;
private Texture background;
private SpriteBatch batch;
private Rectangle pos;
private Rectangle BG_pos;
private float w = 720;
private float h = 1280;

Start game;

public Save_and_Load_Test(Start game)
{
    this.game = game;
}

@Override
public void render(float delta) 
{
    // TODO render()
    Gdx.gl.glClearColor(0, 0, 0, 1);
    Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);

    batch.setProjectionMatrix(camera.combined);
    batch.begin();

        batch.draw(background, BG_pos.x, BG_pos.y);
        batch.draw(texture, pos.x, pos.y);

    batch.end();

    if(Gdx.input.getAccelerometerX() >= 1 && pos.x >= 0)
    {
        pos.x -= 20;
    }

    if(Gdx.input.getAccelerometerX() <= -1 && pos.x <= (720 - pos.width))
    {
        pos.x += 20;
    }

    if(Gdx.input.getAccelerometerY() >= 1 && pos.y >=0)
    {
        pos.y -= 20;
    }

    if(Gdx.input.getAccelerometerY() <= -1 && pos.y <= (1280 - pos.height))
    {
        pos.y += 20;
    }

    if(Gdx.input.isKeyPressed(Keys.RIGHT) && pos.x <= (720 - pos.width - 35))
    {
        pos.x += 20;
    }

    if(Gdx.input.isKeyPressed(Keys.LEFT) && pos.x >=0)
    {
        pos.x -= 20;
    }

    if(Gdx.input.isKeyPressed(Keys.UP) && pos.y <= (1280 - pos.height - 35))
    {
        pos.y += 20;
    }

    if(Gdx.input.isKeyPressed(Keys.DOWN) && pos.y >= 0)
    {
        pos.y -= 20;
    }

    Preferences prefs = Gdx.app.getPreferences("my-preferences");

    prefs.putFloat("X", pos.x);
    prefs.putFloat("Y", pos.y);
    prefs.flush();
}

@Override
public void resize(int width, int height) {
    // TODO Auto-generated method stub

}

@Override
public void show() 
{
    // TODO show()
    camera = new OrthographicCamera();
    camera.setToOrtho(false, w, h);

    texture = new Texture(Gdx.files.internal("Jeff_the_Happy_Clown.png"));
    background = new Texture(Gdx.files.internal("babe_BG.png"));

    texture.setFilter(TextureFilter.Linear, TextureFilter.Linear);
    background.setFilter(TextureFilter.Linear, TextureFilter.Linear);

    batch = new SpriteBatch();

    pos = new Rectangle();
    pos.width = 100;
    pos.height = 100;
    pos.x = (w/2) - (pos.width/2);
    pos.y = (h/2) - (pos.height/2);

    BG_pos = new Rectangle();
    BG_pos.width = background.getWidth();
    BG_pos.height = background.getHeight();
    BG_pos.x = (w/2) - (BG_pos.width/2);
    BG_pos.y = (h/2) - (BG_pos.height/2);
}

@Override
public void hide() {
    // TODO Auto-generated method stub

}

@Override
public void pause() {
    // TODO Auto-generated method stub

}

@Override
public void resume() {
    // TODO Auto-generated method stub

}

@Override
public void dispose() 
{
    // TODO dispose
    batch.dispose();
    texture.dispose();
}

}

Start.java

package com.test.save_and_load_test;

import com.badlogic.gdx.Game;

public class Start extends Game
{

@Override
public void create() 
{
    setScreen(new Save_and_Load_Test(this));
}

@Override
public void resume()
{
    // Is this method involved for loading the last file game saved?
}

}

person David Dimalanta    schedule 19.11.2012    source источник
comment
Если эти два java-класса слишком длинны для анализа, я бы посоветовал взглянуть на метод render(), я помещаю код предпочтения в последнюю строку; и проверьте Start.java, потому что я использую переопределение резюме(). Это автоматически загрузит последний сохраненный файл.   -  person David Dimalanta    schedule 20.11.2012


Ответы (1)


Вы должны инициализировать pos в методах resume и show из сохраненного файла настроек. Что-то типа:

Preferences prefs = Gdx.app.getPreferences("my-preferences");
pos.x = prefs.getFloat("X", 99.0f); // XXX use a better default
pos.y = prefs.getFloat("Y", 99.0f); // XXX use a better default

Если вы вычислите разумные значения по умолчанию, вам не придется беспокоиться об исходном случае.

Технически вы можете просто сделать это в начале render (в обычном случае вы просто перечитаете значения, которые вы только что сохранили в предыдущем рендере, но в случае, когда это первый вызов render, это должно помочь). Но это кажется немного расточительным (и делать ненужные вещи в потоке рендеринга, особенно IO, — плохая идея).

flush при каждом рендеринге немного избыточно, и это приведет к случайным сбоям, когда IO останавливает ваш поток рендеринга. Вы должны быть в состоянии просто flush объект настроек в pause, так как ваше приложение находится на выходе. (Конечно, вам нужно будет сохранить ссылку на объект Preferences в вашем экземпляре.)

Другие ваши вопросы в конце этого вопроса должны быть опубликованы как отдельный вопрос. Прежде чем сделать это, обязательно прочитайте http://developer.android.com/guide/topics/data/data-storage.html

person P.T.    schedule 22.11.2012
comment
Если я использую Gdx.app.getPreferences(my-preferences), my-preferences можно указать как имя с самого начала, верно? - person David Dimalanta; 22.11.2012
comment
Согласно Badlogicgames.com, настройки LibGDX будут представлять собой код «два в одном» (автоматически создает XML-файл для рабочего стола и SharedPreferences для Android), верно? И когда я увидел часть Gdx, getPreferences(my-preferences), ищет ли он my-preferences.txt или .file(?) в папке с ресурсами или дает имя переменной как есть? - person David Dimalanta; 22.11.2012
comment
Имя, переданное Gdx.app.getPreferences, используется для создания имени файла на хосте (в каталоге пользователя на рабочем столе или в личном хранилище приложения — не совсем в каталоге ресурсов — на Android). Содержимое объекта prefs будет прочитано и сброшено в этот файл. - person P.T.; 22.11.2012
comment
Я понимаю. Я собираюсь проверить это предложение, которое вы мне дали. - person David Dimalanta; 22.11.2012
comment
Оно работает! Любопытный вопрос: почему вы использовали 99.0f в методе getFloat()? - person David Dimalanta; 22.11.2012
comment
Я использовал 99.0f, чтобы было ясно, что это магия, которую нужно заменить. Это значение по умолчанию, используемое, если значение предпочтения не найдено. - person P.T.; 22.11.2012
comment
Итак, вы хотите сказать, что это как индекс (т.е. 99.0f)? - person David Dimalanta; 23.11.2012