您好,登錄后才能下訂單哦!
1、在各種不同類型的精靈之間注冊碰撞
考慮到你的游戲中擁有各種不同類型的精靈,但有時候我們只關心其中某兩種類型之間的碰撞。
例如在超級瑪麗中,馬里奧(Mario)和關卡中的硬幣、站點(CheckPoint,不知道咋翻譯)、烏龜之間的碰撞。在這種情況下,讓我們先來定義碰撞的回調函數吧。
你可以同時定義碰撞前后的回調函數,也可以只定義碰撞前,或者碰撞后。具體得按你游戲中需求來做,代碼如下
- void HelloWorld::preCollisionBetweenMarioAndCoin(LHContactInfo* contact)
- {
- CCLog("PRE Mario ... Coin");
- }
- void HelloWorld::preCollisionBetweenMarioAndTurtle(LHContactInfo* contact)
- {
- CCLog("Mario ... Turtle");
- }
- void HelloWorld::preCollisionBetweenMarioAndCheckpoint(LHContactInfo* contact)
- {
- CCLog(@"Mario ... Checkpoint");
- }
- void HelloWorld::postCollisionBetweenMarioAndCoin(LHContactInfo* contact)
- {
- CCLog(@"Mario ... Coin");
- }
- void HelloWorld::postCollisionBetweenMarioAndTurtle(LHContactInfo* contact)
- {
- CCLog(@"Mario ... Turtle");
- }
- void HelloWorld::postCollisionBetweenMarioAndCheckpoint(LHContactInfo* contact)
- {
- CCLog(@"Mario ... Checkpoint");
- }
現在定義好了我們所需要的函數,接下來就只要讓LevelHelper在碰撞發生的時候去調用它們就行了。首先在我們載入關卡的后面寫上以下方法:
- //creating the objects
- loader->addObjectsToWorld(world, this);
- ...
- loader->useLevelHelperCollisionHandling();//這個方法是必要的,否則碰撞將不會執行
- loader->registerPreColisionCallbackBetweenTagA(COIN, MARIO, this,
- callfuncO_selector(HelloWorld::preCollisionBetweenMarioAndCoin))
- loader->registerPostColisionCallbackBetweenTagA(COIN, MARIO, this,
- callfuncO_selector(HelloWorld::postCollisionBetweenMarioAndCoin))
- loader->registerPreColisionCallbackBetweenTagA(CHECKPOINT, MARIO, this,
- callfuncO_selector(HelloWorld::preCollisionBetweenMarioAndCheckpoint))
- loader->registerPostColisionCallbackBetweenTagA(CHECKPOINT, MARIO, this,
- callfuncO_selector(HelloWorld::postCollisionBetweenMarioAndCheckpoint))
- loader->registerPreColisionCallbackBetweenTagA(TURTLE, MARIO, this,
- callfuncO_selector(HelloWorld::preCollisionBetweenMarioAndTurtle))
- loader->registerPostColisionCallbackBetweenTagA(TURTLE, MARIO, this,
- callfuncO_selector(HelloWorld::postCollisionBetweenMarioAndTurtle))
在碰撞事件的函數中,會發現有一個參數LHContactInfo* contact,它將返回所有發生碰撞時的信息。
為了獲得碰撞的兩個物體,可以很簡單的通過contact來獲得:
- void HelloWorld::preCollisionBetweenMarioAndCoin(LHContactInfo* contact)
- {
- CCLog("Mario ... Coin");
- b2Body* coin = contact->bodyA;
- b2Body* mario= contact->bodyB;
- }
更多可用的信息都在LHContactInfo這個類中,詳細可以查看具體的源碼。下面我簡單描述部分屬性:
- // 獲得 TagA/TagB 屬性對應的body
- b2Body* bodyA = contact->bodyA;
- b2Body* bodyB = contact->bodyB;
- // 獲得 TagA/TagB 屬性對應的精靈對象,
- // 如果發生碰撞的是貝塞爾曲線/直線, 則返回NULL, 所以使用之前需要核查是否為空
- LHSprite* sprA = contact->spriteA();
- LHSprite* sprB = contact->spriteB();
- // Box2d contact info, 可以查看源碼獲得它更多的信息
- b2Contact* boxContact = contact->contact;
- // old manifold info, 只在pre Collision有效
- // 如果發生碰撞的body具有Sensor屬性, 則返回NULL,使用之前需檢查
- const b2Manifold* oldManifold = contact->oldManifold;
- // 碰撞發生時的沖量信息, 只在post Collision有效
- // 如果發生碰撞的body具有Sensor屬性, 則返回NULL,使用之前需檢查
- const b2ContactImpulse* impulse = contact->impulse;
2、靜態物體與靜態物體, 或者手動移動靜態物體與其他類型的物體發生碰撞
在Box2D中,會將靜態物體的質量存儲為零,靜態物體可以讓用戶手動移動,它速度為零。另外它不會和其他任意類型的物體相互碰撞。
但有時候我們需要檢測到靜態物體間的相互碰撞。那該怎么做呢?
想象你有一個臺階(platform靜態)通過LevelHelper的路徑動畫上下來回移動;
想象你需要有一個在臺階與玩家之間碰撞發生時的回調函數。
這時,像剛才那樣定義的回調函數是不會執行的。
解決方法:
*復制一份platform, 并在LevelHelper中設置為不可見。
*設置新的這個platform屬性為: "Is Sensor", "Dynamic", "Is Bullet", "Fixed Rotation",
*設置新的platform tag 與之前的匹配,
*通過距離關節把這兩個platform綁定在一塊。
現在兩個物體就會同時運動,但在游戲中我們看不到新的這個platform,因為它是不可見的。但它卻能幫你檢測碰撞。幫你處理其他更多的邏輯信息。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。