如何在cocos2d-x中使用box2d进行碰撞检测
我的两个精灵是滚动和英雄。我想在 cocos2d-x 中使用 box2d 检测它们的碰撞 我已经让两个精灵在屏幕上移动(自动滚动,手动英雄)。
我想做的就是调用函数 junction();
当两个精灵碰撞时。 (精灵在 *.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..........................................................");
}
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..........................................................");
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
精灵不碰撞。您必须使用 Box2D、同步图形和物理来创建它们的物理表示。然后,您必须实现自己的接触侦听器(继承自
b2ContactListener
)并使用它在发生碰撞时收到通知。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.您必须为要应用
box2D 碰撞
的每个对象创建Bodies
。物体必须有装置
,因为装置是发生碰撞的装置,而不是物体。请查看 box2d 的本教程。
编辑:
只是补充一下:精灵只是图像,它们不知道物理。它们必须通过固定装置固定在车身上。这样他们就知道那里还有其他精灵,他们需要对碰撞做出反应,例如反弹或只是摧毁另一个精灵。
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.
在我看来, 本教程更有帮助。
如果您不希望角色在碰撞时弹起,但仍能检测到碰撞,请将其固定装置设置为传感器。
如果您根本不希望它们发生碰撞,请将它们的固定装置 groupIndex 设置为相同的整数(最好是负值)。
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).