(NO.00005)iOS實現炸彈人遊戲(六):遊戲資料初始化介紹(三)
現在我們來看看實際初始化地圖的randomCreateMap方法:
//在空白地圖上根據當前關卡資料隨機建立一個關卡地圖//地圖總共瓦塊為30x10 = 300塊,拋去不能移動的Wall(48塊)還剩252塊空格.//還要減去player和敵人佔去的空格.玩家出現在每一關的(0,0)瓦格上.//為了保證player不至於卡死,(0,0),(0,1)和(1,0)三個空格不能放磚//敵人位置也是不可以放磚的,所以//最後可以放磚數量為 252 - 3 = 249 -> 249 - _gd.curLevelEnemyCount-(void)randomCreateMap{ NSInteger rndIdx; NSInteger brickCount = _gd.curLevelBrickCount; CGPoint tmpTilePos; NSAssert((brickCount <= 249-(_gd.curLevelFSCount+_gd.curLevelFSGhostCount)), @"too many bricks!!!"); //刪除對象層(0,0)位置的佔位磚 [self removeObjectAtTileCoord:ccp(0, 0)]; NSMutableArray *bricksAry = [NSMutableArray array]; //隨機擺放磚塊 for (int i = 0; i < brickCount; i++){ rndIdx = arc4random_uniform(_notWallTiles.count); tmpTilePos = [_notWallTiles[rndIdx] CGPointValue]; [_objectLayer setTileGID:4 at:tmpTilePos]; [bricksAry addObject:[NSValue valueWithCGPoint:tmpTilePos]]; [_notWallTiles removeObjectAtIndex:rndIdx]; } //隨機擺放遊戲道具 GameProperty *gp = [GameProperty sharedInstance]; GamePropertyType gpType; for (int i = 0; i < _gd.curLevelGPCount; i++) { gpType = [gp randomGP]; NSAssert(bricksAry.count != 0, @"剩下的磚塊數目太少不足以放置剩餘的道具"); rndIdx = arc4random_uniform(bricksAry.count); tmpTilePos = [bricksAry[rndIdx] CGPointValue]; //隨機擺放一個道具 [gp putGPAt:tmpTilePos InLayer:_propertiesLayer type:gpType]; //該磚塊下已有道具,所以將其從bricksAry中排除出去 [bricksAry removeObjectAtIndex:rndIdx]; } //將_propertiesLayer (0,0)位置的佔位瓦塊刪掉 [gp removeGPAt:ccp(0, 0) InLayer:_propertiesLayer]; NSInteger exitTileID = [_underObjectsLayer tileGIDAt:ccp(0, 0)]; rndIdx = arc4random_uniform(bricksAry.count); tmpTilePos = [bricksAry[rndIdx] CGPointValue]; //隨機擺放出口 [_underObjectsLayer setTileGID:exitTileID at:tmpTilePos]; [bricksAry removeObjectAtIndex:rndIdx]; _exitTilePos = tmpTilePos; //將_underObjectsLayer (0,0)位置的佔位瓦塊刪掉 [_underObjectsLayer removeTileAt:ccp(0, 0)];}
額…為了不造成困惑,我特意做了比較詳細的注釋,我們還是依次來看看代碼吧.
首先一個斷言確保有足夠數量的磚塊可供使用,因為磚塊下面要放置道具和出口,如果磚塊太少就不能完全覆蓋住底下的道具了.
然後將地圖對象層的(0,0)位置的瓦塊刪除掉.為什麼要在地圖層中放置一塊用不到的瓦塊呢?因為Tiled工具有點小問題,我前面的博文裡也講過了.如果在某一層中開始什麼瓦塊都不放,而希望運行時動態增加瓦塊是不可行的.
我也曾實驗過,雖然Cocos2D中內建的瓦塊地圖方法裡有像某一層關聯一個地圖集的方法,但實際操作卻不成功,總是失敗.
所以這裡我們先在Tiled裡放置一塊瓦塊,這樣等於關聯了一個地圖集,接下來在啟動並執行時候就可以隨意增減其他瓦塊了.
回到代碼流中,接下來根據當前關卡中指定磚塊的數目隨機初始化磚塊.
同樣的,後面是隨機擺放道具的代碼,根據指定道具的數量來擺放.這裡可以再”真實”一些,根據道具的稀有程度的機率產生道具,否則一些通關道具隨便一大堆,會使遊戲平衡性大打折扣.
最後是出口的擺放,並將產生好的出口座標儲存到_exitTilePos執行個體變數中,便於以後操作.
遊戲初始化內容大致就是這些了,很多童鞋可能會想遊戲的資料是從哪裡來的,這個實際是放在plist檔案中的,在下一篇我們來討論.