cocos2d-x学习笔记(如何用鼠标去拖动box2d的物体)-- 转自CSDN x13610036461

(转自CSDN x13610036461cocos2d-x学习笔记(如何用鼠标去拖动box2d的物体)原文地址:http://blog.csdn.net/x13610036461/article/details/7799037)

之前一章我用box2d制作了一根用关节连接起来的绳子,但制作完绳子之后该怎么用控制它看它的效果呢。

之后我去翻了下testbed的代码,找到了用鼠标拖拽物体的方法,这里就和大家一起分享下简单的box2d的鼠标拖拽

box2d中是模拟的物理世界,所以你不能随便去改变物体的位置,所以要拖拽物体就要用到鼠标关节

好了,下面来简单讲讲怎么实现鼠标拖拽把

首先来讲讲鼠标拖拽的基本思路

在touchBegan中判定触点是否在body上,若在body上则创建mouseJoint关节

再在touchMoved改变MouseJoint的target,

在touchEnded中删除MouseJoint关节。

 

好了首先我们在头文件Layer类中声明这3个虚函数

virtual bool ccTouchBegan(CCTouch *touch,CCEvent *event);

virtual void ccTouchMovedCCTouch *touch,CCEvent *event);

virtual void ccTouchEnded(CCTouch *touch,CCEvent *event);

还有分别对应3个touch函数的子函数,接受 一个鼠标现在的位置

bool mouseDown(const b2Vec2 p);

void mouseMove(const b2Vec2 p);

void mouseUp(const b2Vec2 p);

还有一些成员

b2MouseJoint m_joint;//保存鼠标关节

b2Body *m_groundBody;//一个空body

然后先来定义mouse函数

bool mouseDown(const b2Vec2 p){

if(m_joint != NULL){//以防鼠标还没松手时坐标的另一body上
        return false;
    }
    b2AABB aabb;//确定触点(注意这触点是一个shape而不是一个point因为这引擎是为触屏控制设计的所以是模糊点不需要绝对的精确
    b2Vec2 d;
    d.Set(0.001f,0.001f);
    aabb.lowerBound = position - d;
    aabb.upperBound = position + d;
    QueryCallback callback(position);//回调函数类,下面会定义
    _world->QueryAABB(&callback,aabb);//大概就是当触点包括该位置就会触发回调,然后会为callback赋值,内部怎么实现我也不清楚
    if(callback.m_fixture)//判定是否有指向的物体

    {

        //下面即创建鼠标关节
        b2Body *body = callback.m_fixture->GetBody();
        b2MouseJointDef md;
        md.bodyA = m_groundBody;//空的body
        md.bodyB = body;
        md.target = position;
        md.maxForce = 1000.0f * body->GetMass();
        m_joint = (b2MouseJoint *)_world->CreateJoint(&md);
        body->SetAwake(true);//注意一定要把body唤醒不然body不会受任何力
        return true;
    }
    return false;

}

之后来看看里面的回调函数

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;//这里的成员一定要定位公有,不然回调函数无法赋值
};

然后是mouseMove和mouseDown 都比较简单

void StartLayer::mouseMove(const b2Vec2 &position){
    if(m_joint){
        m_joint->SetTarget(position);

    }
}
void StartLayer::mouseUp(const b2Vec2 &position){
    if(m_joint){
        _world->DestroyJoint(m_joint);
        m_joint = NULL;
    }
}

然后是touch函数这个也比较简单

bool ccTouchBegan(CCTouch *touch,CCEvent *event)

{

CCPoint location = touch->locationInView(touch->view());

location = CCDirector::sharedDirector()->convertToGL(location);//坐标转换GL

return mouseDown(b2Vec2(location.x/PTM_RATIO,location.y/PTM_RATIO));

}

 

bool ccTouchMoved(CCTouch *touch,CCEvent *event)

{

CCPoint location = touch->locationInView(touch->view());

location = CCDirector::sharedDirector()->convertToGL(location);//坐标转换GL

mouseMove(b2Vec2(location.x/PTM_RATIO,location.y/PTM_RATIO));

}

 

bool ccTouchEnded(CCTouch *touch,CCEvent *event)

{

CCPoint location = touch->locationInView(touch->view());

location = CCDirector::sharedDirector()->convertToGL(location);//坐标转换GL

mouseUp(b2Vec2(location.x/PTM_RATIO,location.y/PTM_RATIO));

}

好了到这里鼠标拖拽已经完成了,现在只要F5编译就行了

(转自CSDN x13610036461cocos2d-x学习笔记(如何用鼠标去拖动box2d的物体)原文地址:http://blog.csdn.net/x13610036461/article/details/7799037)

posted @ 2013-03-24 20:44  bxddno1  阅读(958)  评论(0)    收藏  举报