0

私の 2 つのスプライトはロールとヒーローです。cocos2d-x で box2d を使用して衝突を検出したいのですが、両方のスプライトが画面上を移動しています (ロールは自動的に、ヒーローは手動で)。

私がしたいのは、関数 Intersection(); を呼び出すことだけです。

2 つのスプライトが衝突したとき。(スプライトは *.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..........................................................");
}
4

3 に答える 3

4

スプライトは衝突しません。Box2D を使用して物理表現を作成し、グラフィックと物理を同期する必要があります。次に、独自の連絡先リスナーを実装し (から継承b2ContactListener)、それを使用して衝突が発生したときに通知を受ける必要があります。

于 2012-01-28T06:13:50.893 に答える
2

Bodies適用するオブジェクトごとに作成する必要がありますbox2D collisionfixturesフィクスチャはボディではなく衝突するものであるため、ボディには が 必要です。

box2d については、このチュートリアルを確認してください。

編集:

追加するだけです:スプライトは単なる画像であり、物理学を知りません. それらは固定具でボディに取り付ける必要があります。そこに他のスプライトがあり、跳ね返ったり、他のスプライトを破壊したりするなど、衝突時に反応する必要があることを彼らが知るようにします。

于 2012-06-19T07:36:25.690 に答える
0

私の意見では、このチュートリアルはもっと役に立ちました。また、キャラクターが衝突時に跳ね返ることを望まないが、とにかく衝突を検出する場合は、フィクスチャをセンサーとして設定します。また、それらをまったく衝突させたくない場合は、フィクスチャgroupIndexを同じ整数(より負の値)に設定します。

yourFixtureDef.filter.groupIndex = -1; // for example
于 2012-09-16T14:38:40.963 に答える