cara menggunakan box2d untuk deteksi tabrakan di cocos2d-x

dua sprite saya adalah roll dan hero. saya ingin mendeteksi tabrakan mereka menggunakan box2d di cocos2d-x saya memiliki kedua sprite yang bergerak di layar (berputar secara otomatis, pahlawan secara manual).

yang ingin saya lakukan hanyalah memanggil fungsi Intersection();

ketika kedua sprite bertabrakan. (sprite dideklarasikan secara global di file *.h)

#include "GameScene.h"
#include "HomeScene.h"
USING_NS_CC;

CCScene* GameScene::scene()
{
    // 'scene' is an autorelease object
    CCScene *scene = CCScene::node();

    // 'layer' is an autorelease object
    GameScene *layer = GameScene::node();

    // add layer as a child to scene
    scene->addChild(layer);

    // return the scene
    return scene;
}

// on "init" you need to initialize your instance
bool GameScene::init()
{

    //////////////////////////////
    // 1. super init first
    if ( !CCLayerColor::initWithColor(ccc4(0,0,0,255) ))
    {
        return false;
    }

    //////////////////////////////
    // 2. add your codes below...
    count=0;
    life=3;
    CCSize WinSize= CCDirector::sharedDirector()->getWinSize();
    // background
    CCSprite * bg=CCSprite::spriteWithFile("bg.png");
    bg->setPosition(CCPointZero);
    bg->setAnchorPoint(CCPointZero);
    bg->setScaleX(WinSize.width/460);
    bg->setScaleY(WinSize.height/325);
    this->addChild(bg,0,1);

    //close button
    CCSprite * back=CCSprite::spriteWithFile("close.png");
    CCSprite * back1=CCSprite::spriteWithFile("closeS.png");
    CCMenuItemSprite *home=CCMenuItemSprite::itemFromNormalSprite(back,back1,this,menu_selector(GameScene::callNext));
    CCMenu *MenuClose=CCMenu::menuWithItem(home);
    MenuClose->setPosition(ccp(WinSize.width-20,WinSize.height-20));
    this->addChild(MenuClose,5,1);

    //life icon
    CCSprite * rc=CCSprite::spriteWithFile("rc.png");
    rc->setPosition(ccp(20,WinSize.height-20));
    this->addChild(rc,5,15);

    //score icon
    CCSprite * dp=CCSprite::spriteWithFile("dp.png");
    dp->setPosition(ccp(55,WinSize.height-20));
    this->addChild(dp,5,18);

    //insert roller at a random place
    roll=CCSprite::spriteWithFile("ball.png");
    int minY = (roll->getContentSize().height/2)+(WinSize.height/(4.5));
    int maxY = (WinSize.height)-  (roll->getContentSize().height/2);
    int rangeY = maxY - minY;

    srand ( time(NULL) );

    int actualY = ( rand() % rangeY ) + minY;
    CCLOG("the actualY is oooooooooooooooooooooooooooooooooooooooooooooooooooooooo %d",actualY);
    roll->setPosition(ccp(20,actualY));
    this->addChild(roll,5,8);

    // Determine speed of the roller
    int minDuration = 3;
    int maxDuration = 7;
    int rangeDuration = maxDuration - minDuration;
    int actualDuration = ( rand() % rangeDuration)+ minDuration;

/*  
//creating constraints for the roller
float maxXX = WinSize.width - roll->getContentSize().width/2;
float minXX =roll->getContentSize().width/2;
if (roll->getPosition().x > maxXX)
{
    roll->setPosition( ccp(maxXX, roll->getPosition().y)) ;
}
else if (roll->getPosition().x < minXX)
{
     roll->setPosition (ccp(minXX,roll->getPosition().y));
}


float maxYY = WinSize.height - roll->getContentSize().height/2;
float minYY = roll->getContentSize().height/2;

if (roll->getPosition().y > maxYY)
{
   roll->setPosition ( ccp(roll->getPosition().x, maxYY));
}
else if (getPosition().y < minYY)
{
   roll->setPosition( ccp(roll->getPosition().x, minYY));
}
*/


    // Create the rolling action   
    roll->runAction(CCRepeatForever::actionWithAction((CCSequence*) CCSequence::actions(
                    CCJumpTo::actionWithDuration( actualDuration,ccp(WinSize.width,( rand() % rangeY ) + minY ),( rand() % rangeY ) + minY,4 ),
                    CCHide::action(), 
                    CCMoveTo::actionWithDuration(0,ccp(20,( rand() % rangeY ) + minY)),
                    CCShow::action(), 
                    CCCallFunc::actionWithTarget( this,callfunc_selector(GameScene::scores)),
                    NULL)) );

    //displaying scores
    sprintf(score,"%d",count);  
    scr= CCLabelBMFont::labelWithString(score , "arial16.fnt");
    scr->setPosition(ccp(55,WinSize.height-20));
    scr->setColor(ccc3(0,0,255));
    this->addChild(scr,50);

    //displaying lifes
    sprintf(lifeLabel,"%d",life);   
    lif= CCLabelBMFont::labelWithString(lifeLabel , "arial16.fnt");
    lif->setPosition(ccp(20,WinSize.height-20));
    lif->setColor(ccc3(0,0,255));
    this->addChild(lif,50);

    // insert animated hero
    CCSpriteFrameCache::sharedSpriteFrameCache()->addSpriteFramesWithFile("boyJog.plist","boyJog.png");

    CCMutableArray<CCSpriteFrame*> *proFrame = new CCMutableArray<CCSpriteFrame *>;
    hero = CCSprite::spriteWithSpriteFrameName("boyJog1.png");
    hero->setPosition(ccp(WinSize.width/2-30,WinSize.height/(4.5)));
    hero->setAnchorPoint(CCPointZero);

    char buff[60];
    for(int i=1;i<=13;i++)
    {
        sprintf(buff,"boyJog%d.png",i);
        proFrame->addObject( (CCSpriteFrameCache::sharedSpriteFrameCache())->spriteFrameByName(buff));
    }

    CCAnimation *progressAnimation=CCAnimation::animationWithFrames(proFrame, 0.05);

    //set animation object here
    CCAnimate *animate=CCAnimate::actionWithAnimation(progressAnimation,false); 
    hero->runAction(CCRepeatForever::actionWithAction(animate));
    hero->setScale(.5);

    this->addChild( hero);




    //left right button
    CCSprite *moveRight= CCSprite::spriteWithFile("arrowRight.png");
    CCSprite *moveLeft= CCSprite::spriteWithFile("arrowLeft.png");
    CCSprite *moveRightS= CCSprite::spriteWithFile("arrowRight.png");
    CCSprite *moveLeftS= CCSprite::spriteWithFile("arrowLeft.png");

    CCMenuItemSprite *right=CCMenuItemSprite::itemFromNormalSprite(moveRight,moveRightS,this,menu_selector(GameScene::heroRight));
    CCMenuItemSprite *left=CCMenuItemSprite::itemFromNormalSprite(moveLeft,moveLeftS,this,menu_selector(GameScene::heroLeft));
    CCMenu *RL =CCMenu::menuWithItems(left,right,NULL);

    RL->alignItemsHorizontallyWithPadding(20);
    RL->setPosition(ccp(WinSize.width-40,20));
    RL->setOpacity(150);
    this->addChild(RL);


    //jump button
    CCSprite *jump= CCSprite::spriteWithFile("arrowUp.png");
    CCSprite *jumpS= CCSprite::spriteWithFile("arrowUp.png");
    CCMenuItemSprite *mmJump=CCMenuItemSprite::itemFromNormalSprite(jump,jumpS,this,menu_selector(GameScene::heroJump));
    CCMenu *menuJump=CCMenu::menuWithItem(mmJump);
    menuJump->setPosition(ccp(20,20));

    menuJump->setOpacity(150);

    this->addChild(menuJump,5,12);




    //////////////////////////////
    return true;
}


