my two sprites are roll and hero. i want to detect their collision using box2d in cocos2d-x i have got both the sprites moving on the screen (roll automatically, hero manually).
all i want to do is call the function intersection();
when the two sprites collide. (sprites are declared globally in the *.h file)
#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..........................................................");
}
In my opinion, this tutorial was more helpful. And if you don't want your characters to bounce on collision but detect the collision anyway, set their fixtures as sensors. And if you don't want them to collide at all, set their fixture groupIndex with the same integer (better negative).
You have to create
Bodies
for every object you want to applybox2D collision
on. The bodies must havefixtures
, as fixtures are the one that collides, not the bodies.Please check this tutorial for box2d.
EDIT:
Just to add: Sprites are just images, and they do not know physics. They must be attached to bodies with fixtures. So that they know that there're some other sprite out there and they need to have a reaction on collision like bouncing back or Just destroy the other sprite.
Sprited are not colliding. You have to create their physical representation using Box2D, sync graphics and physics. Then you have to implement your own contact listener (inherit from
b2ContactListener
) and use it to be notified when collision happens.