保存游戏状态 Android

Posted

技术标签:

【中文标题】保存游戏状态 Android【英文标题】:Saving Game state Android 【发布时间】:2012-04-23 17:13:01 【问题描述】:

我不确定我应该如何保存我正在开发的游戏的游戏状态。我应该保存一个包含所有游戏信息的实例/对象吗?如果是,如何?还是应该将所有相关信息保存在 .txt 文件中,并在需要时保存/加载信息?

您是如何做到的?您如何看待我的建议?

【问题讨论】:

【参考方案1】:

除非您将其序列化并将其保存到某个文本/二进制/数据库文件中,否则您无法保存实例/对象。因此,您的两个选项是相同的。

您需要保存的是重建游戏状态所需的所有信息。您可能可以从这里获得一些信息。

如果您只有一小部分固定变量来定义您的游戏状态,那么请使用 SharedPreferences。

如果您想保留多个状态和/或保存更复杂,请使用一些文本(xml、json、...)/binary/database/.. 表示并存储它。

【讨论】:

【参考方案2】:

我可以建议使用 Parse。

https://parse.com/docs/android_guide#objects

The ParseObject

Storing data on Parse is built around the ParseObject. Each ParseObject contains key-value pairs of JSON-compatible data. This data is schemaless, which means that you don't need to specify ahead of time what keys exist on each ParseObject. You simply set whatever key-value pairs you want, and our backend will store it.

For example, let's say you're tracking high scores for a game. A single ParseObject could contain:

score: 1337, playerName: "Sean Plott", cheatMode: false
Keys must be alphanumeric strings. Values can be strings, numbers, booleans, or even arrays and objects - anything that can be JSON-encoded.

Each ParseObject has a class name that you can use to distinguish different sorts of data. For example, we could call the high score object a GameScore. We recommend that you NameYourClassesLikeThis and nameYourKeysLikeThis, just to keep your code looking pretty.

Saving Objects

Let's say you want to save the GameScore described above to the server. The interface is similar to a Map, plus the save method:

ParseObject gameScore = new ParseObject("GameScore");
gameScore.put("score", 1337);
gameScore.put("playerName", "Sean Plott");
gameScore.put("cheatMode", false);
try 
    gameScore.save();
 catch (ParseException e) 
    // e.getMessage() will have information on the error.

After this code runs, you will probably be wondering if anything really happened. To make sure the data was saved, you can look at the Data Browser in your app on Parse. You should see something like this:

objectId: "xWMyZ4YEGZ", score: 1337, playerName: "Sean Plott", cheatMode: false,
createdAt:"2011-06-10T18:33:42Z", updatedAt:"2011-06-10T18:33:42Z"
There are two things to note here. You didn't have to configure or set up a new Class called GameScore before running this code. Your Parse app lazily creates this Class for you when it first encounters it.

There are also a few fields you don't need to specify that are provided as a convenience. objectId is a unique identifier for each saved object. createdAt and updatedAt represent the time that each object was created and last modified on the server. Each of these fields is filled in by the server, so they don't exist on a ParseObject until a save operation has completed.

Retrieving Objects

Saving data to the cloud is fun, but it's even more fun to get that data out again. If you have the objectId, you can retrieve the whole ParseObject using a ParseQuery:

ParseQuery query = new ParseQuery("GameScore");
ParseObject gameScore;
try 
    gameScore = query.get("xWMyZ4YEGZ");
 catch (ParseException e) 
    // e.getMessage() will have information on the error.

To get the values out of the ParseObject, there's a getX method for each data type:

int score = gameScore.getInt("score");
String playerName = gameScore.getString("playerName");
boolean cheatMode = gameScore.getBoolean("cheatMode");
If you don't know what type of data you're getting out, you can call get(key), but then you probably have to cast it right away anyways. In most situations you should use the typed accessors like getString.

The three special values have their own accessors:

String objectId = gameScore.getObjectId();
Date updatedAt = gameScore.getUpdatedAt();
Date createdAt = gameScore.getCreatedAt();
If you need to refresh an object you already have with the latest data that is on the server, you can call the refresh method like so:

myObject.refresh();

【讨论】:

关于 Parse,你能在不知道其 Id 的情况下检索 ParseObject 吗?【参考方案3】:

您可以使用 SQLite 数据库来保存游戏中的重要变量。如果游戏从一个类开始,您可以为该类提供两个构造函数,一个从一开始就实例化普通游戏,另一个从游戏中接受所有变量并从保存点创建游戏对象。

这将允许您保存多个游戏(通过将 id 与任何数据一起保存)并且如果您更新游戏(假设您不更改数据库),游戏保存将不会丢失。

快速搜索“构造函数重载”以了解更多信息。

【讨论】:

【参考方案4】:

如果您的游戏不是数据密集型的,并且如果序列化并保存到共享首选项就足够了,您可以查看我编写的库的 GNStateManager 组件,以便轻松存储和检索标记为我的活动的必填字段@ GNState 注释。使用起来非常简单。也可以保存其他单例类对象状态。有关设置和使用信息,请参见此处:https://github.com/noxiouswinter/gnlib_android/wiki/gnstatemanager

【讨论】:

以上是关于保存游戏状态 Android的主要内容,如果未能解决你的问题,请参考以下文章

保存游戏状态的最佳方法是啥?

使用Game Center保存/分享游戏数据/状态

Activity 状态的保存和恢复

Android组件系列-----Activity保存状态

使用序列化 C++ 保存游戏状态

iCloud 用于保存相当频繁的游戏状态更改