1

我有一个关于如何自动保存和加载游戏的问题。在这个例子中,就像Temple Run一样,它会自动保存游戏的所有内容(记录、获得的金钱和解锁的好东西),就像看起来一样简单。与 PlayStation 1 游戏相比,例如Abe's Exodus,它没有自动保存/加载功能,但它可以将游戏保存在游戏关卡中 Abe 离开的区域的确切位置以及您何时离开加载游戏,它会自动在此关卡中的最后一个位置开始游戏。

现在,我正在尝试通过我制作的这个简单的应用程序测试自动加载和保存游戏的这个功能,这是我期望成功的顺序如下:

  1. 首次打开应用,如果是新应用,可移动精灵默认从中心开始。
  2. 接下来,我尝试通过倾斜设备来移动精灵,并将其放置在顶部。
  3. 然后,当我使用BACK键而不是HOME键关闭应用程序时,通过处置关闭应用程序。
  4. 最后,当我重新打开应用程序时,只要我把它放在精灵上的那个坐标就会成为新的起点。

我的程序有一些错误。而不是顶部的精灵和这个位置应该保存这个坐标,一旦我重新打开精灵就会回到中心!我在代码工作区直接尝试了render()方法中的关键字Preferences以测试保存游戏的功能,但令人困惑,因为它似乎只读取值。

这是我关于上述主题的几个问题:

  1. 在 LibGDX 中使用SQL Lite for Java 来保存游戏是个好主意吗?
  2. 三星 Galaxy SIII等 Android 智能手机有 SD 卡插槽,但在Google Nexus 平板电脑中没有,主要问题是:Android 平板电脑中真的有外置驱动器吗?我可以通过编码将游戏保存在内部吗?
  3. 使用首选项是自动保存所有内容(即角色、记录、项目、设置、关卡等)并仅在关闭应用程序并重新打开后自动加载所有内容的唯一方法吗?

希望您能够帮助我。

这是我的代码:

Save_Load_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();
}

}

启动.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?
}

}
4

1 回答 1

2

您应该在保存的首选项文件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

于 2012-11-22T04:20:20.117 回答