cocos2dx3.5 新增物理引擎分析
World 世界物理刚体被添加到一个叫世界(World)的容器里,这也是它们被模拟的场所。将bodies,shapes,constraints这些对象添加到物理世界中,将整个物理世界作为一个整体进行更新。物理世界决定了所有这些部件在一起的互动方式。其中,用物理API实现的许多互动都是与PhysicsWorld这个对象有关的。 物理世界物理世界(PhysicsWorld)对象是进行物理模拟时的一个核心部件。物理世界(PhysicsWorld)与场景(Scene)紧密整合在一起。让我们来看一个我们都会涉及到的例子吧。你住的房子里有厨房吗?你想这个问题的时候,就像是在想你的物理世界一样!现在,你的世界里拥有一些物理刚体(PhysicsBody)对象,就跟食物、刀具、电器这些东西一样!在这个世界中,这些刚体相互作用。它们相互接触,并且对相互的接触做出反应。例如:用刀子切开食物,并把它放到电器中。刀子切到食物了吗?可能切到了。也可能还没有。还可能这个刀子根本就不适合做这个。 PhysicsWorld相关的函数: /** Adds a joint to the physics world.*/ /** set the gravity value */ /** 每一个物理世界(PhysicsWorld)都具有与之相关的属性: -重力(gravity):全局重力,应用于整个物理世界。默认值为Vec2(0.0f,-98.0f)。 -速度(speed):设定了物理世界的速度。这里,速度指的是这个模拟世界运动的一种比率。默认值为1.0。 -刷新率:设定了物理世界的刷新率,这里刷新率指的是EngineUpdateTimes/PhysicsWorldUpdateTimes的比值。 -子步(substeps):设定了物理世界中每次刷新的子步数量。刷新物理世界的过程也被称为步进(stepping)。按照默认设置,物理世界会不停地进行自动刷新。这被称为“自动步进(auto stepping)”,它会自动地进行。你可以通过设定PhysicsWorld::setAutoStep(false)禁用一个物理世界的auto step,然后通过设定PhysicsWorld::step(time)来手动刷新PhysicsWorld。substeps使用比单一框架更加精确的时间增量来刷新物理世界。使用它,我们可以实现更加细致地实现对步进过程的控制,包括更加流畅的运动。 创建一个带有物理世界的场景: auto scene=Scene::createWithPhysics(); 参考: bool Scene::initWithPhysics() 获得场景的物理世界 scene->getPhysicsWorld() 不过首先要保证: CC_USE_PHYSICS==1.这个宏,控制物理世界的开和关。
物理刚体物理刚体(PhyicsBody)对象具有位置(position)和速度(velocity)两个属性。可以在PhysicsBody上应用forces、movement、damping和impulses。物理刚体可以是静态的,也可以是动态的。静态的刚体在模拟世界中不会移动,看起来就像它拥有无限大的质量一样。动态的刚体则是一种完全仿真的模拟。它可以被用户手动移动,但更常见的是它们受到力的作用而移动。动态刚体可以与所有的刚体类型发生碰撞。 Cocos2d-x提供了Node::setPhysicsbody()来将物理刚体与一个节点对象关联在一起。 创建一个物理刚体 auto physicsBody = PhysicsBody::createBox(Size(65.0f,81.0f), PhysicsMaterial(0.1f,1.0f,0.0f));
physicsBody还有以下函数:
static PhysicsBody* createCircle(float radius,const PhysicsMaterial& material = PHYSICSBODY_MATERIAL_DEFAULT,const Vec2& offset = Vec2::ZERO);
/** Create a body contains a box shape. */ static PhysicsBody* createBox(const Size& size,const Vec2& offset = Vec2::ZERO); /** * @brief Create a body contains a polygon shape. * points is an array of Vec2 structs defining a convex hull with a clockwise winding. */ static PhysicsBody* createPolygon(const Vec2* points,int count,const Vec2& offset = Vec2::ZERO); /** Create a body contains a EdgeSegment shape. */ static PhysicsBody* createEdgeSegment(const Vec2& a,const Vec2& b,float border = 1); /** Create a body contains a EdgeBox shape. */ static PhysicsBody* createEdgeBox(const Size& size,float border = 1,const Vec2& offset = Vec2::ZERO); /** Create a body contains a EdgePolygon shape. */ static PhysicsBody* createEdgePolygon(const Vec2* points,float border = 1); /** Create a body contains a EdgeChain shape. */ static PhysicsBody* createEdgeChain(const Vec2* points,float border = 1);
virtual PhysicsShape* addShape(PhysicsShape* shape,bool addMassAndMoment = true);
physicsBody->setDynamic( false );
//create a sprite
auto sprite = Sprite::create(
"whiteSprite.png"
);
sprite->setPosition(s_centre);
addChild(sprite);
精灵设置刚体
//apply physicsBody to the sprite
sprite->setPhysicsBody(physicsBody );
//add five dynamic bodies
for
(
int
i = 0; i < 5; ++i)
{
physicsBody = PhysicsBody::createBox(Size(65.0f,
PhysicsMaterial(0.1f,0.0f));
//set the body isn't affected by the physics world's gravitational force
physicsBody->setGravityEnable(
false
);
//set initial velocity of physicsBody
physicsBody->setVelocity(Vec2(cocos2d::random(-500,500),
cocos2d::random(-500,500)));
physicsBody->setTag(DRAG_BODYS_TAG);
sprite = Sprite::create(
"blueSprite.png"
);
sprite->setPosition(Vec2(s_centre.x + cocos2d::random(-300,300),
s_centre.y + cocos2d::random(-300,300)));
sprite->setPhysicsBody(physicsBody);
addChild(sprite);
}
物理调试
打开
#if CC_USE_PHYSICS
getPhysicsWorld()->setDebugDrawMask( PhysicsWorld::DEBUGDRAW_ALL); #endif
关闭
#if CC_USE_PHYSICS
getPhysicsWorld()->setDebugDrawMask(PhysicsWorld::DEBUGDRAW_NONE); #endif 连接/关节关节是一种把接触点联结在一起的方式。每一个关节都有一个从PhysicsJoint对象获得的定义。在两个不同的刚体之间,所有的关节都是联结在一起的。刚体可以是静态的。你可以使用joint->setCollisionEnable(false)来避免相关联的刚体相互碰撞。很多关节的定义需要你提供一些几何数据。很多情况下,关节由锚点来定义。其余的关节定义数据取决于关节的类型。
bool PhysicsDemo::onTouchBegan(Touch* touch,Event* event) RayCast: /** Searches for physics shapes that intersects the ray. */ Vec2 point3 = point2;
contact: auto contactListener = EventListenerPhysicsContact::create(); contactListener->onContactBegin = CC_CALLBACK_1(PhysicsContactTest::onContactBegin,this); _eventDispatcher->addEventListenerWithSceneGraphPriority(contactListener,this); (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |