zoukankan      html  css  js  c++  java
  • box2d——2.加入鼠标关节MouseJoint和box2d基础概念

      上一节加入了tiles积木,但不能进行鼠标操作。

    以下加入鼠标相关的控制。

    【加入鼠标关节】

    b2MouseJoint *mMouseJoint

    【处理按键响应】

      设置开启触屏之类的就不说了。在触屏開始的时候要查询相交的形状,依据其夹具fixture获得物体。然后创建它与地面间的鼠标关节。

    bool CBaseLayer::ccTouchBegan(CCTouch* touch, CCEvent* event)
    {
    	CCPoint nodePos = convertToNodeSpace(touch->getLocation());
    	mMouseWorldPos = b2Vec2(nodePos.x, nodePos.y);
    
    	if (mMouseJoint)
    		return false;
    
    	// 构造一个小点击盒子
    	b2AABB aabb;
    	b2Vec2 d;
    	d.Set(0.001f, 0.001f);
    	aabb.lowerBound = mMouseWorldPos - d;
    	aabb.upperBound = mMouseWorldPos + d;
    
    	// 向物理世界查询覆盖的形状
    	CQueryCallback callback(mMouseWorldPos);
    	mWorld->QueryAABB(&callback, aabb);
    
    	if (callback.mFixture)
    	{
    		// 创建鼠标关节
    		b2Body *body = callback.mFixture->GetBody();
    		b2MouseJointDef md;
    		md.bodyA = mGroundBody;		// 世界边界
    		md.bodyB = body;			
    		md.target = mMouseWorldPos;// 拖动的坐标
    		md.maxForce = 1000.0f * body->GetMass();	// 拖动的力
    		mMouseJoint = (b2MouseJoint *)mWorld->CreateJoint(&md);
    		// 设置睡眠(这里awake为true表示sleep...)
    		body->SetAwake(true);
    
    		return true;
    	}
    
    	return false;
    }
      然后在鼠标移动的时候更新鼠标关节的目标位置,并在触屏结束的时候删除鼠标关节。

    void CBaseLayer::ccTouchMoved(CCTouch* touch, CCEvent* event)
    {
    	CCPoint nodePos = convertToNodeSpace(touch->getLocation());
    	mMouseWorldPos = b2Vec2(nodePos.x, nodePos.y);
    
    	if (mMouseJoint)
    		mMouseJoint->SetTarget(mMouseWorldPos);
    }
    
    void CBaseLayer::ccTouchEnded(CCTouch* touch, CCEvent* event)
    {
    	if (mMouseJoint)
    	{
    		mWorld->DestroyJoint(mMouseJoint);
    		mMouseJoint = NULL;
    	}
    }


    【物理查询回调】

      从b2QueryCallback派生一个查询回调的类来存储要处理的查询结果:

    // 查询的回调
    class CQueryCallback : public b2QueryCallback
    {
    public:
    	CQueryCallback(const b2Vec2& point)
    	{
    		mPoint = point;
    		mFixture = NULL;
    	}
    
    	bool ReportFixture(b2Fixture* fixture)
    	{
    		b2Body* body = fixture->GetBody();
    		if (body->GetType() == b2_dynamicBody)
    		{
    			// 该点是否在形状内
    			bool inside = fixture->TestPoint(mPoint);
    			if (inside)
    			{
    				mFixture = fixture;
    
    				// We are done, terminate the query.
    				return false;
    			}
    		}
    
    		// Continue the query.
    		return true;
    	}
    
    	b2Vec2		mPoint;
    	b2Fixture	*mFixture;
    };

    【效果图和代码下载】


    代码下载地址

    【box2的基本组件的概念】

    b2World世界:物理世界就是物体、形状和约束相互作用的集合

    b2Body物体

    b2Fixture夹具:用于把形状附加到物体上的关系

    b2Shape形状:物体的形状。依附于五条的2d碰撞几何结构。有摩擦力friction和恢复力restitution等材质性质

    约束:消除物体自由度的物理连接。2d世界中,一个物体有x、y方向和旋转角度3个自由度。

    b2Joint关节:用于把两个或多个物体固定到一起的约束。

    包含旋转、棱柱和距离等。可限制一个关节的活动范围,可通过关节驱动所连接物体的转动。


      box2d针对大小0.1~10单位长度的物体作了优化,所以定义一个转换PTM_RATIO=32,表示像素/米,以便把物体尺寸在cocos2dx与box2d间转换。

      一个物体可附加多个夹具。每一个夹具代表一个特定密度、形状的部件,而物体的主要特征则表现为整个物体在空间的位置和速度信息。

      b2body的userData属性同意存放一个随意类型的指针指向我们自己定义的数据。

  • 相关阅读:
    Windows快捷键
    visual studio code颜色主题切换
    visual studio code中文语言包安装
    顶点缓存与索引缓存
    程序结构(2)
    ansible常用模块
    ansible常用模块
    ubuntu实用技巧
    ubuntu实用技巧
    Sqoop导出MySQL数据
  • 原文地址:https://www.cnblogs.com/wgwyanfs/p/6789778.html
Copyright © 2011-2022 走看看