多多色-多人伦交性欧美在线观看-多人伦精品一区二区三区视频-多色视频-免费黄色视屏网站-免费黄色在线

國(guó)內(nèi)最全I(xiàn)T社區(qū)平臺(tái) 聯(lián)系我們 | 收藏本站
阿里云優(yōu)惠2
您當(dāng)前位置:首頁 > 互聯(lián)網(wǎng) > 實(shí)例介紹Cocos2d-x物理引擎:碰撞檢測(cè)

實(shí)例介紹Cocos2d-x物理引擎:碰撞檢測(cè)

來源:程序員人生   發(fā)布時(shí)間:2014-10-10 08:00:00 閱讀次數(shù):2672次
碰撞檢測(cè)是使用物理引擎的一個(gè)重要目的,使用物理引擎可以進(jìn)行精確的碰撞檢測(cè),而且執(zhí)行的效率也很高。
在Cocos2d-x 3.x中使用事件派發(fā)機(jī)制管理碰撞事件,EventListenerPhysicsContact是碰撞事件監(jiān)聽器。碰撞檢測(cè)相關(guān)的API我們?cè)谇懊嬉还?jié)介紹過了,下面通過一個(gè)實(shí)例介紹碰撞檢測(cè)的實(shí)現(xiàn)。這個(gè)實(shí)例的運(yùn)行后的場(chǎng)景如圖所示,當(dāng)場(chǎng)景啟動(dòng)后,玩家可以觸摸點(diǎn)擊屏幕,每次觸摸時(shí)候,就會(huì)在觸摸點(diǎn)生成一個(gè)新的精靈,精靈的運(yùn)行是自由落體運(yùn)動(dòng)。當(dāng)這些精靈之間發(fā)生接觸時(shí)候,它們的顏色被設(shè)置為黃色,分離后顏色又恢復(fù)到原來狀態(tài)了。


檢測(cè)碰撞實(shí)例
本實(shí)例涉及到物理引擎中物體之間的檢測(cè)碰撞,當(dāng)兩個(gè)物體接觸到兩個(gè)物體分離過程中,會(huì)發(fā)生一些事件,我們可以通過注冊(cè)監(jiān)聽器EventListenerPhysicsContact來響應(yīng)這些事件。
首先看一下看HelloWorldScene.h文件,它的代碼如下:
#ifndef __HELLOWORLD_SCENE_H__ #define __HELLOWORLD_SCENE_H__ #include "cocos2d.h" USING_NS_CC; class HelloWorld : public cocos2d::Layer { public: static cocos2d::Scene* createScene(); virtual bool init(); virtual bool onTouchBegan(cocos2d::Touch* touch, cocos2d::Event* event); virtual void onEnter(); virtual void onExit(); CREATE_FUNC(HelloWorld); void addNewSpriteAtPosition(Vec2 p); }; #endif // __HELLOWORLD_SCENE_H__


上述代碼聲明了onEnter和onExit函數(shù),用來處理層進(jìn)入和退出回調(diào)函數(shù)。我們會(huì)在onEnter函數(shù)注冊(cè)EventListenerPhysicsContact監(jiān)聽器,以便于響應(yīng)碰撞檢測(cè)事件,在onExit函數(shù)中注銷這些監(jiān)聽器。
HelloWorldScene.cpp中創(chuàng)建物理世界和指定世界的邊界語句是在HelloWorld::createScene()和HelloWorld::init()函數(shù)中,這兩個(gè)函數(shù)類似于上一節(jié)的HelloPhysicsWorld實(shí)例,這里不再解釋這些函數(shù)代碼了。
HelloWorldScene.cpp中與碰撞檢測(cè)相關(guān)的代碼是在onEnter和onExit函數(shù)中,代碼如下:
void HelloWorld::onEnter() { Layer::onEnter(); auto listener = EventListenerPhysicsContact::create(); listener->onContactBegin = [](PhysicsContact& contact) ① { auto spriteA = (Sprite*)contact.getShapeA()->getBody()->getNode(); ② auto spriteB = (Sprite*)contact.getShapeB()->getBody()->getNode(); ③ if (spriteA && spriteA->getTag() == 1 && spriteB && spriteB->getTag() == 1) ④ { spriteA->setColor(Color3B::YELLOW); spriteB->setColor(Color3B::YELLOW); } log("onContactBegin"); return true; }; listener->onContactPreSolve = [] (PhysicsContact& contact, PhysicsContactPreSolve& solve) { ⑤ log("onContactPreSolve"); return true; }; listener->onContactPostSolve = [] (PhysicsContact& contact, const PhysicsContactPostSolve& solve) ⑥ log("onContactPostSolve"); }; listener->onContactSeperate = [](PhysicsContact& contact) { ⑦ auto spriteA = (Sprite*)contact.getShapeA()->getBody()->getNode(); auto spriteB = (Sprite*)contact.getShapeB()->getBody()->getNode(); if (spriteA && spriteA->getTag() == 1 && spriteB && spriteB->getTag() == 1) { spriteA->setColor(Color3B::WHITE); spriteB->setColor(Color3B::WHITE); } log("onContactSeperate"); }; Director::getInstance()->getEventDispatcher()-> addEventListenerWithFixedPriority(listener,1); ⑧ } void HelloWorld::onExit() { Layer::onExit(); log("HelloWorld onExit"); Director::getInstance()->getEventDispatcher()->removeAllEventListeners(); ⑨ }


