物理集成

物理集成

加入版本: 3.0alpha1

介绍

在游戏开发中人工地去模拟模拟一个物理世界是悲催的,所以一般由物理引擎来搞定这种问题。我们知道,Box2D就是模拟物理效果的,还有一个轻量的Chipmunk。在Cocos2d-x 2.0中,游戏直接使用物理引擎,而Cocos2d-x则提供一个简单的CCPhysicsSprite。CCPhysicsSprite负责物理引擎与CCSprite之间关系,但其它的物理元素却没有连接到cocos2d-x,这种方式迫使开发人员需要调用Chipmunk或者Box2D的APIs来解决这些问题。所以对于游戏开发人员来说直接使用物理引擎是繁琐的,得记大量的API参数。

不过在Cocos2d-x 3.0中就大有不同了,物理集成将Chipmunk和Box2D合成起来。开发人员不需要关心调用哪些API来对应哪个引擎。

物理引擎与Cocos2d-x的集成:
  • 物理世界集成到Scene,你可以在创建场景的时候就指定是否使用物理引擎
  • 节点有自己的身体属性,也就是说Sprite有自己的身体属性
  • Cocos2d-x 3.0封装了物理引擎的Body(PhysicsBody), Shape(PhysicsShape), Contact(PhysicsContact), Joint(PhysicsJoint)和World(PhysicsWorld),这将使物理的引擎使用更加便利
  • 更加简单的碰撞检测监听-EventListenerPhysicsContact。

创建使用物理引擎的游戏项目

创建3.0的项目可以直接使用/tools/project-creator下的create_project.py。
创建项目默认使用Chipmunk作为物理引擎,你也可以改成Box2D,其实它也不会有很大的不同。
在android中使用Box2D,你必须将 yourprojectName/proj.android/jni/Application.mk 作下面的改动:
DCC_ENABLE_CHIPMUNK_INTEGRATION=1
改成:
DCC_ENABLE_BOX2D_INTEGRATION=1
还有在项目设置的宏预处理器将
CC_ENABLE_CHIPMUNK_INTEGRATION=1
改成:
CC_ENABLE_BOX2D_INTEGRATION=1
Debug和Release两种都要改,如下图所示:

创建一个物理世界的场景

下面的代码创建一个物理世界的场景。
在PhysicsLayer.h添加下面代码:
class PhysicsLayer : public cocos2d::Layer
{
...
// add following codes
void setPhyWorld(PhysicsWorld* world){m_world = world;}
private:
    PhysicsWorld* m_world;
...
}
在PhysicsLayer.cpp的createScene方法中添加下面代码:
Scene* PhysicsLayer::createScene()
{
...
// add following codes
auto scene = Scene::createWithPhysics();
scene->getPhysicsWorld()->setDebugDrawMask(PhysicsWorld::DEBUGDRAW_ALL);

auto layer = HelloWorld::create();
layer->setPhyWorld(scene->getPhysicsWorld());
...
return scene;
}
Scene类有一个静态的工厂方法-createWithPhysics()来创建场景和物理世界。你可以通过调用Scene的getPhysicsWorld()方法来获取物理世界的实例。
PhysicsWorld有一个对于调试物理引擎很有用的方法,setDebugDrawMask(),它可以使图形,连接和碰撞等可见。不过发布游戏时可得记得把调试模式关闭掉。

你可以使用setPhyWorld()将PhysicsWorld传递到子层去,一个场景只有一个PhysicsWorld,所有的图层共享它一个。

创建物理边界

物理世界的一切物品都受重力影响。物理引擎提供了staticShape方法来创建不受重力影响的图形,在Cocos2d-x 2.x中,我们得记住staticShape中的所有参数。
不过在3.0中,PhysicsShape是Node的一个属性,如果你想设置PhysicsWorld的属性,你可以将一个Node实例作为参数传进来。
下面的代码创建一个物理边界:
Size visibleSize = Director::getInstance()->getVisibleSize();
auto body = PhysicsBody::createEdgeBox(visibleSize, PHYSICSBODY_MATERIAL_DEFAULT, 3);
auto edgeNode = Node::create();
edgeNode->setPosition(Point(visibleSize.width/2,visibleSize.height/2));
edgeNode->setPhysicsBody(body);
scene->addChild(edgeNode);
PhysicsWorld有许多诸如createEdgeBox(创建矩形边界)的工厂方法,它们的参数都是:
  1. 矩形边界,默认为可见的大小;
  2. 可选参数-Texture,默认为PHYSICSBODY_MATERIAL_DEFAULT;
  3. 可选参数迟框尺寸,默认为1。
代码中创建完边界后就创建一个Node,然后将屏幕的中点设置为该Node的位置,最后将Node添加到场景中。
Cocos2d-x 3.0中Node的addChild方法能处理物理身体,它将自动将Node的身体添加到场景的PhysicsWorld中。
PhysicsBody的项目方法可以创建相关的PhysicsBody和自动根据body大小的PhysicsShape,以往通常是直接通过物理引擎创建一个body,不过,3.0的物理集成已经简化了流程,我们不需要再写一大堆的代码了。

创建一个受重力影响的Sprite

Cocos2d-x 3.0中创建受重力影响的Sprite是极其容易的:
void HelloWorld::addNewSpriteAtPosition(Point p)
{
    auto sprite = Sprite::create("circle.png");
    sprite->setTag(1);
    auto body = PhysicsBody::createCircle(sprite->getContentSize().width / 2);
    sprite->setPhysicsBody(body);
    sprite->setPosition(p);
    this->addChild(sprite);
}
首先创建一个sprite,然后通过PhysicsBody::createCircle创建一个圆体与sprite关联就行了。

碰撞检测

Cocos2d-x重构了事件分发,所有的事件都由事件发送器来管理。所以现在的物理引擎的碰撞事件也由事件发送器来管理。
下面代码注册了一个碰撞开始的回调函数:
auto contactListener = EventListenerPhysicsContact::create();
contactListener->onContactBegin = CC_CALLBACK_2(HelloWorld::onContactBegin, this);
_eventDispatcher->addEventListenerWithSceneGraphPriority(contactListener, this);
所有的碰撞检测事件都被EventListenerPhysicsContact监听着。创建一个实例,然后设置它的回调方法conContactBegin。CC_CALLBACK_2是C++ 11的回调指针转换方法。因为onContactBegin方法有两个参数,所以我们用CC_CALLBACK_2来转换它们。
_eventDispatcher是基类Node的一个成员,它可以在初始化图层时使用。

Demo

你可以从这里获得这篇文章里的Demo
Demo是基于cocos2d-x 3.0alpha1的,将它复制到你的cocos2d-x-3.0alpha1/projects里去,没有projects文件夹的话就自己创建一个哈。

原文地址:这里
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值