COCOS2DX学习之Box2D物理引擎-------物体和相互作用

1、创建一个静态物体

创建一个静态物体应该很简单,在头文件生命一下要创建新物体的函数,然后在cpp文件中实现它即可。

具体的时候先过程,首先要用createbody函数创建一个物体,然后定义一个b2bodydef变量,指定一下这个变量的type还有position。这样的话一个最简单的静态物体就算是创建好了。

2、物体的相互作用

但是我们虽然创建了两个物体但是在运行的时候发现依然没有看到静止的物体挡住了动态运动的物体,这就是两个物体并没有发生相互作用。

为了让两个物体发生相互作用,我们要设置一个fixture

2.  Body:
    Box2d 中的 Body 没有形状大小,不能碰撞,只具备质量(由 Fixture 的 shape 和 density 决定)、速度、位置这几个基本属性;
    Body 可以接收力和冲量的作用;
    可以附着 Fixture ,附着后才具备形状大小,可以碰撞反弹

    Body 有 3 种:
    static: 没有速度,不接受力和冲量的作用;
    dynamic: 有速度,可以接受力和冲量的作用;
    kinematic: 有速度,不接受力和冲量的作用。与 dynamic 碰撞不会改变原速度,与 static 碰撞不会有反应

    创建 Body:
    b2BodyDef myBodyDef;
    myBodyDef.type = b2_dynamicBody;
    myBodyDef.position.Set(0, 20);
    m_body = m_world->CreateBody(&myBodyDef);

3.  Fixture:
    Fixture 描述了物体的 形状、密度、弹性、摩擦因数;
    两个物体发生碰撞时的反应由其 Fixture 决定;
    一个 Body 可以有多个 Fixture ,Body 的重心受多个 Fixture 的影响;
    Fixture 中的 shape、destiny 等都是以标准单位 米、千克每平方来作为单位的,设定的时候可以参考实际的情形;

    Fixture 有四种 shape :
    b2PolygonShape: 多边形
    b2CircleShape: 圆形
    b2EdgeShape: 线
    b2ChainShape: 链(几条线连在一起)

    Friction 摩擦因数:
    friction 值的范围为 0 到 1,为 0 表示完全没有摩擦,为 1 并不意味着不存在滑动;
    当两个物体发生摩擦时,摩擦的大小取决于比较小的 friction

    Restitution 弹性:
    restitution 值的范围为 0 到 1, 为 0 表示完全没有弹性,碰撞时所有的能量将全部被反弹回去;
    当两个物体发生碰撞时,碰撞的结果取决于比较大的 restitution

    创建 Friction:
    b2PolygonShape polygonShape;
    polygonShape.SetAsBox(1,1);

    b2FixtureDef myFixtureDef;
    myFixtureDef.shape = &polygonShape;
    myFixtureDef.density = 1;
    myFixtureDef.friction = 0;        // 摩擦因数为 0
    myFixtureDef.restitution = 1;        // 弹性因数为 1
    m_body->CreateFixture(&myFixtureDef);

上面的代码片段还有解释应该能说明为什么要给一个物理设置fixture,body看起来是很单一的,如果想让他实现真实物理世界中的一些特性就要设置fixture。

fixture主要是设置物体的一些性质,和之前创建物体时候的bodydef的概念类似。

在用b2PolygonShape shape;这句话指定了物体的形状是多边形之后,还要对应的设置这个物体的位置。利用的就是setasbox.SetAsBox函数接收半个宽度和半个高度作为参数,也就是说,设置出来的这个物体的尺寸是里面的参数的两倍大小。

void HelloWorld::addrect()
{
	b2BodyDef def;
	b2FixtureDef fixdef;
	b2PolygonShape shape;
	b2Body *b =  word->CreateBody(&def);
	auto sprite = Sprite::create();
	def.position = b2Vec2(3,5);
	def.type = b2_dynamicBody;
	shape.SetAsBox(0.5,0.5);
	fixdef.density = 1;
	fixdef.friction = 0.3;
	fixdef.shape = &shape;
	b->CreateFixture(&fixdef);
	addChild(sprite);
	sprite->setTextureRect(Rect(0,0,0.5*2*RATIO,0.5*2*RATIO));
	b->SetUserData(sprite);
}

void HelloWorld::addground()
{
	b2BodyDef def;
	b2PolygonShape shape;
	def.position = b2Vec2(400/RATIO,0);
	shape.SetAsBox(400/RATIO,0.5);
	def.type = b2_staticBody;
	b2Body * body =  word->CreateBody(&def);
	b2FixtureDef fixdef;
	fixdef.density = 1;
	fixdef.friction = 0.3;
	fixdef.shape = &shape;
	body->CreateFixture(&fixdef);
}

