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

时间:2012-09-14 14:00:33

标签: javascript compression

背景

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

我的想法是将级别数据存储在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)似乎对网址的长度有限制。

问题

Javascript中有更好的方法来存储我的游戏数据(即哪个会导致更短的URI)?

4 个答案:

答案 0 :(得分:3)

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

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

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

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

答案 1 :(得分:3)

我做了类似的事情,我使用JSON数据对GAE进行POST,并使用生成的密钥将其存储在数据存储区中,并根据该密钥返回一个URL供用户共享。

所以你发表了JSON数据。您将该数据存储在以下对象中:

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

key是自动生成的int。然后,您向用户返回一个网址:http://www.mygameurl.com/games?id=1234,其ID与生成的key相对应。然后,您可以让用户共享该URL以从数据存储区返回游戏数据。它缩短了用户共享的网址,并防止他们弄乱网址并破坏游戏数据。

答案 2 :(得分:1)

您可以将游戏存储在sql数据库中,并将该URL指向数据库中的ID以加载它。

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

答案 3 :(得分:1)

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

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

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