Box2D引擎与触摸的交互通过创建鼠标关节以及碰撞检测来得到触摸点下面的刚体,在根据触摸操作完成相应的功能。首先添加触摸响应函数声明
virtual void ccTouchesBegan(cocos2d::CCSet* touches, cocos2d::CCEvent* event); virtual void ccTouchesMoved(cocos2d::CCSet* touches, cocos2d::CCEvent* event); virtual void ccTouchesEnded(cocos2d::CCSet* touches, cocos2d::CCEvent* event);
声明一个鼠标关节变量
b2World* world; b2Body* wallBody ; float32 wallLineOffset ; b2MouseJoint* m_MouseJoint; //鼠标关节 GLESDebugDraw* m_debugDraw; //调试物理世界绘制对象
在init中打开触摸功能
m_MouseJoint = NULL; this->setTouchEnabled(true);
创建一个碰撞查询回调类
class QueryCallback : public b2QueryCallback { public: QueryCallback(const b2Vec2& point) { m_point = point; m_fixture = NULL; } bool ReportFixture(b2Fixture* fixture) { b2Body* body = fixture->GetBody(); if (body->GetType() == b2_dynamicBody) { bool inside = fixture->TestPoint(m_point); if (inside) { m_fixture = fixture; // We are done, terminate the query. return false; } } // Continue the query. return true; } b2Vec2 m_point; b2Fixture* m_fixture; };
实现触摸函数
void HelloWorld::ccTouchesBegan(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(); if (m_MouseJoint != NULL) return ; // 根据触摸点创建一个很小的碰撞检测矩形 b2AABB aabb; b2Vec2 d; b2Vec2 p = b2Vec2(location.x/PIXEL_TO_METER,location.y/PIXEL_TO_METER); d.Set(0.001f, 0.001f); aabb.lowerBound = p - d; aabb.upperBound = p + d; // 查询物理世界中的碰撞的刚体,回调对象(QueryCallback)中已经过滤的非动态物体 QueryCallback callback(p); world->QueryAABB(&callback, aabb); if (callback.m_fixture) { b2Body* body = callback.m_fixture->GetBody(); //为获取到的刚体创建一个鼠标关节 b2MouseJointDef md; md.bodyA = wallBody; md.bodyB = body; md.target = p; md.maxForce = 1000.0f * body->GetMass(); m_MouseJoint = (b2MouseJoint*)world->CreateJoint(&md); body->SetAwake(true); //唤醒刚体 } } } void HelloWorld::ccTouchesMoved(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(); if (m_MouseJoint) { //更新刚体的位置 m_MouseJoint->SetTarget(b2Vec2(location.x/PIXEL_TO_METER,location.y/PIXEL_TO_METER)); } } } void HelloWorld::ccTouchesEnded(CCSet* touches, CCEvent* event) { if (m_MouseJoint) { //触摸结算销毁鼠标关节 world->DestroyJoint(m_MouseJoint); m_MouseJoint = NULL; } }
最后看看运行效果