physicsbody怎么unity 设置摩擦力力

2689人阅读
cocos2d-x(8)
一、环境:
& & & & cocos2d-x 3.0
& & & & PhysicsEditor 1.0.10
二、cocos2d-x 3.0 篇:
& & & &从cocos2d-x 3.0 可以在scene 中直接添加物理世界后,开发物理效果的2d游戏相对轻松多了。可是编辑多边形的body 就成了问题,之前-x 2.x 版的PE loader 没有目前 CCPhysicsBody 的封装。本人就参考 之前的-x 2.x 版的loader 写了一个-x 3.x&版的PE laoder &,加载 chipmunk shapes ,并根据图片名 获得CCPhysicsBody。
测试代码如下: & &&
#include &HelloWorldScene.h&
#include &VisibleRect.h&
#include &ResourcesPath.h&
#include &PEShapeCache_X3_0.h&
USING_NS_CC;
static const int DRAG_BODYS_TAG = 0x79;
static const int DRAG_BODYS_TAG_Y = 0x80;
static const int DRAG_BODYS_TAG1 = 0x81;
Scene *HelloWorld::createScene()
auto scene = Scene::createWithPhysics();
auto layer = HelloWorld::create();
scene-&addChild(layer);
Device::setAccelerometerEnabled(true);
void HelloWorld::onEnter()
Layer::onEnter();
//初始化父节点
_scene = dynamic_cast&Scene *&(this-&getParent());
//注册触摸监听器
auto touchListener = EventListenerTouchOneByOne::create();
touchListener-&onTouchBegan = CC_CALLBACK_2(HelloWorld::onTouchBegan, this);
touchListener-&onTouchMoved = CC_CALLBACK_2(HelloWorld::onTouchMoved, this);
touchListener-&onTouchEnded = CC_CALLBACK_2(HelloWorld::onTouchEnded, this);
_eventDispatcher-&addEventListenerWithSceneGraphPriority(touchListener, this);
auto accListener = EventListenerAcceleration::create(CC_CALLBACK_2(HelloWorld::onAcceleration, this));初始一个重力感应监听
_eventDispatcher-&addEventListenerWithSceneGraphPriority(accListener, this);注册重力感应监听
//设置物理世界
_scene-&getPhysicsWorld()-&setGravity(Vect(0, 0));
//设置重力
_scene-&getPhysicsWorld()-&setSpeed(1.0f);
//物理世界速度 速度越快刚体越快
_scene-&getPhysicsWorld()-&setDebugDrawMask(PhysicsWorld::DEBUGDRAW_ALL); //绘制调试绘制
//添加拼图模板图片
auto bg = Sprite::create(shizi_di_png);
bg-&setPosition(VisibleRect::center());
this-&addChild(bg);
PEShapeCache::getInstance()-&addBodysWithFile(buttonsbodys_plist);
this-&addPhysicsSprite();
void HelloWorld::addPhysicsSprite()
_scene-&getPhysicsWorld()-&setUpdateRate(5.0f);
// wall 添加物理边境
Size size = VisibleRect::getVisibleRect().
auto wall = Node::create();
//给节点添加静态矩形刚体(PhysicsBody)并带材质(PhysicsMaterial)
wall-&setPhysicsBody(PhysicsBody::createEdgeBox(Size(size.width - 5, size.height - 5), PhysicsMaterial(0.1f, 1.0f, 1.0f)));
wall-&getPhysicsBody()-&setDynamic(false);//设置为静态刚体(Edge
wall-&getPhysicsBody()-&setEnable(false);
wall-&getPhysicsBody()-&setGroup(1); //组编号
/**一个body的CategoryBitmask和另一个body的ContactTestBitmask的逻辑与的结果不等于0时,接触事件将被发出,否则不发送。
*一个body的CategoryBitmask和另一个body的CollisionBitmask的逻辑与结果不等于0时,他们将碰撞,否则不碰撞
wall-&getPhysicsBody()-&setCategoryBitmask(0x03);//
碰撞系数编号
wall-&getPhysicsBody()-&setContactTestBitmask(0x03);// 0001
碰撞检测编号
wall-&getPhysicsBody()-&setCollisionBitmask(0x01);// 0001
wall-&setPosition(VisibleRect::center()); //位置可见区域中心
this-&addChild(wall);
//多纳的头
auto tou = Sprite::create(shizi_tou_png);
tou-&setPhysicsBody(PhysicsBody::createCircle(271, PhysicsMaterial(1000.1f, 0.0f, 1.0f)));//添加半径为271动态圆形刚体 并赋予材质密度1000.1f 反弹力0.0f 摩擦力1.0f
auto toubody = PEShapeCache::getInstance()-&getPhysicsBodyByName(&shizi_tou&);
tou-&setPhysicsBody(toubody);
tou-&getPhysicsBody()-&setTag(DRAG_BODYS_TAG);//给刚体设置标签
tou-&getPhysicsBody()-&setMass(0.1);//刚体设置质量
tou-&getPhysicsBody()-&setGroup(2);//刚体组编号
tou-&getPhysicsBody()-&setCategoryBitmask(0x01);
tou-&getPhysicsBody()-&setContactTestBitmask(0x01); // 0001
tou-&getPhysicsBody()-&setCollisionBitmask(0x01);
tou-&getPhysicsBody()-&setDynamic(false); 动态刚体是可以设置为静态
tou-&getPhysicsBody()-&setRotationEnable(false); //设置不可旋转刚体 碰撞后也不会旋转刚体
tou-&getPhysicsBody()-&setGravityEnable(false);//设置是否接受重力影响
tou-&getPhysicsBody()-&setLinearDamping(3.0f); //设置线性阻尼系数 理论是0-1 但是可以大于1 值越大惯性越小
this-&addChild(tou);
tou-&setPosition(VisibleRect::center());
auto touyingzi = Node::create();
touyingzi-&setPhysicsBody(PhysicsBody::createCircle(271, PhysicsMaterial(1000.1f, 0.0f, 1.0f)));
touyingzi-&getPhysicsBody()-&setTag(DRAG_BODYS_TAG_Y);
//多纳的身子
//PhysicsShapePolygon 是通过点数组来构建不规则的凸多边形;用工具PhysicsEditor 编辑shap 让后导出Chipmunk 格式的plist 中的数据 注:PhysicsEditor Relative为锚点Anchor
设置为cocos默认值(0.5,0.5)才行 ,
auto shengzi = Sprite::create(shizi_shenzi_png);
auto shengzibody = PhysicsBody::create();
Point vert1[3] = {Point(109.500), Point(14.000), Point(117.5000)};
shengzibody-&addShape(PhysicsShapePolygon::create(vert1, 3, PhysicsMaterial(0.1f, 0.0f, 1.0f)));
Point vert2[6] = {Point(-130.50000, -154.00000), Point(-120.500), Point(-67.5000), Point(14.000), Point(-4.00000, -93.00000), Point(-63.00000, -178.50000)};
shengzibody-&addShape(PhysicsShapePolygon::create(vert2, 6, PhysicsMaterial(0.1f, 0.0f, 1.0f)));
Point vert3[6] = {Point(138.500), Point(110.50000, -177.00000), Point(51.50000, -175.00000), Point(-4.00000, -93.00000), Point(14.000), Point(109.500)};
shengzibody-&addShape(PhysicsShapePolygon::create(vert3, 6, PhysicsMaterial(0.1f, 0.0f, 1.0f)));
Point vert4[4] = {Point(-67.5000), Point(-55.0000), Point(-54.0000), Point(14.000)};
shengzibody-&addShape(PhysicsShapePolygon::create(vert4, 4, PhysicsMaterial(0.1f, 0.0f, 1.0f)));
auto shengzibody = PEShapeCache::getInstance()-&getPhysicsBodyByName(&shizi_shenzi&);
shengzi-&setPhysicsBody(shengzibody);
shengzibody-&setTag(DRAG_BODYS_TAG1);
shengzibody-&setRotationEnable(false);
shengzibody-&setGroup(2);
shengzibody-&setMass(0.1);
shengzibody-&setCategoryBitmask(0x02);
shengzibody-&setContactTestBitmask(0x02); //0010
shengzibody-&setCollisionBitmask(0x02);
shengzibody-&setLinearDamping(3.0f);
this-&addChild(shengzi);
shengzi-&setPosition(VisibleRect::bottom() - Point(0, -300));
auto contactListener = EventListenerPhysicsContactWithBodies::create(tou-&getPhysicsBody(), shengzi-&getPhysicsBody());
contactListener-&onContactBegin = CC_CALLBACK_1(HelloWorld::onContactBegin, this);
_eventDispatcher-&addEventListenerWithSceneGraphPriority(contactListener, this);
//多纳的头
auto b1 = Sprite::create(shizi_youshou_png);
b1-&setPhysicsBody(PEShapeCache::getInstance()-&getPhysicsBodyByName(&shizi_youshou&));
b1-&setPosition(VisibleRect::center()+Point(300,0));
b1-&getPhysicsBody()-&setTag(1);
b1-&getPhysicsBody()-&setRotationEnable(false);
this-&addChild(b1);
auto b2 = Sprite::create(shizi_zuoshou_png);
b2-&setPhysicsBody(PEShapeCache::getInstance()-&getPhysicsBodyByName(&shizi_zuoshou&));
b2-&setPosition(VisibleRect::center()-Point(300,0));
b2-&getPhysicsBody()-&setRotationEnable(false);
b2-&getPhysicsBody()-&setTag(1);
this-&addChild(b2);
// LabelTTF
auto label2 = LabelTTF::create(&多纳小狮子爱学习&, &Arial&, 64);
label2-&setPhysicsBody(PhysicsBody::createBox(label2-&getBoundingBox().size, PhysicsMaterial(0.1f, 0.0f, 1.0f)));
label2-&getPhysicsBody()-&setTag(1);
label2-&getPhysicsBody()-&setRotationEnable(false);
label2-&setPosition(VisibleRect::center()+Point(0,300));
addChild(label2, 0);
PEShapeCache::getInstance()-&removeBodysWithWithFile(buttonsbodys_plist);
//注册碰撞检测监听
auto contactListener1 = EventListenerPhysicsContact::create();
contactListener1-&onContactBegin = CC_CALLBACK_1(HelloWorld::onContactBegin, this);
contactListener1-&onContactPostSolve = CC_CALLBACK_2(HelloWorld::onContactPostSolve, this);
_eventDispatcher-&addEventListenerWithSceneGraphPriority(contactListener1, this);
void HelloWorld::onContactPostSolve(PhysicsContact &contact, const PhysicsContactPostSolve &solve)
CCLOG(&%s&, &################## onContactPostSolve&);
bool HelloWorld::onContactBegin(PhysicsContact &contact)
CCLOG(&%s&, &################## onContactBegin&);
// contact.getContactData()-&normal.y & 0;
void HelloWorld::onAcceleration(Acceleration *acc, Event *event)
static float prevX = 0, prevY = 0;
#define kFilterFactor 0.05f
float accelX = (float)acc-&x * kFilterFactor + (1 - kFilterFactor) * prevX;
float accelY = (float)acc-&y * kFilterFactor + (1 - kFilterFactor) * prevY;
prevX = accelX;
prevY = accelY;
auto v = Point(accelX, accelY);
v = v * 200;
if (_scene != nullptr)
_scene-&getPhysicsWorld()-&setGravity(v);
bool HelloWorld::onTouchBegan(cocos2d::Touch *touch, cocos2d::Event *event)
CCLOG(&%s&, &touch&);
auto location = touch-&getLocation();
auto arr = _scene-&getPhysicsWorld()-&getShapes(location);//从物理世界得到多边形
PhysicsBody *body =
for (auto &obj : arr)
if ((obj-&getBody()-&getTag() & DRAG_BODYS_TAG) != 0) //得到刚体
body = obj-&getBody();
if (body != nullptr)
//创建一个刚体
Node *mouse = Node::create();
mouse-&setPhysicsBody(PhysicsBody::create(PHYSICS_INFINITY, PHYSICS_INFINITY));
mouse-&getPhysicsBody()-&setDynamic(false);
mouse-&setPosition(location);
this-&addChild(mouse);
body-&setLinearDamping(0.0f);
//用图钉关节与点中刚体绑定 赋予力 可以拖动
PhysicsJointPin *joint = PhysicsJointPin::construct(mouse-&getPhysicsBody(), body, location);
joint-&setMaxForce(5000.0f * body-&getMass());
_scene-&getPhysicsWorld()-&addJoint(joint);
_mouses.insert(std::make_pair(touch-&getID(), mouse));
void HelloWorld::onTouchMoved(Touch *touch, Event *event)
auto it = _mouses.find(touch-&getID());
if (it != _mouses.end())
it-&second-&setPosition(touch-&getLocation());
void HelloWorld::onTouchEnded(Touch *touch, Event *event)
auto it = _mouses.find(touch-&getID());
if (it != _mouses.end())
this-&removeChild(it-&second);
_mouses.erase(it);
//增加摩擦阻尼 减小惯性
PhysicsBody *body = _scene-&getPhysicsWorld()-&getBody(DRAG_BODYS_TAG);
if (body != nullptr)
body-&setLinearDamping(2.5f);
PhysicsBody *body1 = _scene-&getPhysicsWorld()-&getBody(DRAG_BODYS_TAG1);
if (body1 != nullptr)
body1-&setLinearDamping(2.5f);
void HelloWorld::menuCloseCallback(Ref *pSender)
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WP8) || (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT)
MessageBox(&You pressed the close button. Windows Store Apps do not implement a close button.&, &Alert&);
Director::getInstance()-&end();
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
效果如下:
三、demo 和 库下载&
Github 传送门:
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:28839次
排名:千里之外
原创:20篇
转载:19篇
评论:11条
(3)(10)(15)(2)(3)(1)(1)(1)(1)(3)(1)(1)主题 : cocos2dx 3.0 physicsBody做滚屏地图有bug
级别: 新手上路
可可豆: 162 CB
威望: 162 点
在线时间: 110(时)
发自: Web Page
来源于&&分类
cocos2dx 3.0 physicsBody做滚屏地图有bug&&&
Sprite* s = Sprite::create(&CloseNormal.png&);
s-&setPosition(Point(_pCenterX+300,_pCenterY-200));
s-&setAnchorPoint(Point::ANCHOR_MIDDLE);
s-&setPhysicsBody(PhysicsBody::createBox(Size(50, 50)));
layer-&addChild(s,10);
layer-&runAction(CCMoveBy::create(5,1000));
//scene-&runAction(CCMoveBy::create(5,1000));
尝试用cocos2dx3.0的新碰撞的物理碰撞引擎,如上代码,挡我移动sprite父节点layer的时候,sprite与他的physicsbody保持屏幕相对位置不动这个现象我理解为physicsbody是在世界坐标系下的,是由scene管理的,所以layer即使移动了,但physics body 绑定了sprite 让它不移动。那好把,我移动scene, 这次Physicsbody果然移动了,不过sprite还是相对于屏幕不动,这是为什么呢,我真是一头雾水,难道physicsbody不是使用和sprite绑定的么。我想要利用物理引擎做一款横版闯关游戏,不可避免要移动场景,如果physicsbody不能跟随移动的话就很麻烦,不知道有没有大神提供一些解决方案
级别: 新手上路
可可豆: 85 CB
威望: 85 点
在线时间: 147(时)
发自: Web Page
同问,今天花了我一天在这蛋疼的问题上
级别: 新手上路
可可豆: 54 CB
威望: 44 点
在线时间: 67(时)
发自: Web Page
直接移动Sprite, 要移动场景就移动场景上的所有节点.
级别: 新手上路
可可豆: 63 CB
威望: 63 点
在线时间: 84(时)
发自: Web Page
Lz&& 我也发现了同样的问题,&&我是用TileMap的对象层的折线画出地形 根据地形 创建地形碰撞边缘&&但是这个地形无法跟着地图移动 ,哎 折腾好久了 ,不知道楼主解决了没
级别: 新手上路
可可豆: 26 CB
威望: 6 点
在线时间: 50(时)
发自: Web Page
在UPDATE里面进行修改,把physicbody与Sprite分离开,用UPdate同步起来关键在这里void GameScene::update(float dt){&&&&now = player-&fake-&getPosition();//获取当前body的位置&&&&Point offset=now-//body在给定速度的情况下在0.1s内的位移量&&&&this-&getScene()-&setPosition(this-&getScene()-&getPositionX()-offset.x, this-&getPositionY());//移动整体scene&&&& player-&fake-&setPosition(Point(player-&fake-&getPositionX()+offset.x,player-&fake-&getPositionY()));//整体scene的移动导致body被移动,现在我们把它还原到正常位置&&&&last = player-&fake-&getPosition();&&&&&&player-&play-&setPosition(player-&body-&getPosition());//把用于显示的spirte附着在Physicbody上面,就像一层皮肉附着在骨头上一样}详情在附件里面有我修改后的代码,本来发了个帖子专门探讨这个问题,结果点击发表以后就渺无音信了,同时希望有人可以告诉我BOX2D会有这样问题吗?或者说物理引擎的这个问题现在有修复BUG或官方解决方案吗
(188 K) 下载次数:11
级别: 新手上路
可可豆: 11 CB
威望: 11 点
在线时间: 4(时)
发自: Web Page
我的解决方案:我是在layer里加了一个TiledMap,sprite再加到TiledMap里的。遇到的情况和你一样,而且还有奇怪的点:若sprite静止,你移动地图,sprite是不动的,保持在physicsworld的某个位置;而sprite Moveto的话,你移动地图 ,sprite会跟着地图移动,而且在map上的移动路径不会变。然后,我也搞了一天真是郁闷死了。后来我想到了将tiledMap也加上一个body,设置body为collisionMask为0,大小和map一致(不一致也应该可以)。现在是你移动map,sprite也能跟着移动了。但是,这里会出现新问题:你map的默认anchorpoint为0,0 ,加上body后变为0.5,0.5而且不能设置了,所以之后对map的控制都要以0.5的来处理。我觉得以上几点都应该算bug吧。。。后来我稍微看了下源码,也没找出问题出在哪里。chipmunk 和box没时间去研究space是怎么对body影响的。就先这样草草了解吧。
级别: 新手上路
UID: 81041
可可豆: 59 CB
威望: 45 点
在线时间: 137(时)
发自: Web Page
回 5楼(afoundo) 的帖子
请问 最总如何解决的该问题啊。。
关注本帖(如果有新回复会站内信通知您)
苹果公司现任CEO是谁?2字 正确答案:库克
发帖、回帖都会得到可观的积分奖励。
按"Ctrl+Enter"直接提交
关注CocoaChina
关注微信 每日推荐
扫一扫 浏览移动版主题 : PhysicsJointPin的用法是怎样的
级别: 侠客
可可豆: 192 CB
威望: 192 点
在线时间: 103(时)
发自: Web Page
来源于&&分类
PhysicsJointPin的用法是怎样的&&&
static PhysicsJointPin* construct(PhysicsBody* a, PhysicsBody* b, const Vec2& anchr1, const Vec2& anchr2);anchr1和anchr2是什么意思来的。我一开始是bodyA的cnchr1点会和bodyB的anchr2点重合,然后两个可以绕着那点旋转。但试了不是[ 此帖被abc8-02-06 09:21重新编辑 ]
级别: 侠客
可可豆: 192 CB
威望: 192 点
在线时间: 103(时)
发自: Web Page
对了,如果想看源码的话,在哪里下载的?用什么软件看比较方便
级别: 圣骑士
UID: 356822
可可豆: 790 CB
威望: 775 点
在线时间: 438(时)
发自: Web Page
看下这个吧然后源码吗,coco是开源的,你下了引擎就有了..直接编译器跳转到定义就可以了
级别: 侠客
可可豆: 192 CB
威望: 192 点
在线时间: 103(时)
发自: Web Page
回 2楼(abc88798) 的帖子
那个机器翻译得...自己探索,终于搞懂了:anchr1是相对于nodeA的anchor的实际偏移。
关注本帖(如果有新回复会站内信通知您)
苹果公司现任CEO是谁?2字 正确答案:库克
发帖、回帖都会得到可观的积分奖励。
按"Ctrl+Enter"直接提交
关注CocoaChina
关注微信 每日推荐
扫一扫 浏览移动版UNITY3D物理引擎Rigidbody,Collider,PhysicMaterial的整理
其中最基本的关系:
Collider是最基本的触发物理的条件,例如碰撞检测。基本上,没有Collider物理系统基本没有意义(除了重力)。
Rigidbody是物体的基本物理属性设置,当检测碰撞完之后,就要计算物理效果,而Rigidbody就是提供计算基本参数的玩意。
PhysicMaterial则是附加的基本物理参数,是一个物理材质,UNITY3D有自带默认的物理材质的系数(在Edit/Project
Settings/Physic下设置),它参与碰撞的计算例如反弹效果摩擦效果等。
Rigidbody部分:
Rigidbody组件的中文手册:/Script/Rigidbody/Rigidbody.html
Rigidbody相关具体函数我就不解释了,看官方手册就很明朗,不过有几个还是要讲一下。
如果没有Rigidbody而设置了Collider碰撞的话,那这个物体就是个死死不会动的物体。
假设有Rigidbody去撞它的话,那将会被弹开。不过,假设该脚本控制的是位移而不是物理加力的方式的话,将穿透过去。
两个没有Rigidbody的物体,也是穿透。
两个只有collider而没有rigidbody啥都不会发生,碰撞时连OnTriggerEnter等函数也不会触发。
若碰撞体设置了isTrigger属性,将取代UNITY的物理函数来运算。可以在触发函数里将其屏蔽,再次触发碰撞等效果。
如果物理系统感觉不真实不好,那很可能是缩放的问题。如果你的游戏世界非常大,所以的东西将显示移动非常慢,确保你所有的模型为真实世界大小。例如,一个汽车应该有4米长,一个角色约2米高。物体以相同的加速度下落,不论大或小,重或轻。如果你的游戏世界有较大的缩放,物体仍以相同的加速度下落,但是因为所有的物体都比较大,物体的下落显得就比较慢。(BY
U3D圣典的翻译)
当改变刚体参数的时候(例如质量等),应该在FixedUpdate函数中使用它,物理模拟以离散的时间步执行。FixedUpdate函数在每一步之前被立即调用。(修改自U3D圣典的翻译)
isKinematic这个参数指的是是否受物理力的影响,如果勾上则不收AddForce等物理添加力的函数影响了。
collisionDetectionMode 碰撞检测模式
使用这个创建一个刚体的连续碰撞检测,从没有碰撞检测的其他物体传递,用来防止快速移动的物体,为了获得最佳效果,为快速移动的物体设置这个值为CollisionDetectionMode.ContinuousDynamic,以及为其他与之需要碰撞的物体设置这个值,为CollisionDetectionMode.Continuous。这个对物理性能有很大影响,所以只要给它设置为默认值
CollisionDetectionMode.Discrete,假如快速物体的碰撞没有任何问题。连续碰撞检测只支持刚体的球体、胶囊或盒子碰撞器。(BY
U3D圣典的翻译)
AddTorque()
添加一个让物体旋转的力——力矩。
参照百度百科:/view/36869.htm
关于爆炸和聚拢。
AddForceAtPosition()提供一个聚拢的力
AddExplosionForce()可用于炸弹爆炸的效果
ClosestPointOnBounds()可以计算范围内从内到外的伤害,可以计算爆炸范围内不同地点受到的伤害。好东西。
与collider相应的时间触发
OnCollisionEnter/OnCollisionExit/OnCollisionStay
当collider的isTrigger属性为true的时候,其碰撞事件将转移到自定义脚本那。若想两方同时触发,再加个碰撞体来检测。或者直接触发完后将isTrigger设为false,则会再触发rigidbody的碰撞。
Collider部分:
Collider倒没啥好讲的,主要就是一个isTrigger属性。还有选用怎么样的Collider,选用的话看情况而定了。
其中物理材质在下面提一下,这个对于物理效果来说还是挺重要的。
两Collider相碰,至少要有一个物体具有Rigibody刚体才会触发Trigger函数。
当物体进来,OnTriggerEnter当然会触发。出去时,OnTriggerExit也当然触发。那么物体在进来后Destory后会如何?经过测试是:不会调用OnTriggerExit。
不仅是OnTriggerEnter,OnCollisionEnter这个由碰撞引起的函数也很有用,具体以项目所用为标准把,多查查函数手册。
PhysicMaterial部分:
PhysicMaterial的各属性手册:/Script/PhysicMaterial/PhysicMaterial.html
一般来说只用前三个吧。
1.dynamicFriction
移动时候使用的摩擦力。这个值在0到1之间。
2.staticFriction
当物体在表面静止时使用的摩擦力。通常在0到1之间。
3.bounciness
表面的弹力怎样?0值没有弹力。1值没有能量损失的反弹。
设置好材质直接用就可以了,拖到collider里面。
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。实例介绍Cocos2d-x物理引擎:HelloPhysicsWorld - 关东升 - ITeye技术网站
博客分类:
我们通过一个实例介绍一下,在Cocos2d-x 3.x中使用物理引擎的开发过程,熟悉这些API的使用。这个实例的运行后的场景,当场景启动后,玩家可以触摸点击屏幕,每次触摸时候,就会在触摸点生成一个新的精灵,精灵的运行是自由落体运动。
HelloPhysicsWorld实例
使用物理引擎的一般步骤,如下图所示。
这个过程与上帝创建世界的过程类似,上帝首先创建了世界,然后为世界指定了边界,否则万物就会掉到世界之外的混沌里去了,最后上帝创建了万物。当然这只是一个最基本的步骤,有的时候还需要碰撞检测和使用关节等处理。下面我们就按照这个步骤介绍一下代码部分。首先看一下看HelloWorldScene.h文件,它的代码如下:
#ifndef __HELLOWORLD_SCENE_H__
#define __HELLOWORLD_SCENE_H__
#include "cocos2d.h"
USING_NS_CC;
class HelloWorld : public cocos2d::Layer
static cocos2d::Scene* createScene();
virtual bool init();
virtual bool onTouchBegan(cocos2d::Touch* touch, cocos2d::Event* event);
CREATE_FUNC(HelloWorld);
void addNewSpriteAtPosition(Vec2 p);
#endif // __HELLOWORLD_SCENE_H__
上述第①行代码是声明了单点触摸函数onTouchBegan,以便于响应单点触摸事件。第②行代码是定义创建精灵函数,这个函数是在触摸点击位置创建一个精灵对象。HelloWorldScene.cpp中创建物理世界,代码如下:
Scene* HelloWorld::createScene()
auto scene = Scene::createWithPhysics();
scene-getPhysicsWorld()-setDebugDrawMask(PhysicsWorld::DEBUGDRAW_ALL);
auto layer = HelloWorld::create();
scene-addChild(layer);
上述第①行代码Scene::createWithPhysics()语句是创建场景,这个是带物理引擎世界场景,使用createWithPhysics()函数会在场景中进行初始化物理引擎,我们可以通过场景的getPhysicsWorld()函数获取初始化的物理世界(PhysicsWorld)对象。我们也可以根据需要在这里设置物理世界,其中第②行代码设置在物理世界中绘制调试遮罩,这会把物体的形状绘制出来。因为世界中的物体,如果没有与精灵绑定到一起,我们是看不到它的。这主要用于调试,当调试结束后,游戏发布的时候,我们需要把它关闭。关闭绘制调试遮罩的场景如下图所示。HelloWorldScene.cpp中指定世界的边界,代码如下:
bool HelloWorld::init()
if ( !Layer::init() )
Size visibleSize = Director::getInstance()-getVisibleSize();
Vec2 origin = Director::getInstance()-getVisibleOrigin();
//定义世界的边界
auto body = PhysicsBody::createEdgeBox(visibleSize,
PHYSICSBODY_MATERIAL_DEFAULT,5.0f);
auto edgeNode = Node::create();
edgeNode-setPosition(Vec2(visibleSize.width/2,visibleSize.height/2));
edgeNode-setPhysicsBody(body);
this-addChild(edgeNode);
setTouchEnabled(true);
//设置为单点触摸
setTouchMode(Touch::DispatchMode::ONE_BY_ONE);
上述代码HelloWorld::init是初始化层函数,在这个函数中我们可以指定世界的边界,世界边界也是一个物体,代码第①行PhysicsBody::createEdgeBox是创建物体对象,静态函数createEdgeBox指定世界边界是矩形盒子,createEdgeBox函数的第一个参数指定矩形的大小。第二个参数是设置材质,PHYSICSBODY_MATERIAL_DEFAULT常量是默认材质,材质是由结构体PhysicsMaterial定义的,结构体PhysicsMaterial成员有:density(密度)、friction(磨擦系数)和restitution(弹性系数)。密度可以用来计算物体的质量,密度可以为零或者为正数。摩擦系数经常会设置在0.0~1.0之间,0.0表示没有摩擦力,1.0会产生强摩擦。弹性系数的值通常设置到0.0~1.0之间,0.0表示物体不会弹起,1.0表示物体会完全反弹,即称为弹性碰撞。createEdgeBox函数的第三个参数是设置边的宽度。代码第②行是创建边界节点对象,这个节点对象作为世界边界对象,第③行代码是设置节点对象的位置。第④行代码edgeNode-&setPhysicsBody(body)是设置与节点相关的物体对象。通过这条语句使得游戏场景中的节点对象(精灵等)与物体关联起来。第⑤行代码是将节点对象添加到层中。代码第⑥行setTouchEnabled(true)是使层开始触摸事件支持。第⑦行代码setTouchMode(Touch::DispatchMode::ONE_BY_ONE)是设置触摸模式为单点触摸。HelloWorldScene.cpp其他代码如下:
bool HelloWorld::onTouchBegan(Touch* touch, Event* event)
Vec2 location = touch-getLocation();
addNewSpriteAtPosition(location);
void HelloWorld::addNewSpriteAtPosition(Vec2 p)
auto sp = Sprite::create("Ball.png");
sp-setTag(1);
auto body = PhysicsBody::createCircle(sp-getContentSize().width / 2);
//auto body = PhysicsBody::createBox(sp-getContentSize());
sp-setPhysicsBody(body);
sp-setPosition(p);
this-addChild(sp);
上述代码第①行是单点触摸时候调用的函数,在这个函数中调用addNewSpriteAtPosition(location)函数,在触摸点创建一个精灵对象。第②行代码是定义addNewSpriteAtPosition函数,第③行代码Sprite::create("Ball.png")是创建一个精灵对象,第④行代码sp-&setTag(1)是设置精灵的tag属性,在检查碰撞时候可以通过tag属性判断并获得精灵对象。第⑤行代码是通过PhysicsBody的静态createCircle函数创建圆圈形状物体。PhysicsBody还有很多类似的create函数,如createBox、createCircle、createPolygon和createEdgePolygon等函数,这些函数与物理形状对应的。这里只详细解释createCircle函数, createCircle函数API如下:static PhysicsBody* createCircle(float radius,const PhysicsMaterial & material = PHYSICSBODY_MATERIAL_DEFAULT,const Vec2 & offset = Vec2::ZERO )其中第一个参数radius是设置圆圈的半径,第二参数material是材质,这可以省略,默认值是PHYSICSBODY_MATERIAL_DEFAULT,所以在HelloWorld::init()函数中定义世界的边界时候,PhysicsBody::createEdgeBox语句中的material参数也是可以省略的。第三个参数offset是偏移量,可以省略,默认值是Vec2::ZERO。
第⑥行代码PhysicsBody::createBox(sp-&getContentSize())是创建一个没有边的矩形盒子。第⑦行代码sp-&setPhysicsBody(body)是设置与精灵相关的物体对象。
更多内容请关注最新Cocos图书《Cocos2d-x实战 C++卷》
本书交流讨论网站:更多精彩视频课程请关注智捷课堂Cocos课程:
欢迎加入Cocos2d-x技术讨论群:
《Cocos2d-x实战 C++卷》现已上线,各大商店均已开售:
互动出版网:
《Cocos2d-x实战 C++卷》源码及样章下载地址:
源码下载地址:
样章下载地址:
欢迎关注智捷iOS课堂微信公共平台
论坛回复 /
浏览: 248193 次
来自: 北京
有下载地址么?
支持支持!
wwwang89 写道关老师,你好 ,请问:我的服务器端是用j ...
关老师,你好 ,请问:我的服务器端是用java写的,不是.ne ...
crowning_2008 写道关老师 好!你好

我要回帖

更多关于 cbbe body physics 的文章

 

随机推荐