我在从.tmx(Tiled)文件中提取图层内容时遇到问题。 我希望在PHP中获得完整的未压缩数据,并对其进行一些描述。 获取宽度,高度等标题信息是没有问题的 - SimpleXML正在那里完成它的工作。但不知何故,瓦片层的解压缩无法正常工作。
数据本身存储为base64和gzip编码的字符串(类似于H4sIAAAAAAAAC+3bORKAIBQEUVzuf2YTTSwEA/gL00EnJvJQsAjcSyk7EU3v+Jn3OI
)但是我甚至在获取base64解码的代码时遇到了问题(它只是给了我很奇怪的字符,当我在平铺中重新打开地图时并将其保存为“base64 uncompressed”,结果只是一个空字符串 - not 当然使用gzip解压缩。)
我已经在网上搜索了一下,看看数据是如何精确压缩的(Github article)。好像我必须使用gzinflate()
命令而不是所有其他命令(例如gzuncompress),但这对我来说也不起作用。
我现在的代码如下:
<?php
// Get the raw xml data
$map_xml = new SimpleXML(file_get_contents("map.tmx"));
$data = $map_xml["layer"][0]["data"]["@content"]; // I would make a loop here
$content =gzinflate(base64_decode($map_content)); // gives me and error
var_dump($data); // results in nothing
?>
经过一些研究后,我发现我应该使用zlib过滤器(php.net article)。 现在我真的很困惑我不知道应该选择什么 - 我再次询问谷歌并得到以下内容:Compressing with Java Decompressing with PHP。根据答案,我必须在使用base64和gzip方法之前裁剪标题。
现在我的问题:我之前是否需要裁剪标题?如果是的话,我该怎么做? 如果没有,那我怎么才能得到未压缩的数据?
我真的希望有人可以帮助我!
答案 0 :(得分:4)
如前所述,Php的gzinflate和gzuncompress错误地命名。但是,我们可以利用接受原始压缩数据的gzinflate。 gzip头是10个字节长,可以使用substr去掉。使用上面的示例我尝试了这个:
$base64content = "H4sIAAAAAAAAC+3bORKAIBQEUVzuf2YTTSwEA/gL00EnJvJQsAjcSyk7EU3v+Jn3OI";
$compressed = substr( base64_decode($base64content), 10);
$content = gzinflate($compressed);
这为您提供了一个表示原始数据的字符串。你的TMX层主要由gid 0,2和3组成,因此如果打印出来,你只会看到空格。要获得有用的数据,您需要调用角色ord:
$chars = str_split($content);
$values = array();
foreach($chars as $char) {
$values[] = ord($char);
}
var_dump( implode(',', $values) ); // This gives you the equivalent of saving your TMX file with tile data stored as csv
希望有所帮助。
答案 1 :(得分:2)
您可能会遇到或能够制作三种格式。他们是:
.gz
。 PHP函数gzdeflate()
和gzinflate()
创建并解码原始deflate格式。 PHP函数gzcompress()
和gzuncompress()
创建并解码zlib格式。这些函数的无名称中应该包含“gz”,因为它们的 none 处理gzip格式!对于试图创建或解码gzip格式数据的PHP编码器来说,这将永远令人困惑。
似乎(但文档不清楚,如果它们总是在那里)PHP函数gzencode()
和gzdecode()
,如果我正确阅读简洁文档,默认情况下创建和解码gzip格式。 gzencode()
还可以选择生成zlib格式,我怀疑gzdecode()
会尝试自动检测gzip或zlib格式并进行相应的解码。 (这是所有这些函数都使用的实际zlib library的一部分功能。)
zlib_encode()
和zlib_decode()
的文档不完整(这些页面承认:“此函数目前未记录;只有其参数列表可用”),因此很难说出它们是什么做。 encoding
有一个未记录的zlib_encode()
字符串参数,如果您知道要在字符串中放入什么,可能会允许您选择三种格式中的一种。 encoding
没有zlib_decode()
参数,因此可能尝试在三种格式中自动检测。
答案 2 :(得分:1)
我知道现在已经老了,但我真的花了一整天玩这段代码。
对我的所作所为非常挑剔。但是,这是一个快速功能,可以将TMX文件转换为每个图层上每个图块的ID数组。
其他答复的人会去帮助我在错误的地方拼凑起来。
<?php
function getLayer($getLayerName = '')
{
$xml = simplexml_load_file('level.tmx');
$values = array();
foreach($xml->layer as $child)
{
$name = $child->attributes()->name;
if(!empty($getLayerName))
if($name != $getLayerName)
continue;
$data = gzinflate(substr(base64_decode(trim($child->data)), 10));
$chars = str_split($data);
$i = 0;
foreach($chars as $char)
{
$charID = ord($char);
if($i % 4 == 0) // I'm only interested in the tile IDs
{
$values[(String) $name][] = $charID;
}
$i++;
}
}
return $values;
}
print_r(getLayer());
//or you could use getLayer('LayerName') to get a single layer!
?>
在我的示例3x3地图上,只有一个平铺图像,我得到以下内容:
Array
(
[floor] => Array
(
[0] => 1
[1] => 1
[2] => 1
[3] => 1
[4] => 1
[5] => 1
[6] => 1
[7] => 1
[8] => 1
)
[layer2] => Array
(
[0] => 0
[1] => 0
[2] => 1
[3] => 0
[4] => 1
[5] => 0
[6] => 1
[7] => 1
[8] => 0
)
)
希望这个功能对于那些需要它的人来说非常方便。