Laya TileMap 系列二 如何在Laya中使用

參考用LayaAir引擎解析Tiled Map地圖
1.必須是CSV格式贾惦,不支持Tiled Map地圖為Base64的圖塊層格式叠荠。
2.導出為json格式

image.png

3.修改圖集路徑
打開剛剛保存的orthogonal.json匿沛,搜索關鍵字"image"我們會發(fā)現(xiàn)默認的image路徑位于Tiled安裝目錄中。如圖4所示榛鼎。
圖4

路徑在Tiled安裝目錄中肯定是不行的逃呼,所以,我們需要先將這個圖片(buch-outdoor.png)復制到項目目錄者娱,與之前保存的orthogonal.json同級抡笼,如圖5所示。
圖5

然后將orthogonal.json中的image路徑修改為相對路徑"image":"buch-outdoor.png"
但是我在做這一步時黄鳍,發(fā)現(xiàn)我的json文件中tileset指向的沒有image推姻,而是一個source:

 "tilesets":[
        {
         "firstgid":1,
         "source":"Tile01.tsx"
        }, 
        {
         "firstgid":561,
         "source":"Tile02.tsx"
        }

估計是新建圖塊時設置有問題,重新建圖塊框沟,如圖藏古,勾選嵌入地圖即可


image.png
{
 "columns":19,
 "firstgid":1209,
 "image":"..\/..\/tiled-windows-64bit-snapshot\/examples\/Tile03.PNG",
 "imageheight":480,
 "imagewidth":640,
 "margin":1,
 "name":"Tile03",
 "spacing":1,
 "tilecount":266,
 "tileheight":32,
 "tilewidth":32
}

4.創(chuàng)建TiledMap地圖


laya.map.TiledMap類中的createMap方法
//初始化舞臺
Laya.init(Laya.Browser.width, Laya.Browser.height, Laya.WebGL);
//創(chuàng)建TiledMap實例
var tMap = new Laya.TiledMap();
//創(chuàng)建Rectangle實例增炭,視口區(qū)域
var viewRect: Laya.Rectangle = new Laya.Rectangle
(0, 0, Laya.Browser.width, Laya.Browser.height);
//創(chuàng)建TiledMap地圖
tMap.createMap("res/TiledMap/orthogonal.json", viewRect, null);

5.縮放

通過動圖9-3,從原圖比例的0.1到2倍的縮放變化效果拧晕,來進一步理解scale屬性的中心點
在laya.map.TiledMap類中的setViewPortPivotByScale()方法可以設置視口的中心點
private tMap: Laya.TiledMap;
constructor() {
    //初始化舞臺
    Laya.init(Laya.Browser.width, Laya.Browser.height, Laya.WebGL);
    //創(chuàng)建TiledMap實例
    this.tMap = new Laya.TiledMap();
    //創(chuàng)建Rectangle實例隙姿,視口區(qū)域
    var viewRect: Laya.Rectangle = new Laya.Rectangle
        (0, 0, Laya.Browser.width, Laya.Browser.height);
    //創(chuàng)建TiledMap地圖
    this.tMap.createMap("res/TiledMap/orthogonal.json"
        , viewRect, Laya.Handler.create(this, this.onMapLoaded));
}
private onMapLoaded(): void {
    //設置縮放中心點為視口的左上角
    this.tMap.setViewPortPivotByScale(0, 0);
    //將原地圖放大2倍
    this.tMap.scale = 2;
}

6.拖動地圖,需要用到moveViewPort()(移動視口)方法和changeViewPort()(改變視口大谐Ю獭)方法

private tMap: Laya.TiledMap;
private MapX: number = 0;
private MapY: number = 0;
private mLastMouseX: number;
private mLastMouseY: number;

constructor() {
    //初始化舞臺
    Laya.init(Laya.Browser.width, Laya.Browser.height, Laya.WebGL);
    //創(chuàng)建TiledMap實例
    this.tMap = new Laya.TiledMap();
    //創(chuàng)建Rectangle實例输玷,視口區(qū)域
    var viewRect: Laya.Rectangle = new Laya.Rectangle
        (0, 0, Laya.Browser.width, Laya.Browser.height);
    //創(chuàng)建TiledMap地圖
    this.tMap.createMap("res/TiledMap/orthogonal.json"
        , viewRect, Laya.Handler.create(this, this.onMapLoaded));
}
private onMapLoaded(): void {
    //設置縮放中心點為視口的左上角
    this.tMap.setViewPortPivotByScale(0, 0);
    //將原地圖放大2倍
    this.tMap.scale = 2;

    Laya.stage.on(Laya.Event.RESIZE, this, this.resize);
    Laya.stage.on(Laya.Event.MOUSE_DOWN, this, this.mouseDown);
    Laya.stage.on(Laya.Event.MOUSE_UP, this, this.mouseUp);
    this.resize();
}
/**
 * 移動地圖視口
 */
private mouseMove(): void {
    var moveX: number = this.MapX - (Laya.stage.mouseX - this.mLastMouseX);
    var moveY: number = this.MapY - (Laya.stage.mouseY - this.mLastMouseY)
    //移動地圖視口
    this.tMap.moveViewPort(moveX, moveY);
}
private mouseUp(): void {
    this.MapX = this.MapX - (Laya.stage.mouseX - this.mLastMouseX);
    this.MapY = this.MapY - (Laya.stage.mouseY - this.mLastMouseY);
    Laya.stage.off(Laya.Event.MOUSE_MOVE, this, this.mouseMove);
}
private mouseDown(): void {
    this.mLastMouseX = Laya.stage.mouseX;
    this.mLastMouseY = Laya.stage.mouseY;
    Laya.stage.on(Laya.Event.MOUSE_MOVE, this, this.mouseMove);
}
/**
 *  改變視口大小
 *  重設地圖視口區(qū)域
 */
private resize(): void {
    //改變視口大小
    this.tMap.changeViewPort(this.MapX, this.MapY
        , Laya.Browser.width, Laya.Browser.height);
}

7.銷毀地圖
當Tiled Mapa不再使用的時候,需要使用destroy()方法進行銷毀靡馁,回收被占用的內(nèi)存欲鹏。tMap.destroy();

8.開啟和關閉自動緩存
LayaAir引擎使用TiledMap時,默認會將沒有動畫的地塊自動緩存起來臭墨,并且緩存類型默認為normal赔嚎。

//自動緩存沒有動畫的地塊
tMap.autoCache = true;
//自動緩存的類型,地圖較大時建議使用normal
tMap.autoCacheType = "normal";
//消除縮放導致的縫隙,也就是去黑邊,1.7.7版本新增的優(yōu)化屬性
tMap.antiCrack = true;

以上的代碼屬性是引擎的默認值裙犹,在多數(shù)情況下尽狠,保持默認值即可,無需額外設置叶圃。那么為什么要再介紹一遍呢袄膏?因為有的時候,緩存后的Tiled地圖會出現(xiàn)黑邊(縫隙)掺冠。盡管在1.7.7版本新增了antiCrack屬性沉馆,可以消除絕大多數(shù)因normal緩存導致的黑邊。但如果偶現(xiàn)的黑邊問題仍未得到解決時德崭〕夂冢可以通過關閉自動緩存來解決黑邊(縫隙)問題。

9.設置緩存區(qū)塊大小
TiledMap地圖都是由一個個單元區(qū)塊拼接組成眉厨。如果緩存時保持原大小锌奴,當小圖區(qū)塊很多時會對性能產(chǎn)生影響。因此建議開啟緩存區(qū)塊設置憾股,并將緩存區(qū)塊的大小設置為512像素左右鹿蜀,必須保持原小圖區(qū)塊的整數(shù)倍。
例如服球,本文示例中的單圖區(qū)塊大小為1616茴恰,那么緩存區(qū)塊可以設置 16的32倍,即為512512斩熊。如果單圖是1515往枣,緩存可區(qū)塊可以設置為510510(34倍),以此類推,盡量在原區(qū)塊整數(shù)倍的前提下分冈,設置在512左右圾另。推薦為512*512。

緩存區(qū)塊的設置需要在createMap(創(chuàng)建地圖)的時候設置丈秩。設置第四個參數(shù)gridSize盯捌,示例如下:

//為第二個參數(shù)創(chuàng)建Rectangle實例,視口區(qū)域
var viewRect:Rectangle = new Rectangle(0, 0, Browser.width, Browser.height);
//為第四個參數(shù)gridSize創(chuàng)建一個512*512大小的Point對象實例
var gridSize:Point = new Point(512, 512);
//創(chuàng)建TiledMap地圖
tMap.createMap("res/TiledMap/orthogonal.json"
,viewRect, Handler.create(this,onMapLoaded), null, gridSize)

10.開啟合并圖層
當TiledMap里有多個圖層時蘑秽,開啟合并圖層的屬性enableMergeLayer,可以將圖層合并箫攀,會對性能有所提高肠牲。開啟的方式為:tMap.enableMergeLayer = true;需要注意的是,如果需要對合并前的圖層進行操作靴跛,那就不能直接合并缀雳。因為合并后會導致無法對合并前的圖層進行操作。

如果沒有在TiledMap里將圖層分組梢睛,那么圖層合并時肥印,會將所有圖層合并到一起。因此绝葡,需要分為多個圖層并分別操作時深碱≡勘樱可以在TiledMap里將圖層分組牛哺。打開TiledMap地圖編輯器初厚,選中要分組的圖層谤饭,在圖層的自定義屬性欄攀芯,添加一個名為layer的string類型屬性择克。操作如圖14-1所示拳恋。

圖14-1

開啟合并圖層時终畅,圖層屬性內(nèi)可添加layer屬性榜旦,運行時將會將相鄰的layer屬性相同的圖層進行合并以提高性能幽七。例如,我們將塊層2與塊層3的分組名稱設置為layaAir溅呢,那么名為layaAir的圖層澡屡,開啟enableMergeLayer后,會合并到同一個圖層藕届。操作如圖14-2所示挪蹭。
圖14-2

11.移除被覆蓋的格子
如果下層的格子被遮擋,并且遮擋地塊并不是透明的休偶,那么被遮擋的部分直接移除而不被渲染梁厉,可以提高性能。移除被覆蓋的開啟方式為:tMap.removeCoveredTile = true;//移除被非透明地塊覆蓋的部分
Tips:如果開啟后,需要對移除的部分進行操作词顾,是不可能的八秃。所以開啟該功能前要確認,不再對移除部分進行操作肉盹。

如果在Tiled Map中沒有對圖塊設置type屬性昔驱,那么即便開啟了removeCoveredTile ,也是無效的上忍。所以骤肛,開啟之前,需要先在TiledMap編輯器中窍蓝,為圖塊新增自定義屬性type腋颠,并將設置為1。


在圖塊面板中吓笙,點擊圖塊編輯淑玫,打開圖塊地形編輯面板

在圖塊地形編輯面板內(nèi),選中地形面睛,在自定義屬性欄絮蒿,點擊+號圖標,添加int類型的type屬性

完成添加后叁鉴,設置type屬性值為1

只要是自定義屬性type設置為1的地形土涝,當removeCoveredTile開啟后。被遮擋不可見時都可以被移除亲茅,以提高性能回铛。

12.設置tiledMap寬高
參考分享:TiledMap設置viewport后黑屏問題!
tiledMap默認是沒有寬高的克锣,所以我們在設置viewport的時候茵肃,要為tiledMap設置一個寬高,否則tiledMap將可能會被裁剪掉

//切記:設置tiledMap的寬高袭祟,需要在地圖創(chuàng)建完成之后
private function onLoaded():void
{
    var sp:Sprite=tiledMap.mapSprite() as Sprite;
    //為tiledMap整個地圖的顯示容器設置寬高
    sp.size(800,800);
}

13.屏幕坐標和地圖坐標轉換
參考官方示例 等角地圖

private function onStageClick(e:*=null):void
{
    var p:Point = new Point(0, 0);
    layer.getTilePositionByScreenPos(Laya.stage.mouseX, Laya.stage.mouseY, p);
    layer.getScreenPositionByTilePos(Math.floor(p.x), Math.floor(p.y), p);
    sprite.pos(p.x, p.y);
}

private function mapLoaded(e:*=null):void
{
    layer = tiledMap.getLayerByIndex(0);
    
    var radiusX:Number = 32;
    var radiusY:Number = Math.tan(180 / Math.PI * 30) * radiusX;
    var color:String = "#FF7F50";
    
    sprite = new Sprite();
    sprite.graphics.drawLine(0, 0, -radiusX, radiusY, color);
    sprite.graphics.drawLine(0, 0, radiusX, radiusY, color);
    sprite.graphics.drawLine(-radiusX, radiusY, 0, radiusY * 2, color);
    sprite.graphics.drawLine(radiusX, radiusY, 0, radiusY * 2, color);
    Laya.stage.addChild(sprite);
}
效果就是有個紅框验残,鼠標點哪,紅框就在相應的圖塊里出現(xiàn)

參考一下這兩個方法源碼的API說明:

/**
 * 通過屏幕坐標來獲取選中格子的索引
 * @param   screenX 屏幕坐標x
 * @param   screenY 屏幕坐標y
 * @param   result 把計算好的格子坐標巾乳,放到此對象中
 * @return
 */
public function getTilePositionByScreenPos
(screenX:Number, screenY:Number, result:Point = null):Boolean {}

/**
 * 通過地圖坐標得到屏幕坐標
 * @param   tileX 格子坐標X
 * @param   tileY 格子坐標Y
 * @param   screenPos 把計算好的屏幕坐標數(shù)據(jù)您没,放到此對象中
 */
public function getScreenPositionByTilePos
(tileX:Number, tileY:Number, screenPos:Point = null):void {}

14.動畫

laya官方回復是,不支持Laya的ani動畫放置到tiledMap中胆绊,參考可以用laya的ani動畫系統(tǒng)動態(tài)插入到tiledmap的tiled中嗎

參考官方示例 帶動畫的地圖
Tiled地圖編輯器 Tiled Map Editor 的使用(二)動畫效果
在最新版本的tiled map editor中氨鹏,需要進入圖塊文件,然后在主菜單->Tile集->圖塊動畫編輯器

image.png

雙擊圖塊即可添加到左側压状,但是沒看懂怎么把添加上去的幀刪掉……
看一下tmx中對應的標簽:

   <animation>
    <frame tileid="30" duration="1000"/>
    <frame tileid="31" duration="2000"/>
    <frame tileid="38" duration="3000"/>
   </animation>

沒有看到Frame Duration:500ms在哪里仆抵,另外動畫的三幀跟继,也不是按1秒為間隔來播放的。第1幀的仙人掌镣丑,到第2幀的石頭特別快舔糖。
最終,導出的json是這樣的:

 "tiles":[
        {
         "id":29,
         "properties":[
                {
                 "name":"isCanPass",
                 "type":"bool",
                 "value":true
                }]
        }, 
        {
         "animation":[
                {
                 "duration":1000,
                 "tileid":30
                }, 
                {
                 "duration":2000,
                 "tileid":31
                }, 
                {
                 "duration":3000,
                 "tileid":38
                }],
         "id":31,
         "properties":[
                {
                 "name":"isCanPass",
                 "type":"bool",
                 "value":false
                }]
        }],

在TiledMap.as的源碼中莺匠,可以看到onJsonComplete中關于動畫的解析:

//動畫數(shù)據(jù)
var tTiles:* = tileset.tiles;
if (tTiles) {
    for (var p:*in tTiles) {
        var tAnimation:Array = tTiles[p].animation;
        if (tAnimation) {
            var tAniData:TileMapAniData = new TileMapAniData();
            _animationDic[p] = tAniData;
            tAniData.image = tileset.image;
            for (var j:int = 0; j < tAnimation.length; j++) {
                var tAnimationItem:Object = tAnimation[j];
                tAniData.mAniIdArray.push(tAnimationItem.tileid);
                tAniData.mDurationTimeArray.push(tAnimationItem.duration);
            }
        }
    }
}

class TileMapAniData {
    public var mAniIdArray:Array = [];
    public var mDurationTimeArray:Array = [];
    public var mTileTexSetArr:Array = [];
    public var image:*;
}

會把duration金吗、tileid存到TileMapAniData這個類型的相應數(shù)組里去,tAniData.image = tileset.image;取到的是"image":"tmw_desert_spacing.png"這個屬性趣竣。

/**
 * 初始化地圖
 */
private function initMap():void {
var i:int, n:int;
for (var p:*in _animationDic) {
var tAniData:TileMapAniData = _animationDic[p];
var gStart:int;
gStart = _texutreStartDic[tAniData.image];
var tTileTexSet:TileTexSet = getTexture(parseInt(p) + gStart);
if (tAniData.mAniIdArray.length > 0) {
    tTileTexSet.textureArray = [];
    tTileTexSet.durationTimeArray = tAniData.mDurationTimeArray;
    tTileTexSet.isAnimation = true;
    tTileTexSet.animationTotalTime = 0;
    for (i = 0, n = tTileTexSet.durationTimeArray.length; i < n; i++) {
        tTileTexSet.animationTotalTime += tTileTexSet.durationTimeArray[i];
    }
    for (i = 0, n = tAniData.mAniIdArray.length; i < n; i++) {
        var tTexture:TileTexSet = getTexture(tAniData.mAniIdArray[i] + gStart);
        tTileTexSet.textureArray.push(tTexture);
    }
}
}

在initMap中摇庙,把屬性都放到TileTexSet中。

/**
 * 加入一個動畫顯示對象到此動畫中
 * @param   aniName //顯示對象的名字
 * @param   sprite  //顯示對象
 */
public function addAniSprite(aniName:String, sprite:TileAniSprite):void {
    if (animationTotalTime == 0) {
        return;
    }
    if (_aniDic == null) {
        _aniDic = {};
    }
    if (_spriteNum == 0) {
        //每3幀刷新一下吧遥缕,每幀刷新可能太耗了
        Laya.timer.frameLoop(3, this, animate);
        _preFrameTime = Browser.now();
        _frameIndex = 0;
        _time = 0;
        _interval = 0;
    }
    _spriteNum++;
    _aniDic[aniName] = sprite;
    if (textureArray && _frameIndex < textureArray.length) {
        var tTileTextureSet:TileTexSet = textureArray[_frameIndex];
        drawTexture(sprite, tTileTextureSet);
    }
}
/**
 * 把動畫畫到所有注冊的SPRITE上
 */
private function animate():void {
    if (textureArray && textureArray.length > 0 && 
        durationTimeArray && durationTimeArray.length > 0) {
        var tNow:Number = Browser.now();
        _interval = tNow - _preFrameTime;
        _preFrameTime = tNow;
        if (_interval > animationTotalTime) {
            _interval = _interval % animationTotalTime;
        }
        _time += _interval;
        var tTime:int = durationTimeArray[_frameIndex];
        while (_time > tTime) {
            _time -= tTime;
            _frameIndex++;
            if (_frameIndex >= durationTimeArray.length ||
                       _frameIndex >= textureArray.length) {
                _frameIndex = 0;
            }
            var tTileTextureSet:TileTexSet = textureArray[_frameIndex];
            var tSprite:TileAniSprite;
            for (var p:* in _aniDic) {
                tSprite = _aniDic[p];
                drawTexture(tSprite, tTileTextureSet);
            }
            tTime = durationTimeArray[_frameIndex];
        }
    }
}

可以看出跟匆,每3幀會刷新一下animate方法。相當于不停地去檢查_interval通砍,然后累加到_time變量上。然后把_time一直和durationTimeArray數(shù)組中的時間戳去比較烤蜕,如果達到了封孙,就進入while循環(huán)更新一下幀圖片。
在while循環(huán)中讽营,會把_time減掉這個時間戳虎忌,并且會把時間戳更新到下一個節(jié)點。這樣就明確了橱鹏,durationTimeArray這個數(shù)組中的值膜蠢,確實是時間的間隔,而不是時間軸莉兰。上面導出的資源挑围,間隔是1000,2000糖荒,3000杉辙。這就意味著動畫間隔越來越長。如果需要每秒切換1幀捶朵,都改成1000即可蜘矢。

但是,當前版本下综看,laya仍然播放不出動畫品腹。經(jīng)過代碼檢查,應該是版本不匹配導致的红碑。在TiledMap中的onJsonComplete方法中舞吭,_animationDic[p] = tAniData;是有問題的,因為現(xiàn)在的導出數(shù)據(jù)是這樣的:

         "tiles":[
                {
                 "animation":[
                        {
                         "duration":1000,
                         "tileid":30
                        }, 
                        {
                         "duration":1000,
                         "tileid":31
                        }, 
                        {
                         "duration":1000,
                         "tileid":38
                        }],
                 "id":31
                }],

可以看到,現(xiàn)在的p實際上是0镣典,真正的值是存在了與animation同級的id屬性上兔毙,所以改成這樣,_animationDic[tTiles[p].id] = tAniData;兄春,就能運行了:

//動畫數(shù)據(jù)
var tTiles:* = tileset.tiles;
if (tTiles) {
    for (var p:*in tTiles) {
        var tAnimation:Array = tTiles[p].animation;
        if (tAnimation) {
            var tAniData:TileMapAniData = new TileMapAniData();
            //_animationDic[p] = tAniData;
            _animationDic[tTiles[p].id] = tAniData;
            tAniData.image = tileset.image;
            for (var j:int = 0; j < tAnimation.length; j++) {
                var tAnimationItem:Object = tAnimation[j];
                tAniData.mAniIdArray.push(tAnimationItem.tileid);
                tAniData.mDurationTimeArray.push(tAnimationItem.duration);
            }
        }
    }
}

15.圖塊的自定義屬性訪問澎剥,截止到2018.5.16號,當前1.78.beta版本仍然是錯的赶舆,關于動畫的操縱也需要關注
參考TiledMap格子上的自定義數(shù)據(jù)問題

都2018年了哑姚,TS依然沒有這個接口。
我用ts直接objdata.properties["R"]來讀取芜茵。直接F5調(diào)試勉強可以用叙量。
發(fā)布重新編譯ts會報錯。希望能盡快提供直接訪問的方法九串。
需要:
1 枚舉圖層的全部成員绞佩。我現(xiàn)在直接用Layer._objDic來強行讀取的。
2 getObjectDataByName("").type 也需要訪問猪钮。
3 getObjectDataByName().properties需要公開訪問品山。
4 tiledMap的動畫貌似跟Laya的動畫實現(xiàn)方法不一樣。不知如何Stop.如何替換烤低。比如肘交,我想實現(xiàn)一個人物奔跑到停止,轉身扑馁,巡邏涯呻。求演示。目前我是用Laya.Animation做的動畫腻要,找到目標GridSprite然后addChild實現(xiàn)的复罐。把原有的GridSprite的成員移除,它會再回來闯第。只好用透明圖占位市栗。我總覺得這種方法不科學。求更科學的套路咳短。

首先填帽,來看看訪問自定義屬性的調(diào)用API

/**
 * 得到tile自定義屬性
 * @param   index       地圖塊索引
 * @param   id          具體的TileSetID
 * @param   name        屬性名稱
 * @return
 */
public function getTileProperties(index:int, id:int, name:String):* {
    if (_tileProperties[index] && _tileProperties[index][id]) {
        return _tileProperties[index][id][name];
    }
    return null;
}

第一個參數(shù),地圖塊索引咙好,注釋寫得并不清楚篡腌,根據(jù)導出的json和相關代碼來觀察,指的是在json導出的tilesets數(shù)組中勾效,占的索引嘹悼,當然是從0開始的叛甫。


這個順序在原始的tmx中也能看出來

也就是說,要獲取一個格子tile的自定義屬性杨伙,首先要知道它是屬于哪個地塊的其监。

第二個參數(shù),就是具體的TileSetID限匣,當然如前文所述抖苦,這個ID并不是從1開始的,而是從0開始米死。而layers保存的data卻是從1開始的锌历,所以如果是點擊地塊,去獲取相應的自定義屬性峦筒,注意需要減1究西。

第三個參數(shù)是自定義屬性的名稱,根據(jù)這個key返回value值物喷。

那么我們看一下json中保存自定義屬性的部分:

 "tilesets":[
        {
        ...
        "tiles":[
                {
                 "id":29,
                 "properties":[
                        {
                         "name":"isCanPass",
                         "type":"bool",
                         "value":true
                        }, 
                        {
                         "name":"tileType",
                         "type":"int",
                         "value":1
                        }]
                }, 
                {
                 "animation":[
                        {
                         "duration":1000,
                         "tileid":30
                        }, 
                        {
                         "duration":1000,
                         "tileid":31
                        }, 
                        {
                         "duration":1000,
                         "tileid":38
                        }],
                 "id":31
                }, 
                {
                 "id":39,
                 "properties":[
                        {
                         "name":"isCanPass",
                         "type":"bool",
                         "value":false
                        }]
                }],
        ...

這里以構建第一個圖塊的自定義數(shù)據(jù)為例卤材,根據(jù)return _tileProperties[index][id][name];,構建數(shù)據(jù)結構如下:

_tileProperties = {};
_tileProperties[0] = {};
_tileProperties[0] = {};

_tileProperties[0][29] = {};
_tileProperties[0][29]["isCanPass"] = true;
_tileProperties[0][29]["tileType"] = 1;

_tileProperties[0][39] = {};
_tileProperties[0][39]["isCanPass"] = false;

在onJsonComplete方法中峦失,我們發(fā)現(xiàn)因為版本問題商膊,代碼并不是這樣去構建數(shù)據(jù)結構的。

var tArray:Array = tJsonData.tilesets;
var tileset:*;
var tTileSet:TileSet;
var i:int = 0;
for (i = 0; i < tArray.length; i++) {
    tileset = tArray[i];
    tTileSet = new TileSet();
    tTileSet.init(tileset);
    
    if (tTileSet.properties && tTileSet.properties.ignore) continue;
        _tileProperties[i] = tTileSet.tileproperties;

上面的i確實是從0開始循環(huán)的宠进,代表著獲取方法中getTileProperties第一個參數(shù)。但是它指向的內(nèi)容是錯誤的,在TileSet的init方法中藐翎,只是簡單粗暴地一句話處理:

//自定義屬性
tileproperties = data.tileproperties;

可是現(xiàn)在的版本里材蹬,json里沒有tileproperties。我們可以模仿解析動畫animation的代碼來寫:

var tTiles:* = tileset.tiles;
if (tTiles) {
    for (var p:*in tTiles) {
        var tAnimation:Array = tTiles[p].animation;
        if (tAnimation) {
            var tAniData:TileMapAniData = new TileMapAniData();
            //_animationDic[p] = tAniData;這一句也改了吝镣,見上面動畫部分
            _animationDic[tTiles[p].id] = tAniData;
            tAniData.image = tileset.image;
            for (var j:int = 0; j < tAnimation.length; j++) {
                var tAnimationItem:Object = tAnimation[j];
                tAniData.mAniIdArray.push(tAnimationItem.tileid);
                tAniData.mDurationTimeArray.push(tAnimationItem.duration);
            }
        }
        //下面這部分是我自己添加的:
        //檢查tiles中堤器,有properties屬性的object
        var properties:Array = tTiles[p].properties;
        if(properties){
            //構造_tileProperties[0][29] = {};
            _tileProperties[i][tTiles[p].id] = {};
            //把properties中的屬性都放進去
            for (var k:int = 0; k < properties.length; j++) {
                _tileProperties[i][tTiles[p].id][properties[k].name] 
                                = properties[k].value;
            }
        }
    }
}

js版本的代碼如下:

//檢查tiles中,有properties屬性的object
var properties = tTiles[p].properties;
if(properties){
    //構造_tileProperties[0][29] = {};
    this._tileProperties[i][tTiles[p].id] = {};
    //把properties中的屬性都放進去
    for (var k = 0; k < properties.length; k++) {
        this._tileProperties[i][tTiles[p].id][properties[k].name] 
                = properties[k].value;
    }
}

當然在這段 代碼前末贾,要先把_tileProperties[i]給初始化:

// this._tileProperties[i]=tTileSet.tileproperties;
this._tileProperties[i]={};

使用以下代碼測試一下闸溃,發(fā)現(xiàn)成功了:

console.log("test:",this.tMap.getTileProperties(0,29,"isCanPass"));//test:true
console.log("test:",this.tMap.getTileProperties(0,39,"isCanPass"));//test:false

16.如何隱藏tiledMap中指定的GridSprite

17._showGridList
參考tiledmap 可以在圖塊層的指定格子上添加Sprite嗎
LayaAir能做RPG嗎?不要問我能不能拱撵,因為我已經(jīng)在做 - 殺意來襲

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末辉川,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子拴测,更是在濱河造成了極大的恐慌乓旗,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,546評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件集索,死亡現(xiàn)場離奇詭異屿愚,居然都是意外死亡汇跨,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,224評論 3 395
  • 文/潘曉璐 我一進店門妆距,熙熙樓的掌柜王于貴愁眉苦臉地迎上來穷遂,“玉大人,你說我怎么就攤上這事娱据◎胶冢” “怎么了?”我有些...
    開封第一講書人閱讀 164,911評論 0 354
  • 文/不壞的土叔 我叫張陵吸耿,是天一觀的道長祠锣。 經(jīng)常有香客問我,道長咽安,這世上最難降的妖魔是什么伴网? 我笑而不...
    開封第一講書人閱讀 58,737評論 1 294
  • 正文 為了忘掉前任,我火速辦了婚禮妆棒,結果婚禮上澡腾,老公的妹妹穿的比我還像新娘。我一直安慰自己糕珊,他們只是感情好动分,可當我...
    茶點故事閱讀 67,753評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著红选,像睡著了一般澜公。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上喇肋,一...
    開封第一講書人閱讀 51,598評論 1 305
  • 那天坟乾,我揣著相機與錄音,去河邊找鬼蝶防。 笑死甚侣,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的间学。 我是一名探鬼主播殷费,決...
    沈念sama閱讀 40,338評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼低葫!你這毒婦竟也來了详羡?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 39,249評論 0 276
  • 序言:老撾萬榮一對情侶失蹤嘿悬,失蹤者是張志新(化名)和其女友劉穎殷绍,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體鹊漠,經(jīng)...
    沈念sama閱讀 45,696評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡主到,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,888評論 3 336
  • 正文 我和宋清朗相戀三年茶行,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片登钥。...
    茶點故事閱讀 40,013評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡畔师,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出牧牢,到底是詐尸還是另有隱情看锉,我是刑警寧澤,帶...
    沈念sama閱讀 35,731評論 5 346
  • 正文 年R本政府宣布塔鳍,位于F島的核電站伯铣,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏轮纫。R本人自食惡果不足惜腔寡,卻給世界環(huán)境...
    茶點故事閱讀 41,348評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望掌唾。 院中可真熱鬧放前,春花似錦、人聲如沸糯彬。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,929評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽撩扒。三九已至似扔,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間搓谆,已是汗流浹背虫几。 一陣腳步聲響...
    開封第一講書人閱讀 33,048評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留挽拔,地道東北人。 一個月前我還...
    沈念sama閱讀 48,203評論 3 370
  • 正文 我出身青樓但校,卻偏偏與公主長得像螃诅,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子状囱,可洞房花燭夜當晚...
    茶點故事閱讀 44,960評論 2 355

推薦閱讀更多精彩內(nèi)容