Android访问瓦片地图 费流量,瓦片地图注意事项
瓦片地圖(Tiled Map)系列文章:
承接上一篇文章,再來聊聊一些coding方面的tips:
TileMapAtlas、FastTMX和TMXTiledMap的選擇
我們看到cocos2d-x提供了三個(gè)和TiledMap相關(guān)的類:TileMapAtlas、FastTMX和TMXTiledMap,那么應(yīng)該采用哪個(gè)類呢?
首先,TileMapAtlas官方不建議使用。
剩下的兩個(gè)C++類FastTMX和TMXTiledMap,分別綁定到lua的ccexp.TMXTiledMap和cc.TMXTiledMap。采用FastTMX的GL verts(頂點(diǎn)數(shù))較少,可惜暫時(shí)不支持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 normally
local map = cc.TMXTiledMap:create("xxx.tmx")
如何判斷tile坐標(biāo)超出地圖區(qū)域
FastTMX和TMXTiledMap提供了一個(gè)方法getMapSize(),需要注意的是這個(gè)函數(shù)和cocos2d-x其他getXXXSize的函數(shù)不同,返回的大小不是以像素值為單位,而是2D地圖在兩個(gè)維度的tile數(shù)目。
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的標(biāo)記
上一篇文章提到,對(duì)于不能放置在地圖上禁止被編輯的區(qū)域,可以在相應(yīng)的Tile做上標(biāo)記。例如,我在Tiled Map里創(chuàng)建了一個(gè)叫"meta"的圖層:
在TileSet Properties里設(shè)置一個(gè)標(biāo)記"Collidable",表示禁止被編輯:
接下來就是用這個(gè)TileSet來刷圖啦!
那么我們?nèi)绾卧诖a中獲取這個(gè)標(biāo)記呢?FastTMX和TMXTiledMap提供了一個(gè)方法getPropertiesForGID(GID)來獲取GID所對(duì)應(yīng)的tile的屬性。
那么新的問題又來了,GID這個(gè)索引又如何獲取呢?還有另一個(gè)函數(shù)getTileGIDAt(),傳入的參數(shù)就是上次所講的tile坐標(biāo)啦!
現(xiàn)在你應(yīng)該明白之前本渣為何要在那套坐標(biāo)系下解決判斷區(qū)域相交的問題了吧?
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
end
end
關(guān)于tile的坐標(biāo)
上回提到Staggered Tiled Map的坐標(biāo)系,其實(shí)這套坐標(biāo)還和你的配置有關(guān)。本渣采用的配置是:
如果改變上述參數(shù),那么你所得到的坐標(biāo)也會(huì)不同,你不妨多試試?yán)?#xff5e;
另外,即使上述參數(shù)不變,但如果你需要由某一點(diǎn)的坐標(biāo)求出它所在tile的坐標(biāo)的話,還需要注意Tiled Map的Y軸tile數(shù)目(之所以是Y軸,是因?yàn)樯厦鍿taggered Axis設(shè)置為Y)的奇偶性。這里也不解釋了,直接上圖最直觀:
'Y軸有奇數(shù)個(gè)tile(圖中是五個(gè)),這里tile個(gè)數(shù)是這么算的:從最底端的tile沿斜線算與它有一條公共邊的tile、一直算到最頂端的tile,例如從坐標(biāo)(0, 4)(0, 3)(1, 2)(1, 1)到?jīng)]有顯示的(2, 0)'
Y軸有偶數(shù)個(gè)tile(圖中是六個(gè))
更多Tiled Map Properties配置
Tile Layer Format最好選擇壓縮的格式,這樣生成的tmx文件比較小。
關(guān)于遮擋關(guān)系的排序函數(shù)
上一篇文章還提到建筑及裝飾物之間的遮擋關(guān)系處理,本渣制定了一套規(guī)則來對(duì)建筑及裝飾物做排序。需要注意的是,lua的table.sort要求排序函數(shù)是stable的,所以最好給每個(gè)要被比較的對(duì)象(這里就是建筑或裝飾物)一個(gè)獨(dú)一無二的id,對(duì)于兩者“相等”這種情況就定義為比較id大小即可。
以下給出示例的偽代碼,其中building就是被封裝過的建筑或裝飾物對(duì)象:
local function getLineOfBuildingRegion(building)
return {
left = building:getRegionLeftPos(),
right = building:getRegionRightPos(),
}
end
local function getDistX(line)
return line.right.x - line.left.x
end
local function getLowerPoint(line)
if line.left.y < line.right.y then
return line.left
else
return line.right
end
end
local function getHigherPoint(line)
if line.left.y > line.right.y then
return line.left
else
return line.right
end
end
local function isPointEqual(posA, posB)
return posA.x == posB.x and posA.y == posB.y
end
local function isLineEqual(lineA, lineB)
return isPointEqual(lineA.left, lineB.left) and isPointEqual(lineA.right, lineB.right)
end
local function getSlope(line)
return (line.right.y - line.left.y) / (line.right.x - line.left.x)
end
local function isLineParallel(lineA, lineB)
return getSlope(lineA) == getSlope(lineB)
end
local 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
end
end
local 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)
end
end
總結(jié)
以上是生活随笔為你收集整理的Android访问瓦片地图 费流量,瓦片地图注意事项的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: android升级功能键,Android
- 下一篇: android camera入门,and