瓦片地图注意事项

瓦片地图注意事项,第1张

概述瓦片地图(Tiled Map)系列文章: 斜45度瓦片地图(Staggered Tiled Map)里的简单数学 瓦片地图注意事项 承接上一篇文章,再来聊聊一些coding方面的tips: <!-- more --> TileMapAtlas、FastTMX和TMXTiledMap的选择 我们看到cocos2d-x提供了三个和TiledMap相关的类:TileMapAtlas、FastTMX和TM

瓦片地图(Tiled Map)系列文章:

斜45度瓦片地图(Staggered Tiled Map)里的简单数学

瓦片地图注意事项

承接上一篇文章,再来聊聊一些Coding方面的tips:

<!-- more -->

TileMapAtlasFastTMXTMXTiledMap的选择

我们看到cocos2d-x提供了三个和TiledMap相关的类:TileMapAtlasFastTMXTMXTiledMap,那么应该采用哪个类呢?

首先,TileMapAtlas官方不建议使用。

剩下的两个C++FastTMXTMXTiledMap,分别绑定到luaccexp.TMXTiledMapcc.TMXTiledMap。采用FastTMX的GL verts(顶点数)较少,可惜暂时不支持staggered类型。所以,staggered类型的Tiled Map只能用TMXTiledMap,其它类型的Tiled Map建议采用FastTMX

-- NOTE: FastTMX doesn't support staggered tmx-- ccexp.TMXTiledMap is faster,but the grID will not be displayed normallylocal map = cc.TMXTiledMap:create("xxx.tmx")
如何判断tile坐标超出地图区域

FastTMXTMXTiledMap提供了一个方法getMapSize(),需要注意的是这个函数和cocos2d-x其他getXXXSize的函数不同,返回的大小不是以像素值为单位,而是2D地图在两个维度的tile数目。

local function isTileInMap(map,tileCoord)    -- NOTE: mapSize is measured in tile number    local mapSize = map:getMapSize()    return (tileCoord.x >= 0)    and (tileCoord.x < mapSize.wIDth)    and (tileCoord.y >= 0)    and (tileCoord.y < mapSize.height)end
如何获取tile的标记

上一篇文章提到,对于不能放置在地图上禁止被编辑的区域,可以在相应的Tile做上标记。例如,我在Tiled Map里创建了一个叫"Meta"的图层:

在TileSet PropertIEs里设置一个标记"CollIDable",表示禁止被编辑:

接下来就是用这个TileSet来刷图啦!

那么我们如何在代码中获取这个标记呢?FastTMXTMXTiledMap提供了一个方法getPropertIEsForGID(GID)来获取GID所对应的tile的属性。

那么新的问题又来了,GID这个索引又如何获取呢?还有另一个函数getTileGIDAt(),传入的参数就是上次所讲的tile坐标啦!

现在你应该明白之前本渣为何要在那套坐标系下解决判断区域相交的问题了吧?

local function isValIDTile(map,tileCoord)    local MetaLayer = map:getLayer("Meta")    local flags = 0    local GID,flags = MetaLayer:getTileGIDAt(tileCoord,flags)    if not GID or GID <= 0 then        return true    end    local property = map:getPropertIEsForGID(GID)    if property and property["CollIDable"] then        return false    else        return true    endend
关于tile的坐标

上回提到Staggered Tiled Map的坐标系,其实这套坐标还和你的配置有关。本渣采用的配置是:

如果改变上述参数,那么你所得到的坐标也会不同,你不妨多试试啦~

另外,即使上述参数不变,但如果你需要由某一点的坐标求出它所在tile的坐标的话,还需要注意Tiled Map的Y轴tile数目(之所以是Y轴,是因为上面Staggered Axis设置为Y)的奇偶性。这里也不解释了,直接上图最直观:


'Y轴有奇数个tile(图中是五个),这里tile个数是这么算的:从最底端的tile沿斜线算与它有一条公共边的tile、一直算到最顶端的tile,例如从坐标(0,4)(0,3)(1,2)(1,1)到没有显示的(2,0)'


Y轴有偶数个tile(图中是六个)

更多Tiled Map PropertIEs配置

Tile Layer Format最好选择压缩的格式,这样生成的tmx文件比较小。

关于遮挡关系的排序函数

上一篇文章还提到建筑及装饰物之间的遮挡关系处理,本渣制定了一套规则来对建筑及装饰物做排序。需要注意的是,lua的table.sort要求排序函数是stable的,所以最好给每个要被比较的对象(这里就是建筑或装饰物)一个独一无二的ID,对于两者“相等”这种情况就定义为比较ID大小即可。

以下给出示例的伪代码,其中building就是被封装过的建筑或装饰物对象:

local function getlineOfBuildingRegion(building)    return {        left = building:getRegionleftPos(),right = building:getRegionRightPos(),}endlocal function getdistX(line)    return line.right.x - line.left.xendlocal function getLowerPoint(line)    if line.left.y < line.right.y then        return line.left    else        return line.right    endendlocal function getHigherPoint(line)    if line.left.y > line.right.y then        return line.left    else        return line.right    endendlocal function isPointEqual(posA,posB)    return posA.x == posB.x and posA.y == posB.yendlocal function islineEqual(lineA,lineB)    return isPointEqual(lineA.left,lineB.left) and isPointEqual(lineA.right,lineB.right)endlocal function getSlope(line)    return (line.right.y - line.left.y) / (line.right.x - line.left.x)endlocal function islineParallel(lineA,lineB)    return getSlope(lineA) == getSlope(lineB)endlocal function isLowerThanline(point,line)    local y = getSlope(line) * (point.x - line.left.x) + line.left.y    if point.y == y then        return y > getLowerPoint(line).y    else        return point.y < y    endendlocal function updateBuildingsZOrder(buildings)    table.sort(buildings,function(a,b)        if not isValIDBuilding(a) then            return false        elseif not isValIDBuilding(b) then            return true        end        local lineA = getlineOfBuildingRegion(a)        local lineB = getlineOfBuildingRegion(b)        if getdistX(lineA) > getdistX(lineB) then            return isLowerThanline(getLowerPoint(lineB),lineA)        elseif getdistX(lineA) == getdistX(lineB) then            if islineEqual(lineA,lineB) then                return a.ID < b.ID            elseif islineParallel(lineA,lineB) then                if getLowerPoint(lineA).y == getLowerPoint(lineB).y then                    return a.ID < b.ID                else                    return getLowerPoint(lineA).y > getLowerPoint(lineB).y                end            else                if getLowerPoint(lineA).y > getLowerPoint(lineB).y then                    return isLowerThanline(getLowerPoint(lineB),lineA)                elseif getLowerPoint(lineA).y == getLowerPoint(lineB).y then                    if getHigherPoint(lineA).y > getHigherPoint(lineB).y then                        return isLowerThanline(getLowerPoint(lineB),lineA)                    elseif getHigherPoint(lineA).y == getHigherPoint(lineB).y then                        return a.ID < b.ID                    else                        return not isLowerThanline(getLowerPoint(lineA),lineB)                    end                else                    return not isLowerThanline(getLowerPoint(lineA),lineB)                end            end        else            return not isLowerThanline(getLowerPoint(lineA),lineB)        end    end)    for i,building in ipairs(buildings) do        building:setLocalZOrder(i)    endend
总结

以上是内存溢出为你收集整理的瓦片地图注意事项全部内容,希望文章能够帮你解决瓦片地图注意事项所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/web/1081321.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-27
下一篇 2022-05-27

发表评论

登录后才能评论

评论列表(0条)

保存