上述代碼的onEnter()函數(shù)是進(jìn)入場(chǎng)景時(shí)候回調(diào)的函數(shù),我們可以在這里通過auto listener = EventListenerPhysicsContact::create()語句創(chuàng)建物體碰撞檢測(cè)事件監(jiān)聽器對(duì)象。接下來通過第①、⑥、⑤、⑦行使用Lambda表達(dá)式定義了事件處理的匿名函數(shù)。
代碼第②和第③行是從接觸點(diǎn)中取出互相接觸的兩個(gè)節(jié)點(diǎn)對(duì)象,它的取值過程有點(diǎn)復(fù)雜,首先接觸點(diǎn)使用getShapeA()和getShapeB()函數(shù)獲得物體形狀,在通過形狀的getBody()函數(shù)獲得物體,通過物體的getNode()函數(shù)獲得與形狀相關(guān)的節(jié)點(diǎn)對(duì)象。第④行代碼是進(jìn)行判斷,判斷從接觸點(diǎn)取出的節(jié)點(diǎn)對(duì)象是否存在,并且判斷是否tag屬性為1。
上面代碼第⑧行addEventListenerWithFixedPriority是指定固定的事件優(yōu)先級(jí)注冊(cè)監(jiān)聽器,事件優(yōu)先級(jí)決定事件響應(yīng)的優(yōu)先級(jí)別,值越小優(yōu)先級(jí)越高。
代碼第⑨行是在退出層回調(diào)函數(shù)onExit()中注銷所有的監(jiān)聽事件。
HelloWorldScene.cpp中還有onTouchBegan和addNewSpriteAtPosition兩個(gè)函數(shù),它們的代碼如下。 
bool HelloWorld::onTouchBegan(Touch* touch, Event* event) { Vec2 location = touch->getLocation(); addNewSpriteAtPosition(location); return false; } void HelloWorld::addNewSpriteAtPosition(Vec2 p) { auto sp = Sprite::create("BoxA2.png"); sp->setTag(1); auto body = PhysicsBody::createBox(sp->getContentSize()); body->setContactTestBitmask(0xFFFFFFFF); ① sp->setPhysicsBody(body); sp->setPosition(p); this->addChild(sp); }


