Box2D C++ 物理世界与自定义重力
2014-08-20 23:05
232 查看
~~~~我的生活,我的点点滴滴!!
可以调用世界里的方法来完成这些功能,所以世界也管理着所有对象的空间分配。这也就意味着世界非常重要,那
么就让我们来看看世界到底可以做些什么吧。
-定义重力加速度
-调用物理模拟
-发现定制器的作用域
-切断射线并找到相交的定制器
此举可以提高程序运行的效率。如果这个参数为真(true),那么物体当不受作用时候会进入睡眠状态,直到有外界作用而
被叫醒(‘wake’),之后会重新对其进行模拟。例如来自其它物体的碰撞,产生外界作用力作用于物体上等等。一旦像上
面那样创建了一个世界,就可以像我们之前做的那样往世界里添加物体。为了让好玩的事情发生,我们需要不停的调用
Step()方法来模拟物理世界的运动。当然了这部分testbed框架做了相应的处理,且作为Test类的一部已经完成了。
在这个例子中,1/20秒调用一次Step方法,所以在场景中的物体如果每秒移动5米,那么每调用Setp一次物体就移动5/20=0.25米。
其中timeStep参数会影响到世界中所有受到重力的物体。你可能发现通过调整时间步长,能够对物体的加速度产生影响。
为了让模拟看起来更逼真,在游戏中通常会将timeStep的值设置成每次调用Step()方法的频率值。比如说testbed中,默认
的帧率为每秒60帧,所以Step()方法也会在一秒内调用60次,并且把timeStep设置成1/60秒。
当物体之间发生碰撞时,速度迭代和位置迭代的设置将会对其产生影响。通常在Box2D中,当两个物体进行碰撞检测时,
物体之间会发生重叠(互相进入),所以需要做一些计算来得出哪个物体应该移动或者旋转,来使它们不再发生重叠。让这两
个数值越大,模拟的精度也就越高,当然了性能消耗也就会越大。
这个涉及到复杂的世界(world)的计算了,本人目前还不能理解与掌握,暂时不做笔记
展那种神奇的效果了?答案是肯定的!!
起来很简单,现在就用我们所了解的力矩试着实现它。上一篇文章里面我们创建了三个物体,这里我们继续拿来用:
我们运行后,会发现他们三个是自然在同一时间落下的,既然在单个时间步长内重力与作用于物体向下的线性力矩类似。
那么我们只需要一个相同的向上的力进行抵消,这样我就实现了不同重力(其实还是同一个重力,只不过我们人为的偷偷的又
多施加了点别的力)。所需力的大小与物体自身的质量有关:
在新版本(2.2.1以后)可以使用下面的方法直接来改变物体的重力系数
采用类似的方法可以对物体施加任何方向上的力,例如你想让物体沿着墙壁或者在天花板上行走。
重要:应该在第一个时间步长之前对物体施加抵消重力的力矩。如果在主循环中的Step()方法之后调用ApplyForce()方法,
那么在第一个时间步长内,在重力被抵消之前物体将会向下移动一点(这个只要自己分别试上面种方法会感觉到的)
1、世界
世界(Worlds)作为Box2D世界里主要的实体,在之前的讨论话题中已简单的介绍过。当你创建或者删除物体的时候,可以调用世界里的方法来完成这些功能,所以世界也管理着所有对象的空间分配。这也就意味着世界非常重要,那
么就让我们来看看世界到底可以做些什么吧。
-定义重力加速度
-调用物理模拟
-发现定制器的作用域
-切断射线并找到相交的定制器
1.1、定义重力加速度
世界(world)的创建像其它普通类型一样,在构造函数里进行基本的设置,在设置时我们可以设置自己的重力加速器//设置重力为0 b2Vec2 gravity(0, 0); //构造一个世界对象 //b2World *world = new b2World(gravity); //或者后面设置改变世界的重力 m_world->SetGravity(gravity); //设定了当物体不受外界作用的时候是否允许睡眠 m_world->SetAllowSleeping(true);
1.2、调用物理模拟
重力加速度的数值大小会影响世界里的每个动态物体,睡眠参数设定了当物体不受外界作用的时候是否允许睡眠("sleep"),此举可以提高程序运行的效率。如果这个参数为真(true),那么物体当不受作用时候会进入睡眠状态,直到有外界作用而
被叫醒(‘wake’),之后会重新对其进行模拟。例如来自其它物体的碰撞,产生外界作用力作用于物体上等等。一旦像上
面那样创建了一个世界,就可以像我们之前做的那样往世界里添加物体。为了让好玩的事情发生,我们需要不停的调用
Step()方法来模拟物理世界的运动。当然了这部分testbed框架做了相应的处理,且作为Test类的一部已经完成了。
float32 timeStep = 1/20.0; int32 velocityIterations = 8; int32 positionIterations = 3; myWorld->Step( timeStep, velocityIterations, position iterations);
在这个例子中,1/20秒调用一次Step方法,所以在场景中的物体如果每秒移动5米,那么每调用Setp一次物体就移动5/20=0.25米。
其中timeStep参数会影响到世界中所有受到重力的物体。你可能发现通过调整时间步长,能够对物体的加速度产生影响。
为了让模拟看起来更逼真,在游戏中通常会将timeStep的值设置成每次调用Step()方法的频率值。比如说testbed中,默认
的帧率为每秒60帧,所以Step()方法也会在一秒内调用60次,并且把timeStep设置成1/60秒。
当物体之间发生碰撞时,速度迭代和位置迭代的设置将会对其产生影响。通常在Box2D中,当两个物体进行碰撞检测时,
物体之间会发生重叠(互相进入),所以需要做一些计算来得出哪个物体应该移动或者旋转,来使它们不再发生重叠。让这两
个数值越大,模拟的精度也就越高,当然了性能消耗也就会越大。
1.3、发现定制器的作用域和切断射线并找到相交的定制器
这个涉及到复杂的世界(world)的计算了,本人目前还不能理解与掌握,暂时不做笔记2、自定义重力
大家看完上面的物理世界后,有没有这样的想法,演示一个有多个物体在同一水平线上同时下落,设置他们的重力不同来展那种神奇的效果了?答案是肯定的!!
2.1 为每一个物体指定不同的重力
我们经常会遇到的一个问题是,在其他物体依然遵循重力规则的情况下,如何让指定的物体不受重力影响。其实这实现起来很简单,现在就用我们所了解的力矩试着实现它。上一篇文章里面我们创建了三个物体,这里我们继续拿来用:
//.h中 //定义了三个物体,全为指针对象 b2Body *m_body[3]; //.cpp中 b2Vec2 gravity(0, 0); /*********************start*************************/ //定义一个物体的基本属性,他基本包含了我们所知现实世界物体的所有属性 b2BodyDef bodyDef; //设置一个动态物体 bodyDef.type = b2_dynamicBody; bodyDef.angle = 0; //形状 b2PolygonShape boxShape; //创建一个2x2的正方形盒子 boxShape.SetAsBox(1,1); //定制器 b2FixtureDef fixtureDef; fixtureDef.shape = &boxShape; fixtureDef.density = 10; for(int i = 0 ;i < 3; ++ i) { bodyDef.position.Set( -10 + i * 10, 20 ); m_body[i] = m_world->CreateBody(&bodyDef); m_body[i]->CreateFixture(&fixtureDef); } ///*************到底就一个正方形物体产生了******************/ //产生一条水平线 b2BodyDef lineDef; lineDef.type = b2_staticBody; lineDef.position.Set(0,0); b2EdgeShape edgeShape; edgeShape.Set(b2Vec2(-20,0), b2Vec2(20,0)); b2FixtureDef edgeFixture; edgeFixture.shape = &edgeShape; b2Body *lineBody = m_world->CreateBody(&lineDef); lineBody->CreateFixture(&edgeFixture);
我们运行后,会发现他们三个是自然在同一时间落下的,既然在单个时间步长内重力与作用于物体向下的线性力矩类似。
那么我们只需要一个相同的向上的力进行抵消,这样我就实现了不同重力(其实还是同一个重力,只不过我们人为的偷偷的又
多施加了点别的力)。所需力的大小与物体自身的质量有关:
<span style="font-family:SimSun;font-size:18px;">//在Step()函数中添加 m_body[1]->ApplyForce( 0.5f * m_body[1]->GetMass() * -m_world->GetGravity() , m_body[1]->GetWorldCenter());</span><span style="font-family:SimSun;font-size:14px;"> </span>
在新版本(2.2.1以后)可以使用下面的方法直接来改变物体的重力系数
//这样方便许多了,直接把重力缩小成原来的一半 //直接在这个物体定义的地方添加下面的方法就行了 if( i == 1 ) { m_body[i]->SetGravityScale(0.5); }
采用类似的方法可以对物体施加任何方向上的力,例如你想让物体沿着墙壁或者在天花板上行走。
重要:应该在第一个时间步长之前对物体施加抵消重力的力矩。如果在主循环中的Step()方法之后调用ApplyForce()方法,
那么在第一个时间步长内,在重力被抵消之前物体将会向下移动一点(这个只要自己分别试上面种方法会感觉到的)
相关文章推荐
- Box2D C++ 教程-自定义重力
- Box2D C++ 教程-自定义重力
- Box2D C++教程-设置世界(World)7
- 物理引擎Box2D之世界
- Cocos2d-x-3.10 创建没有重力的物理世界
- android box2d重力系统 创建游戏世界(一)
- Box2D C++ 教程-设置世界
- animator,视图控制器的视图转化为物理世界,图片添加重力碰撞,边缘碰撞属性
- Cocos2d-x--伪物理世界,实现Box2D弹球效果
- cocos2d之Box2D详解 删除物理世界对象
- 愤怒的小鸟-物理世界Box2d(1)-静态刚体的创建
- Box2D C++教程-自定义重力9
- Box2D C++ 教程-设置世界
- Box2D C++教程-设置世界(World)7
- 愤怒的小鸟-物理世界Box2d(3)-刚体碰撞监听
- 关于Cocos2D-X在pause时物理世界物体仍缓慢受重力影响的解决方案
- Cocos2d-X游戏【泰然网《跑酷》】JS到C++移植5:初始化物理世界【Chipmunk】
- Box2D 物理引擎---创建一个简单的模拟物理世界
- 如何让物理世界的物体不受重力影响
- box2d中的物理世界