cocos2d-x检测碰撞,并显示标记

来源:互联网 发布:餐车淘宝客服接待用语 编辑:程序博客网 时间:2024/05/19 22:59
h文件
</pre><pre name="code" class="html"><pre name="code" class="cpp">#ifndef _BOX2D_TEST_H_#define _BOX2D_TEST_H_#include "cocos2d.h"#include "Box2D/Box2D.h"using namespace cocos2d;class ContactListener;class PhysicSprite :public CCSprite{public:PhysicSprite();void setPhysicsBody(b2Body* body);virtual bool isDirty();virtual CCAffineTransform nodeToParentTransform(void);private:b2Body* m_pBody;};class Box2DTestLayer :public CCLayer{CCTexture2D* m_pSpriteTexture;b2World* world;b2ContactListener* contactListener;public:Box2DTestLayer();~Box2DTestLayer();void init_physics();void createResetButton();void reset(CCObject* pSender);void addNewSpriteAtPosition(CCPoint p);void update(float dt);virtual void ccTouchesEnded(CCSet* touches, CCEvent* event);};class Box2DTestScene:public CCScene{public:     void runThisTest();};class ContactListener : public b2ContactListener{private://两个物体开始接触时会响应virtual void BeginContact(b2Contact* contact);//分离时响应virtual void EndContact(b2Contact* contact);public:void callback1(CCNode* pSender);};#endif