這兩個(gè)函數(shù)的代碼與上一節(jié)介紹的實(shí)例基本一致,但是需要注意的是我們?cè)诘冖傩刑砑恿薭ody->setContactTestBitmask(0xFFFFFFFF)代碼,它的作用是設(shè)置物體接觸時(shí)候能否觸發(fā)EventListenerPhysicsContact中定義的碰撞檢測(cè)事件。如果兩個(gè)物體的接觸測(cè)試掩碼(ContactTestBitmask)執(zhí)行“邏輯與”運(yùn)算,如果結(jié)果為非零值,表明這兩個(gè)物體會(huì)觸發(fā)碰撞檢測(cè)事件。默認(rèn)值是0x00000000,表示清除所有掩碼位,0xFFFFFFFF表示所有掩碼位都設(shè)置為1。
假設(shè)有三個(gè)物體(body1、body2和body3),設(shè)置接觸測(cè)試掩碼如下:
body1->setContactTestBitmask (0x01); //0001
body2->setContactTestBitmask (0x03); //0011
body3>setContactTestBitmask (0x02); //0010
那么body1和body2,以及body2和body3是可以觸發(fā)EventListenerPhysicsContact的碰撞檢測(cè)事件的,而body1和body3是不能的。
另外,除了接觸測(cè)試掩碼(ContactTestBitmask)外,物理引擎中還定義了類別掩碼(CategoryBitmask)和碰撞掩碼(CollisionBitmask),它們的作用是當(dāng)兩個(gè)物體接觸時(shí)候是否發(fā)生“碰撞反應(yīng)”,“碰撞反應(yīng)”會(huì)表現(xiàn)為一個(gè)物體受到另外物體的碰撞,而改變運(yùn)動(dòng)方向。由于兩個(gè)物體是“剛體”,在碰撞的時(shí)候兩個(gè)物體不會(huì)交叉。
那么類別掩碼(CategoryBitmask)與碰撞掩碼(CollisionBitmask)究竟是什么呢?
1、類別掩碼
定義了一個(gè)物體所屬類別,每一個(gè)物體在場(chǎng)景中能被分配到多達(dá)32個(gè)不同的類別。通過body->setCategoryBitmask(int bitmask)函數(shù)設(shè)置類別掩碼。
2、碰撞掩碼
當(dāng)兩個(gè)物體相互接觸時(shí),該物體的碰撞掩碼與另一個(gè)物體的類別掩碼執(zhí)行“邏輯與”運(yùn)算,如果結(jié)果為非零值,該物體能夠?qū)α硪粋€(gè)物體的碰撞發(fā)生反應(yīng)。通過body->setCollisionBitmask(int bitmask) 函數(shù)設(shè)置的碰撞掩碼。
綜上所述,類別掩碼(CategoryBitmask)與碰撞掩碼(CollisionBitmask)決定了物體能否發(fā)生“碰撞反應(yīng)”。而接觸測(cè)試掩碼(ContactTestBitmask)的設(shè)置,能夠檢測(cè)是否發(fā)生接觸發(fā)生,并且觸發(fā)EventListenerPhysicsContact監(jiān)聽事件。 接觸測(cè)試掩碼與類別掩碼和碰撞掩碼沒有什么關(guān)聯(lián)。
假設(shè)有三個(gè)物體(body1、body2和body3),它們?cè)O(shè)置如下:
body1->setCategoryBitmask(0x01); //0001 body1->setCollisionBitmask(0x03); //0011 body2->setCategoryBitmask(0x02); //0010 body2->setCollisionBitmask(0x01); //0001 body3->setCategoryBitmask(0x04); //0100 body3->setCollisionBitmask(0x06); //0110


body1和 body1之間、body1和 body2、body3和 body3能夠互相發(fā)生碰撞反應(yīng),body1和body3不能發(fā)生碰撞反應(yīng)。box 2不能對(duì)box3的碰撞發(fā)生反應(yīng),但box 3能夠?qū)ox2的碰撞發(fā)生反應(yīng)。



更多內(nèi)容請(qǐng)關(guān)注國(guó)內(nèi)第一本Cocos2d-x 3.2版本圖書《Cocos2d-x實(shí)戰(zhàn):C++卷》
本書交流討論網(wǎng)站:http://www.cocoagame.net
更多精彩視頻課程請(qǐng)關(guān)注智捷課堂Cocos課程:http://v.51work6.com
歡迎加入Cocos2d-x技術(shù)討論群:257760386

歡迎關(guān)注智捷iOS課堂微信公共平臺(tái)


生活不易,碼農(nóng)辛苦
如果您覺得本網(wǎng)站對(duì)您的學(xué)習(xí)有所幫助,可以手機(jī)掃描二維碼進(jìn)行捐贈(zèng)
程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關(guān)閉
程序員人生
主站蜘蛛池模板: 免费日韩精品 | 九一精品| 69成人免费视频 | 日韩 欧美 亚洲 中文字幕 | 精品国产一区二区三区久 | 免费看一级欧美毛片 | 欧美日韩一区二区三区麻豆 | 永久在线观看www免费视频 | 中文字幕免费在线观看 | 看一级黄色毛片 | 250pp久久新| 日韩视频高清免费看 | 日韩永久在线观看免费视频 | 亚洲天堂中文 | 免费观看一级欧美在线视频 | 自拍视频精品 | 国产亚洲欧美日韩在线看片 | 国产大片免费观看中文字幕 | 国产一区二区日韩欧美在线 | 国产女乱淫真高清免费视频 | 亚洲欧美日本国产 | 老司机成人午夜精品福利视频 | 一级毛片视频在线观看 | 被男人吃奶添下面好舒服视频 | 久久精品免费 | 亚洲网站一区 | 今天免费中文字幕视频 | 91精品久久久久久久久网影视 | 欧美日本免费一区二区三区 | 中国特黄特级真人毛片 | 青青综合 | 波多野结衣一区二区 | 日本护士xxx | 日本亚洲精品久久 | 国产v在线播放 | 欧美性生交xxxxx久久久 | 久久久精品久久久久久久久久久 | 国产成人精品自拍 | 久久婷五月天 | 亚洲日本一区二区 | 成人a毛片高清视频 |