两个函数,上面的一个是创建动态的物体然后下落,下面这个函数是创建一个地板,是静态物体。之所是设置fixtrue就是为了能让物体之间产生相互的作用。将物体的属性完备一些,就可以出现一些真实物理世界的情况。

3、创建漂浮的物体

创建漂浮的物体其实也很简单,只不过是改变一下这个物体的类型为b2_kinematicBody即可。漂浮物体和静止物体是不一样的,静止物体是绝对不动的。漂浮物体的物体是不受物理世界的重力控制的。如果想让漂浮物体真正起到漂浮的效果要怎么办呢,很简单,给这个物体设置一个初速度就可以了。

def.linearVelocity = b2Vec2(1,0);设置一个只沿着x 轴方向的初速度。

4、物体的碰撞检测

一般来说,侦听一个事件都需要一个侦听器.

b2ContactListener 这个类主要就是用来监听一些物体之间的接触的。通过实现
b2ContactListener 你就可以收到接触数据。接触监听器支持几种事件: 开始(begin),结束(end), 求解前(pre-solve), 求解后(post-solve)。

Begin事件

当两个fixture开始有重叠时,事件会被触发。传感器和非传感器都会触发这事件。这事件只能在时间步内(译注: 也就是b2World::step函数内部)发生。

End事件

当两个fixture不再重叠时,事件会被触发。传感器和非传感器都会触发这事件。当一个body被摧毁时,事件也有可能被触发。所以这事件也有可能发生在时间步之外。

Pre-Solve事件

在碰撞检测之后,但在碰撞求解之前,事件会被触发。这样可以给你一个机会,根据当前情况来决定是否使这个接触失效。 举个例子,在回调中使用b2Contact::SetEnabled(false),你就可以实现单侧碰撞的功能。每次碰撞处理时,接触会重新生效,所以你在每一个时间步 中都应禁用那个接触。由于连续碰撞检测,pre-solve事件在单个时间步中有可能发生多次。

为了测试,我准备用begin来检验这个监听器的效果。

动态的物体会下落,那么下落在地板上的时候,肯定会发生接触,这样就可以用这个类的一些方法来检测了。SetContactListener利用这个函数创建一个监听器,参数就是我们当前的这个类,this。之后便可以重新实现void HelloWorld::BeginContact(b2Contact* contact).

重新实现如下

void HelloWorld::BeginContact(b2Contact* contact)
{
	if(contact->GetFixtureA()->GetBody() == groundbody||contact->GetFixtureB()->GetBody() == groundbody)
	{
		log("have a body in ground");
	}
}

contact对象可以获取到接触的两个fixture进而获取到他们的实体,如果有一个是地板的话,那么就说明那个自由下落的动态物体和地板发生碰撞了,这样就显示一个消息

时间: 2024-10-07 05:50:10

COCOS2DX学习之Box2D物理引擎-------物体和相互作用的相关文章

COCOS2DX学习之Box2d物理引擎使用之------动态物体的创建

1.创建一个物理世界 首先要引入一个头文件#include "Box2D\Box2D.h" 之后利用b2word创建一个对象,并且指定这个物理世界中的加速度方向. word = new b2World(b2Vec2(0,-10));                        //指定物理世界的加速度 最后还要重写一下update函数,这个函数在之前的计时器学习的时候已经说过,每一帧的变动都将自动执行这个函数.所以我们要通过这个函数来进行创建的物理世界的刷新. 2.创建一个运动的物体

COCOS2DX学习之box2d物理引擎在VS2012中的配置

因为vs中并没有继承box2dz游戏物理引擎,所以在开发有关box2d的游戏的时候,要自己将这个引擎添加进去.首先在解决方案中添加一个已经存在的项目,这个项目的路径就是你创建的cocos2dx项目的目录里面cocos2d\external\Box2D\proj.win32这个文件夹下面的一个vs工程,把它添加进去编译好,就会看到proj.win32\Debug.win32中有了Box2d的库. 之后,将生成的box2d的库添加到项目属性的连接器中即可 tool是我创建的coocs2dx项目 CO

cocos2d-x中的Box2D物理引擎

在Cocos2d-x中集成了2个物理引擎,一个是Chipmunk,一个是Box2D.前者是用C语言编写的,文档和例子相对较少:Box2D是用C++写的,并且有比较完善的文档和资料.所以在需要使用物理引擎的时候,大多数开发者会选择Box2D.Box2D是一款用来模拟刚体在物理世界运动的仿真引擎.通过Box2D物理引擎,世界中的物体就可以按照运动定律进行运动. 注:Box2D下的类都是以b2为前缀的,希望不要与你的命名相冲突 1. 首先我们介绍下需要用到的基本概念. 世界(world) :世界代表了