cpp文件:
</pre><pre name="code" class="html">#include "Box2dTest.h"#include "cocos-ext.h"#include "VisibleRect.h"USING_NS_CC_EXT;#define PTM_RATIO 32enum{kTagparent = 1,     //碰撞小球tagkTagSpriteContact=2,//标记碰撞点红色的tag};Box2DTestLayer::Box2DTestLayer():m_pSpriteTexture(NULL), world(NULL), contactListener(NULL){//设置可触摸setTouchEnabled(true);//初始化物理环境this->init_physics();//批处理精灵增加速度CCSpriteBatchNode *parent = CCSpriteBatchNode::create("Images/ball.png", 100);addChild(parent, kTagparent);//贴图,后面用于创建碰撞小球m_pSpriteTexture = parent->getTexture();//创建重新开始按钮createResetButton();//添加小球addNewSpriteAtPosition(ccp(VisibleRect::center().x - 100, VisibleRect::center().y));//调用update函数进行模拟scheduleUpdate();}Box2DTestLayer::~Box2DTestLayer(){CC_SAFE_DELETE(world);CC_SAFE_DELETE(contactListener);}void Box2DTestLayer::init_physics(){b2Vec2 gravity;gravity.Set(0, -10.0f);world = new b2World(gravity);world->SetAllowSleeping(true);world->SetContinuousPhysics(true);contactListener = new ContactListener();world->SetContactListener(contactListener);b2BodyDef groundBodyDef;groundBodyDef.position.Set(0, 0);//创建物体b2Body* goundbody = world->CreateBody(&groundBodyDef);//定义物体边界b2EdgeShape groundBox;groundBox.Set(b2Vec2(VisibleRect::leftBottom().x / PTM_RATIO, VisibleRect::leftBottom().y / PTM_RATIO), b2Vec2(VisibleRect::rightBottom().x / PTM_RATIO, VisibleRect::rightBottom().y / PTM_RATIO));goundbody->CreateFixture(&groundBox, 0);groundBox.Set(b2Vec2(VisibleRect::leftBottom().x / PTM_RATIO, VisibleRect::leftBottom().y / PTM_RATIO), b2Vec2(VisibleRect::leftTop().x / PTM_RATIO, VisibleRect::leftTop().y / PTM_RATIO));goundbody->CreateFixture(&groundBox, 0);groundBox.Set(b2Vec2(VisibleRect::leftTop().x / PTM_RATIO, VisibleRect::leftTop().y / PTM_RATIO), b2Vec2(VisibleRect::rightTop().x / PTM_RATIO, VisibleRect::rightTop().y / PTM_RATIO));goundbody->CreateFixture(&groundBox, 0);groundBox.Set(b2Vec2(VisibleRect::rightBottom().x / PTM_RATIO, VisibleRect::rightBottom().y / PTM_RATIO), b2Vec2(VisibleRect::rightTop().x / PTM_RATIO, VisibleRect::rightTop().y / PTM_RATIO));goundbody->CreateFixture(&groundBox, 0);}void Box2DTestLayer::createResetButton(){CCMenuItemImage* item1 = CCMenuItemImage::create("Images/r1.png", "Images/r2.png", this, menu_selector(Box2DTestLayer::reset));item1->setPosition(ccp(VisibleRect::center().x, VisibleRect::bottom().y + 40));CCMenu* menu = CCMenu::create(item1, NULL);menu->setPosition(ccp(0, 0));addChild(menu);}//void Box2DTestLayer::reset(CCObject* pSender){CCScene* boxscene = new Box2DTestScene;CCLayer* pLayer = new Box2DTestLayer;boxscene->addChild(pLayer);pLayer->autorelease();CCDirector::sharedDirector()->replaceScene(boxscene);boxscene->release();}//添加小球void Box2DTestLayer::addNewSpriteAtPosition(CCPoint p){CCPhysicsSprite *sprite = CCPhysicsSprite::createWithTexture(m_pSpriteTexture, CCRectMake(0, 0, 16, 16));sprite->setScale(2.0f);sprite->setOpacity(128);sprite->setColor(ccc3(0, 255, 0));addChild(sprite);//动态物体定义(类型,位置)b2BodyDef bodyDef;bodyDef.type = b2_dynamicBody;bodyDef.position.Set(p.x / PTM_RATIO, p.y / PTM_RATIO);//userData设置为精灵spritebodyDef.userData = sprite;b2Body *body = world->CreateBody(&bodyDef);//为动态物体附着一个形状//dynamicBox.SetAsBox(.5f, .5f);//These are mid points for our 1m boxb2CircleShape circle;circle.m_p.Set(0.0f, 0.0f);circle.m_radius = 0.5f;//body->CreateFixture(&circle, 1);// Define the dynamic body fixture.b2FixtureDef fixtureDef;fixtureDef.shape = &circle;//密度fixtureDef.density = 1.0f;//摩擦力fixtureDef.friction = 0.0f;//弹性(0-1)fixtureDef.restitution = 1.0f;body->CreateFixture(&fixtureDef);sprite->setB2Body(body);sprite->setPTMRatio(PTM_RATIO);sprite->setPosition(ccp(p.x, p.y));}void Box2DTestLayer::update(float dt){int velocityIterations = 2;int positionIterations = 10;world->Step(dt, velocityIterations, positionIterations);}void Box2DTestLayer::ccTouchesEnded(CCSet* touches, CCEvent* event){CCSetIterator it;CCTouch* touch;for (it = touches->begin(); it != touches->end(); it++){touch = (CCTouch*)(*it);if (!touch)break;CCPoint location = touch->getLocation();bool clickAtBox = false;//判断该触摸点是否在body形状以内,触摸点在物体内,触摸时不添加小球for (b2Body* b = world->GetBodyList(); b; b = b->GetNext()){if (b->GetType() == b2_dynamicBody){b2Shape* shape = b->GetFixtureList()->GetShape();b2Transform transform(b->GetPosition(), b2Rot(b->GetAngle()));b2Vec2 point(location.x / PTM_RATIO, location.y / PTM_RATIO);bool hit = shape->TestPoint(transform, point);if (hit){clickAtBox = true;break;}}if (clickAtBox)break;}if (!clickAtBox)addNewSpriteAtPosition(location);}}//碰撞开始void ContactListener::BeginContact(b2Contact* contact){//获取碰撞物体b2Body* bodyA = contact->GetFixtureA()->GetBody();b2Body* bodyB = contact->GetFixtureB()->GetBody();//获取对应精灵auto spriteA = (CCPhysicsSprite*)bodyA->GetUserData();auto spriteB = (CCPhysicsSprite*)bodyB->GetUserData();if (spriteA != nullptr && spriteB != nullptr)  //如果是两个小球碰撞(边界对应的userData是NULL){//定义b2WorldManifold结构,获取碰撞信息b2WorldManifold* manifold = new b2WorldManifold();contact->GetWorldManifold(manifold);CCSprite* sprite_contact = CCSprite::create("Images/ball.png");CCLayer* parent = (CCLayer*)(spriteA->getParent());parent->addChild(sprite_contact, 2, kTagSpriteContact);//在碰撞点处标记sprite_contact->setPosition(ccp(manifold->points[0].x*32, manifold->points[0].y*32));sprite_contact->setScale(0.5f);sprite_contact->setColor(ccc3(255, 0, 0));//设置动作,动作结束后删除精灵CCActionInterval* TintBy = CCTintBy::create(0.20f, -255, 0, 0);CCActionInterval* tint_reverse = TintBy->reverse();//sprite_contact->runAction(TintBy);sprite_contact->runAction(CCSequence::create(TintBy, CCCallFuncN::create(sprite_contact, callfuncN_selector(ContactListener::callback1)), NULL));delete manifold;}}//动作结束后删除精灵void ContactListener::callback1(CCNode* pSender){CCSprite* sprite = (CCSprite*)pSender;sprite->removeFromParent();}void ContactListener::EndContact(b2Contact* contact){b2Body* bodyA = contact->GetFixtureA()->GetBody();b2Body* bodyB = contact->GetFixtureB()->GetBody();auto spriteA = (PhysicSprite*)bodyA->GetUserData();auto spriteB = (PhysicSprite*)bodyB->GetUserData();if (spriteA != nullptr && spriteB != nullptr){spriteA->setColor(ccc3(0, 255, 0));spriteB->setColor(ccc3(0, 255, 0));}}


结果显示:



0 0
原创粉丝点击