void GameScene::callNext(CCObject *sender)
{
    CCLOG("game played");

    CCDirector::sharedDirector()->replaceScene(CCTransitionFade::transitionWithDuration(1,(HomeScene::scene())));
    //exit(1);
}

void GameScene::heroJump(CCObject *sender)
{
    CCLOG(" U");
    CCSize WinSize= CCDirector::sharedDirector()->getWinSize();
    CCPoint Pt=hero->getPosition();
    hero->runAction(CCJumpTo::actionWithDuration(1,ccp(Pt.x,WinSize.height/(4.5)),50,1));
}
void GameScene::heroLeft(CCObject *sender)
{
    CCLOG(" L");
    CCSize WinSize= CCDirector::sharedDirector()->getWinSize();
    CCPoint Pt=hero->getPosition();
    hero->runAction(CCJumpTo::actionWithDuration(1,ccp(Pt.x-30,WinSize.height/(4.5)),0,1));
    hero->setFlipX(1);
    //hero->runAction(CCRepeatForever::actionWithAction(animate));

}
void GameScene::heroRight(CCObject *sender)
{
    CCLOG(" R");
    CCSize WinSize= CCDirector::sharedDirector()->getWinSize();
    CCPoint Pt=hero->getPosition();
    hero->runAction(CCJumpTo::actionWithDuration(1,ccp(Pt.x+30,WinSize.height/(4.5)),0,1));
    hero->setFlipX(0);
    //hero->runAction(CCRepeatForever::actionWithAction(animate));
}

