如何有效地将游戏数据存储在URL查询字符串中



背景

我写了一个简单的WebGL益智游戏,我想让人们设计和分享他们自己的关卡。

我的想法是将级别数据存储在URL的查询字符串中。这样,如果人们想让朋友尝试这个级别,就可以简单地共享URL。

在查询字符串中存储游戏数据的好方法是什么?

我尝试过的

目前我通过生成URL

"penguins.html?data="+encodeURIComponent(JSON.stringify([X,P]));

这首先将数据转换为JSON:

[[[[3,-1,0,0,0],[4,-1,0,0,0]]],[{"x":20,"y":20,"dx":0,"dy":0,"vy":2.9999999871229686,"vx":0.0002779607689814708,"thetaf":180,"speed":3,"type":0,"state":6,"steps":0,"numfish":0,"d":4,"size":8},{"x":60,"y":60,"dx":20,"dy":100,"vy":97.51615330485151,"vx":-78.06665276994102,"thetaf":0,"speed":3,"type":17,"state":0,"steps":0,"numfish":0,"d":15,"size":89.00000012433019}]]

然后逃离它变成:

[[[[3%2C-1%2C0%2C0%2C0]%2C[4%2C-1%2C0%2C0%2C0]]]%2C[{%22x%22%3A20%2C%22y%22%3A20%2C%22dx%22%3A0%2C%22dy%22%3A0%2C%22vy%22%3A2.9999999871229686%2C%22vx%22%3A0.0002779607689814708%2C%22thetaf%22%3A180%2C%22speed%22%3A3%2C%22type%22%3A0%2C%22state%22%3A6%2C%22steps%22%3A0%2C%22numfish%22%3A0%2C%22d%22%3A4%2C%22size%22%3A8}%2C{%22x%22%3A60%2C%22y%22%3A60%2C%22dx%22%3A20%2C%22dy%22%3A100%2C%22vy%22%3A97.51615330485151%2C%22vx%22%3A-78.06665276994102%2C%22thetaf%22%3A0%2C%22speed%22%3A3%2C%22type%22%3A17%2C%22state%22%3A0%2C%22steps%22%3A0%2C%22numfish%22%3A0%2C%22d%22%3A15%2C%22size%22%3A89.00000012433019}]]

当前方法的缺点

这种方法适用于小级别,但对于更大的级别,我会得到错误:

414. That’s an error.
The requested URL /penguins.html... is too large to process.

我目前的主机(Google Appengine)似乎对URL的长度有限制。

问题

在Javascript中是否有更好的方法来存储我的游戏数据(即,这将导致更短的URI)?

我也做过类似的事情,用JSON数据对GAE进行POST,并用生成的密钥将其存储在数据存储中,并基于该密钥返回一个url供用户共享。

因此,您可以发布JSON数据。您将数据存储在一个对象中,如:

/* Annotations ommitted */
public class GameInfo {
    public JSONObject gameData;
    public Integer key;
}

CCD_ 1是自动生成的CCD_。然后,您向用户返回一个url,如:http://www.mygameurl.com/games?id=1234,其id对应于生成的key。然后,您可以让用户共享该url,以从数据存储中获取游戏数据。它缩短了用户共享的url,防止他们篡改url和破坏游戏数据。

由于数据是由客户端解析和使用的,因此实际上不需要将这些数据发送到服务器。因此,与其使用查询字符串,不如使用url的哈希部分:

"penguins.html#" + encodeURIComponent(JSON.stringify([X, P]));

注意#。现在,您可以使用解析日期

JSON.parse(location.hash.substring(1));

您只需将游戏存储在sql数据库中,并将url指向DB上的ID即可加载。

或者,如果你想要,但更复杂的是,将url打包在二进制数据中,并将其显示为base64,所以只需要解压缩即可加载游戏。

这取决于您正在开发的游戏类型,但在某些情况下,特别是在确定性益智游戏中,存储导致特定游戏状态的步骤可能比存储整个状态本身更有效。

例如,假设你正在制作一个国际象棋游戏,你可以通过保存步骤(e4,e5;f4,exf4;Bc4…)而不是棋盘中所有棋子的位置来保存棋盘状态。如果你的初始游戏状态是按程序生成的,你也可以在URL上保存游戏的初始种子。

这样,当servlet接收到具有特定URL的请求时,servlet可以通过从给定URL重新执行所有步骤来重新计算结束状态。

最新更新