Cocos2d-x遊戲執行個體-《跑跑跑》製作教程(第四篇)——地圖捲動
笨木頭花心貢獻,啥?花心?不呢,是用心~
轉載請註明,原文地址: http://blog.csdn.net/musicvs/article/details/8190473
本文:
註:本文使用到的資源請到這裡下載:http://download.csdn.net/detail/musicvs/4769412
上一篇我們已經把我們跑的主題體現出來了,但是,主角跑沒多久就離開地圖了,也離開螢幕了,這不靠譜啊喂,我們得讓地圖也動起來(難道我做這麼長的地圖是擺設麼~)。
1. 地圖捲動規則
首先要定一個規則,地圖怎麼捲動?我們定義為這樣,地圖只會橫嚮往左捲動,當主角超過螢幕中點的時候地圖就開始捲動。最終的效果應該是這樣的:
留意最左邊,地圖最左邊已經有部分沒有顯示出來了,證明地圖已經往左移動了一小段距離。
2. 觸發捲動
我們在主角座標改變的時候就判斷是否需要移動地圖,來,我們給Player類增加一個函數:
void Player::setViewPointByPlayer(){ if(mSprite == NULL) { return; } CCLayer* parent = (CCLayer* )mSprite->getParent();/* 地圖方塊數量 */ CCSize mapTiledNum = map->getMapSize(); /* 地圖單個格子大小 */ CCSize tiledSize = map->getTileSize(); /* 地圖大小 */ CCSize mapSize = CCSize::CCSize( mapTiledNum.width * tiledSize.width, mapTiledNum.height * tiledSize.height); /* 螢幕大小 */ CCSize visibleSize = CCDirector::sharedDirector()->getVisibleSize(); /* 精靈的座標 */ CCPoint spritePos = mSprite->getPosition(); /* 如果精靈座標小於螢幕的一半,則取螢幕中點座標,否則取精靈的座標 */ float x = max(spritePos.x, visibleSize.width / 2); float y = max(spritePos.y, visibleSize.height / 2); /* 如果x、y的座標大於右上方的極限值,則取極限值的座標(極限值是指不讓地圖超出螢幕造成出現黑邊的極限座標) */ x = min(x, mapSize.width - visibleSize.width / 2); y = min(y, mapSize.height - visibleSize.height / 2); CCPoint destPos = CCPoint::CCPoint(x, y); CCPoint centerPos = CCPoint::CCPoint(visibleSize.width / 2, visibleSize.height / 2); /* 計算螢幕中點和所要移動的目的點之間的距離 */ CCPoint viewPos = ccpSub(centerPos, destPos); parent->setPosition(viewPos);}
這個函數的功能是,讓地圖所在圖層以主角為中心進行移動,也就是,讓世界的焦點停留在主角身上,螢幕隨著主角移動,這樣說比較清晰。
這個函數的演算法解釋起來可能有點繁瑣,總之就是為了讓地圖跟隨主角移動,並且要判斷邊界值,不能讓地圖超出螢幕從而導致有黑邊出現。大家可以根據這個思路自己寫一個演算法,也許比我的更好~
然後,我們的Player要重寫父類的setSimplePosition函數:
void Player::setSimplePosition( int x, int y ){ Entity::setSimplePosition(x, y); /* 以主角為中心移動地圖 */ setViewPointByPlayer();}
記得在標頭檔裡加上這句:
/* 重寫父類的函數 */virtual void setSimplePosition(int x, int y);
於是,編譯運行,就能看到主角在跑,地圖也隨之移動!
呼呼,終於有點意思了~
下一篇我們將給主角添加一個新的很帥的功能——上下移動。
來自未來的PS(2013.01.14):
多位朋友問過我為什麼map變數未聲明,可能是我忘記說了,map變數在Entity.h檔案裡聲明的:
class Entity : public CCNode, public ControllerListener {public: void setSprite(CCSprite* mSprite); void setController(Controller* controller); /* 實現SimpleMoveListener介面的方法 */ virtual void setSimplePosition(int x, int y); virtual CCPoint getCurPosition();protected: CCSprite* mSprite; Controller* mController; CCTMXTiledMap* map; /* ------------------------ Hi,我在這裡~~!!! --------------------------- */ CCTMXLayer* meta; /* 檢測碰撞的地圖層 */ CCTMXLayer* barrier;/* 障礙物層 */ /* 將像素座標轉換為地圖格子座標*/ CCPoint tileCoordForPosition(CCPoint pos);};