void GameScene::scores()
{

    count+=10;
    CCLOG("count ==========================%d",count);
    sprintf(score,"%d",count);
    scr->setString(score);
}

void GameScene::intersection()
{
    CCLOG("collided..........................................................");
}

person Community    schedule 28.01.2012    source sumber


Jawaban (3)


Sprite tidak bertabrakan. Anda harus membuat representasi fisiknya menggunakan Box2D, menyinkronkan grafik dan fisika. Kemudian Anda harus menerapkan pendengar kontak Anda sendiri (mewarisi dari b2ContactListener) dan menggunakannya untuk diberitahu ketika terjadi tabrakan.

person Andrew    schedule 28.01.2012
comment
@jeet.mg: Cocos2d (tanpa box2d) tidak akan menangani atau mendeteksi tabrakan apa pun - person Andrew; 28.01.2012
comment
@jeet.mg: Anda tidak memahami dasar-dasarnya. Baca manual kotak2d. Cari beberapa tutorial cara menggunakannya dengan cocos2d (ada banyak di internet). - person Andrew; 28.01.2012
comment
dasar!! saya telah menulis seluruh kode ini sendiri. meskipun baru mengenal box2d. - person ; 28.01.2012
comment
@ jeet.mg: Anda tidak memahami cara kerja penyertaan. Hanya menyertakan header box2d tidak akan membuat mesin bekerja. Ini adalah dasar-dasarnya. Maaf jika aku mengganggumu. - person Andrew; 28.01.2012
comment
Hai Andrew, terima kasih telah mengoreksi saya saat itu. Itu pertanyaan yang bodoh. Tapi, saya maafkan diri saya sendiri mengingat noob 6,5 tahun yang lalu... haha. P.S. : user1103138 adalah akun saya yang dihapus. - person jeet.chanchawat; 24.06.2018

Anda harus membuat Bodies untuk setiap objek yang ingin Anda terapkan box2D collision. Benda-benda tersebut harus memiliki fixtures, karena perlengkapanlah yang bertabrakan, bukan benda.

Silakan periksa tutorial ini untuk box2d.

EDIT:

Sekadar menambahkan: Sprite hanyalah gambar, dan mereka tidak mengetahui fisika. Mereka harus dipasang ke badan dengan perlengkapan. Agar mereka mengetahui bahwa ada sprite lain di luar sana dan mereka perlu memberikan reaksi jika terjadi tabrakan seperti memantul kembali atau menghancurkan sprite lainnya.

person noob    schedule 19.06.2012
comment
Mengedit jawabannya untuk klarifikasi yang lebih baik - person noob; 17.09.2012

Menurut pendapat saya, tutorial ini lebih bermanfaat. Dan jika Anda tidak ingin karakter Anda terpental saat bertabrakan tetapi tetap mendeteksi tabrakan tersebut, atur perlengkapannya sebagai sensor. Dan jika Anda tidak ingin keduanya bertabrakan sama sekali, atur indeks grup perlengkapannya dengan bilangan bulat yang sama (lebih baik negatif).

yourFixtureDef.filter.groupIndex = -1; // for example
person The Windwaker    schedule 16.09.2012