瘸腿蛤蟆笔记34-cocos2d-x-3.2 Box2d物理引擎World类介绍

上篇回顾 本篇名言:将爱的能量传送给别人,我们自己就会变成一条管道,吸纳来自上天的神圣能源.而那种玄秘体验是我们每个人都得以品尝的! [詹姆士·雷德非] 上篇中,我们学习了Box2d物理引擎dynamics模块中的Contact类,该类包含所有的接触类型.物体碰撞的具体都在该类中. 蛤蟆接着学习dynamics模块中的类,这次咱们学习World这个类. 理论介绍 World类(其实是b2World类,蛤蟆之前说过,Box2d中的类都是b2开头的)包含Body和Joint. 它管理所有的仿真允许异

瘸腿蛤蟆笔记42-cocos2d-x-3.2 Box2d物理引擎Motor Joint

瘸腿蛤蟆原创笔记,欢迎转载,转载请标明出处: 源码下载: http://download.csdn.net/detail/notbaron/7900243 上篇回顾 本篇名言:对"战士旅行者"而言,选择其实不是去选择,而是优雅地接受"无限"的邀请.[唐望] 上篇中,蛤蟆学习了Box2d物理引擎中的持续施加力,接下去蛤蟆继续学习其他的Box2d引擎的使用.这次我们使用Box2d物理引擎来学习 Motor Joint     . 理论介绍 本次的理论知识, 咱们回顾下M

瘸腿蛤蟆笔记36-cocos2d-x-3.2 Box2d物理引擎Ray-cast使用

瘸腿蛤蟆原创笔记,欢迎转载,转载请标明出处: 上篇回顾 本篇名言:人类心灵深处,有许多沉睡的力量:唤醒这些人们从未梦想过的力量,巧妙运用,便能彻底改变一生.[澳瑞森·梅伦] 上几篇中,蛤蟆学习了Box2d物理引擎中如何将我们创建的物理体给描绘在程序里面.让我们能够看到一个非常直观的物体,便于后续进一步学习和理解. 具体步骤 我们还是使用helloworld工程. 1.  首先将\cocos2d-x-3.2\tests\cpp-tests\Classes\Box2DTestBed目录中的6个文件G

瘸腿蛤蟆笔记28-cocos2d-x-3.2 Box2d物理引擎collision模块介绍

上篇回顾 本篇名言:绝不测量山的高度─除非你已到达顶峰,那时你就会知道山有多低. [哈马绍] 上篇中,我们学习了Box2d物理引擎的三大模块之一的common模块,该模块主要包含设置,内存管理和向量数学. 这次蛤蟆接着学习collison模块. 理论介绍 这个collision模块包括了shapes和函数.同时包括一个动态树和broad-phase(蛤蟆不知道怎么解释这个)用于加速碰撞系统.这个模块设计的时候是在动态系统之外使用的.        Shape 这里的shapes描述了碰撞几何,可

瘸腿蛤蟆笔记29-cocos2d-x-3.2 Box2d物理引擎dynamics模块介绍

上篇回顾 本篇名言:奋斗.寻觅.发现,而不屈服.[诗人丁尼生] 上篇中,我们学习了Box2d物理引擎的三大模块之一的collision模块,该模块主要包含形状shape,碰撞函数和动态树等概念. 这次蛤蟆接着学习dynamics模块. 理论介绍 Dynamics模块是Box2d引擎中最复杂的,也是基本上我们打交道最多的模块了.该模块建立在common和collision模块之上,所以需要我们先了解common和collision模块. Dynamics模块包含几大类:  fixture cla

瘸腿蛤蟆笔记39-cocos2d-x-3.2 Box2d物理引擎自由落体实现

瘸腿蛤蟆原创笔记,欢迎转载,转载请标明出处: 上篇回顾 本篇名言:烦恼使我受着极大的影响--我一年多没有收到月俸,我和穷困挣扎:我在我的忧患中十分孤独,而且我的忧患是多么多,比艺术使我操心得更厉害! [米开朗基罗] 前段时间蛤蟆出差北京去了,好在中秋节前回来了哈哈. 上篇中,蛤蟆学习了Box2d物理引擎中的Ray-cast代码解释,接下去蛤蟆继续学习其他的Box2d引擎的使用.这次我们使用Box2d物理引擎来学习物理掉落的情况. 理论介绍 本次的理论知识基本和上次RayCast一致,需要补充如下