zoukankan      html  css  js  c++  java
  • cocos2d之Box2D详细说明 鼠标联合实现

    cocos2d之Box2D具体解释 鼠标关节实现

    DionysosLai2014-5-7

             我们常常要移动物理世界中的某个物体,例如说石头、木块等。假设我们直接改变这些物体的位置,让这些物体尾随我们手指移动,即使这样是可行的,却违反了物理世界的基本规则。这个世界没有“上帝之手”。

             换个思路,假设我们要移动物体,那是否说,就是我们要在物体上施加一个某个方向的无穷大的力量。恩,没错。就是这样。

    在Box2D中,有一个比較特殊的关节类型:鼠标关节(Mouse Joint),之所以特殊,就是由于它并非物理世界中原生的物体,是来自于用户的操作。鼠标关节,能够试图将物体拖向当前鼠标光标的位置,同一时候在选择方向上没有限制。

             使用鼠标关节一般有三个步骤:

    1.      创建(在touchBegan中)

    2.      改变鼠标关节位置(在touchMove中);

    3.      销毁鼠标关节(在touchEnd中)

     

    依照上面步骤:我们一步步创建鼠标关节:

    在头文件里创建一个鼠标关节:        

    b2MouseJoint* m_mouseJoint;

     

    然后在cpp文件里初始鼠标关节为NULL:

    m_mouseJoint = NULL;

             以下就是创建鼠标关节:

    b2Vec2 vec(m_pTouchPoint.x/PTM_RATIO,m_pTouchPoint.y/PTM_RATIO);
    	//	b2Vec2 vec = b2Vec2(touchPoint.x,touchPoint.y);
    
    	if(m_mouseJoint != NULL)
    	{
    		return false;
    	}
    
    	// Make a small box.
    	b2AABB aabb;
    	b2Vec2 d;
    	d.Set(0.001f, 0.001f);
    	aabb.lowerBound = vec - d;
    	aabb.upperBound = vec + d;
    
    	b2BodyDef bodyDef;
    	b2Body *m_groundBody = m_world->CreateBody(&bodyDef);
    
    	// Query the world for overlapping shapes.
    	QueryCallback callback(vec);
    	m_world->QueryAABB(&callback, aabb);
    
    	if (callback.m_fixture)
    	{
    		b2Body* body = callback.m_fixture->GetBody();
    		b2MouseJointDef md;
    		md.bodyA = m_groundBody;//一般为世界边界    
    		md.bodyB = body;//须要拖动的物体 
    		md.target = vec;
    		md.maxForce = 1000.0f * body->GetMass();
    		m_mouseJoint = (b2MouseJoint*)m_world->CreateJoint(&md);
    		body->SetAwake(true);
    
    		CCLog("touch bengin 
    ");
    
    		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;
    };
    

    这里要注意一个问题,就是设置鼠标关节边界时:

                       md.bodyA= m_groundBody;//一般为世界边界   

                       md.bodyB= body;//须要拖动的物体

             md.bodyA是我们的世界

     

             以下就是在touchMove中改变鼠标关节的属性,代码例如以下:

    m_iTouchType = TOUCH_MOVE;
    	CCPoint point = pTouch->getLocation();
    	m_pTouchPoint = point;
    
    	if(m_mouseJoint == NULL )  
    		return;  
    
    	b2Vec2 vecMouse;  
    	vecMouse.Set((m_pTouchPoint.x)/PTM_RATIO, (m_pTouchPoint.y)/PTM_RATIO);  
    	//改变关节位置.  
    	m_mouseJoint->SetTarget(vecMouse);
    

    最后一个当我们手指离开屏幕时。我们要销毁我们所创建的鼠标关节。在ccTouchEnded增加例如以下代码:

    m_iTouchType = TOUCH_END;
    	CCPoint point = pTouch->getLocation();
    	m_pTouchPoint = point;
    	CCLOG("%f, %f", point.x, point.y);
    
    	//销毁关节.  
    	if(m_mouseJoint != NULL)  
    	{  
    		m_world->DestroyJoint(m_mouseJoint);  
    		m_mouseJoint  =NULL;  
    	}  	
    

    好。到现在为止一切ok该。




    版权声明:本文博主原创文章。博客,未经同意不得转载。

  • 相关阅读:
    psy & vr
    psy 2
    psy
    linux c中select使用技巧
    hostent h_addr_list
    gethostbyname() -- 用域名或主机名获取IP地址
    c_select 调用参数说明
    [NYOJ 737] 石子合并(一)
    [HDU 1059] Dividing
    [HDU 1789] Doing Homework again
  • 原文地址:https://www.cnblogs.com/mfrbuaa/p/4885388.html
Copyright © 2011-2022 走看看