以前玩過的遊戲中,總會有不能穿過去的部分,像是房屋的外牆,現在我們編寫的角色居然可以穿過任何的地方,這不太對吧,所以本章是要示範怎樣增加一些阻礙。
開始
首先,我先講一下我們打算要怎麼作。
對於不能穿過去的部分,我們要給他一個標示,這標示會使用tiled的圖片去標,但因為那只是一個標示,所以不需要什麼精美的圖案,只要一個色塊就好。然後,對於每一種色塊,我們會給他一個屬性,這讓我們可以透過code去搜尋,找出有該屬性的方塊,然後對他施加一些方法,讓角色無法穿過去。
把下載的檔案裡面另一份png檔mate_tiles.png載入吧,你會看到紅色和綠色的色塊,紅色的是用來標示不能穿越的部分,你或許會問,那綠色的呢?問的好,這是等一下要用的,表示你可以拾取的部分。
這時我們會在tilemap裡面新增一個層,取名叫做Meta,這一層專門放這些色塊,你可以把色塊重疊在地圖上面,如果你看不到色塊顯示在你的地圖上,請確定Meta層是在最上層。
你可以看一下Meta和Background和Objects三個層彼此的順序,所謂的最上層,表示該層的名稱顯示在最上面,你可以點選欲置於最上方的層,然後用該視窗下面一排的上下箭頭去移動。
好了之後,右鍵點選紅色方塊,會看到可以設定屬性,進去,名稱就輸入Collidable,值的部分就輸入True。
好,儲存吧!
CCTMXLayer *_meta;
然後在下方增加一個特性:
@property (nonatomic, retain) CCTMXLayer *meta;
再到HelloWorldLayer.m裡面去實作,並加入以下方法:
在實作檔一開始加入:
@synthesize meta = _meta;在dealloc裡面增加:
self.meta = nil;在init方法裡面,於載入背景圖片後增加:
- (CGPoint)tileCoordForPosition:(CGPoint)position {int x = position.x / _tileMap.tileSize.width;int y = ((_tileMap.mapSize.height * _tileMap.tileSize.height) - position.y) / _tileMap.tileSize.height;return ccp(x, y);
}self.meta = [_tileMap layerNamed:@"Meta"];
_meta.visible = NO;添加這個新方法:
應該都很簡單吧?我就解釋一下新方法的內涵好了。
首先,他取出position的x座標,然後除上構成tile地圖的方塊的寬度,這可以得到x是落在第幾個方塊裡面。
然後再把整個地圖的高度(y方向的長度)減去position的y座標,然後除上構成tile地圖的方塊的長度,這會得到y是落在第幾個方塊裡面。
但注意y的計算法,這表示原點落在左上方!
然後我們把setPlayerPosition替換成下面的內容:
CGPoint tileCoord = [self tileCoordForPosition:position];int tileGid = [_meta tileGIDAt:tileCoord];if (tileGid) {
NSDictionary *properties = [_tileMap propertiesForGID:tileGid];if (properties) {
NSString *collision = [properties valueForKey:@"Collidable"];if (collision && [collision compare:@"True"] == NSOrderedSame) {return;
}
}
}
_player.position = position;
這邊也要稍微解釋一下。首先他把做為參數的position轉換成他是在哪一個方塊裡面,然後透過這個值在meta之中找到該方塊的識別碼GID,然後使用if迴圈,如果該方塊GID碼有找到,那就去tileMap找到這個方塊的屬性(property),然後if迴圈判斷是否為空,如果有找到,由名為Collidable的key取出一個字串collision,並且測試collision和collision是否為True,如果如此,就返回,然後什麼也不作,自然也沒有把player的位置設置在position上了。
運行一下吧,我想,player應該無法再如同鬼魅一樣穿牆了。
開始
首先,我先講一下我們打算要怎麼作。
對於不能穿過去的部分,我們要給他一個標示,這標示會使用tiled的圖片去標,但因為那只是一個標示,所以不需要什麼精美的圖案,只要一個色塊就好。然後,對於每一種色塊,我們會給他一個屬性,這讓我們可以透過code去搜尋,找出有該屬性的方塊,然後對他施加一些方法,讓角色無法穿過去。
把下載的檔案裡面另一份png檔mate_tiles.png載入吧,你會看到紅色和綠色的色塊,紅色的是用來標示不能穿越的部分,你或許會問,那綠色的呢?問的好,這是等一下要用的,表示你可以拾取的部分。
這時我們會在tilemap裡面新增一個層,取名叫做Meta,這一層專門放這些色塊,你可以把色塊重疊在地圖上面,如果你看不到色塊顯示在你的地圖上,請確定Meta層是在最上層。
你可以看一下Meta和Background和Objects三個層彼此的順序,所謂的最上層,表示該層的名稱顯示在最上面,你可以點選欲置於最上方的層,然後用該視窗下面一排的上下箭頭去移動。
好了之後,右鍵點選紅色方塊,會看到可以設定屬性,進去,名稱就輸入Collidable,值的部分就輸入True。
好,儲存吧!
設定搜尋命名為Collidable的方塊
再來要去設定,讓你的程式會去搜尋命名為Collidable的方塊,首先在HelloWorldLayer.h裡面增加一個變數:CCTMXLayer *_meta;
然後在下方增加一個特性:
@property (nonatomic, retain) CCTMXLayer *meta;
再到HelloWorldLayer.m裡面去實作,並加入以下方法:
在實作檔一開始加入:
@synthesize meta = _meta;在dealloc裡面增加:
self.meta = nil;在init方法裡面,於載入背景圖片後增加:
- (CGPoint)tileCoordForPosition:(CGPoint)position {int x = position.x / _tileMap.tileSize.width;int y = ((_tileMap.mapSize.height * _tileMap.tileSize.height) - position.y) / _tileMap.tileSize.height;return ccp(x, y);
}self.meta = [_tileMap layerNamed:@"Meta"];
_meta.visible = NO;添加這個新方法:
應該都很簡單吧?我就解釋一下新方法的內涵好了。
首先,他取出position的x座標,然後除上構成tile地圖的方塊的寬度,這可以得到x是落在第幾個方塊裡面。
然後再把整個地圖的高度(y方向的長度)減去position的y座標,然後除上構成tile地圖的方塊的長度,這會得到y是落在第幾個方塊裡面。
但注意y的計算法,這表示原點落在左上方!
然後我們把setPlayerPosition替換成下面的內容:
CGPoint tileCoord = [self tileCoordForPosition:position];int tileGid = [_meta tileGIDAt:tileCoord];if (tileGid) {
NSDictionary *properties = [_tileMap propertiesForGID:tileGid];if (properties) {
NSString *collision = [properties valueForKey:@"Collidable"];if (collision && [collision compare:@"True"] == NSOrderedSame) {return;
}
}
}
_player.position = position;
這邊也要稍微解釋一下。首先他把做為參數的position轉換成他是在哪一個方塊裡面,然後透過這個值在meta之中找到該方塊的識別碼GID,然後使用if迴圈,如果該方塊GID碼有找到,那就去tileMap找到這個方塊的屬性(property),然後if迴圈判斷是否為空,如果有找到,由名為Collidable的key取出一個字串collision,並且測試collision和collision是否為True,如果如此,就返回,然後什麼也不作,自然也沒有把player的位置設置在position上了。
運行一下吧,我想,player應該無法再如同鬼魅一樣穿牆了。
留言
張貼留言