更新:我现在已经解决了我的主要问题,所以我将奖励赏金,以评估我的解决方案是否是好的风格。
最近我一直在尝试解析TMX文件,它们是描述地图的 XML 文件。格式中一个有趣的地方是您可以指定外部图块集。
由于它已经处理了大部分工作,我一直在尝试扩展htiled
库,以便它处理外部图块集,但到目前为止还没有成功。
所以基本上,我在这里要完成的任务是,给定两个文件map.tmx
:
<?xml version="1.0" encoding="UTF-8"?>
<map version="1.0" orientation="orthogonal" width="12" height="12" tilewidth="64" tileheight="64">
<tileset firstgid="1" source="ground.tsx"/>
...
</map>
和ground.tsx
:
<?xml version="1.0" encoding="UTF-8"?>
<tileset name="ground" tilewidth="64" tileheight="64" spacing="32">
<image source="ground.png" width="64" height="64"/>
<tile id="0">
<properties>
<property name="sol" value=""/>
</properties>
</tile>
</tileset>
返回结构:
Map {..., tilesets = [Tileset { name = "ground", ...}]}
解析(仅限内部)图块集的工作方法是:
tilesets ∷ IOSArrow XmlTree [Tileset]
tilesets = listA tileset
tileset ∷ IOSArrow XmlTree Tileset
tileset = isElem >>> hasName "tileset" >>> proc ts → do
tsName ← getAttrValue "name" ⤙ ts
tsInitialGid ← getAttrR "firstgid" ⤙ ts
tsTileWidth ← getAttrR "tilewidth" ⤙ ts
tsTileHeight ← getAttrR "tileheight" ⤙ ts
tsMargin ← arr (fromMaybe 0) . getAttrMaybe "margin" ⤙ ts
tsSpacing ← arr (fromMaybe 0) . getAttrMaybe "spacing" ⤙ ts
tsImages ← images ⤙ ts
tsTileProperties ← listA tileProperties ⤙ ts
returnA ⤙ Tileset {..}
where tileProperties ∷ IOSArrow XmlTree (Word32, Properties)
tileProperties = getChildren >>> isElem >>> hasName "tile"
>>> getAttrR "id" &&& properties
images = listA (getChildren >>> image)
我尝试调整该tilesets
方法,使其根据当前元素的source
属性使用当前元素或外部文档,但无济于事:
tilesets ∷ IOSArrow XmlTree [Tileset]
tilesets = listA $ proc ts → do
source ← isElem >>> hasName "tileset" >>> getAttrValue "source" ⤙ ts
case source of
"" → tileset ⤙ ts
f → tileset ⤙ readDocument [withValidate no, withWarnings yes] f
(这是我的许多尝试之一)。
通常我会到达一个点,GHC 告诉我我没有使用箭头命令,或者我的值在箭头内,而它不应该。我知道我不能以类型安全的方式透明地执行 IO(也许还有 XHT 中间操作?),但我被困在这里。我真的不确定如何进行。