天天看点

(四)cocos2d -关节的使用(绳子)使用方式 (绳子为例)

cocos2d 中有很多中关节类,关节是为了让两个独立物体之间建立某种联系,使之犹如一体

常见的关节类有:

PhysicsJointXXX

含义 举例说明
PhysicsJointDistance 设定两个刚体间的固定距离
PhysicsJointFixed 将两个刚体结合在了一起
PhysicsJointGear 使一对刚提的角速度比率保持一定比例 比如齿轮
PhysicsJointGroove 一个刚体连到线上,另一个连到点上
PhysicsJointLimit 限制两个刚体间的最大距离 比如流星锤
PhysicsJointMotor 两个刚体的相对角速度保持一个常数
PhysicsJointPin 两个刚体独立的围绕锚点进行旋转
PhysicsJointRatchet 与套筒扳手的工作类似,单向旋转,不能转回来,比如自行车的飞轮,正想踏实有动力的,反向是没有动力的
PhysicsJointRotoryLimit 与限制关节类似,增加了自旋 地球绕太阳运动(地球同时在自旋))
PhysicsJointRotarySpring 与弹簧关节相似,增加自旋 汽车的悬挂系统
PhysicsJointSpring 永泰黄来连接两个物理刚体

使用方式 (绳子为例)

使用 PhysicsJointDistance 将多个节点连接起来,实现绳子下落摆动的效果

基本步骤:

  1. 固定一个端点,并且设置body
  2. 循环增加节点,将节点addChild() 添加到场景中
  3. 相邻选两个节点创建一个关节 PhysicsJointDistance::cons
  4. 将关节 添加到PhysicsWorld对象 中

demo代码片段:

#include "HelloWorldScene.h"
#include "cocostudio/CocoStudio.h"
#include "ui/CocosGUI.h"

USING_NS_CC;

using namespace cocostudio::timeline;
#define PHYSICS_MATERIAL1  PhysicsMaterial(1,1,0)
#define PHYSICS_MATERIAL2  PhysicsMaterial(1,0,0)
PhysicsWorld * world;
Scene* HelloWorld::createScene()
{
    // 'scene' is an autorelease object
    //auto scene = Scene::create();
	// 创建带物理特性的世界
	auto  scene = Scene::createWithPhysics();
	world = scene->getPhysicsWorld();
	scene->getPhysicsWorld()->setGravity(Vec2(0, -980));
	//scene->getPhysicsWorld()->setAutoStep(false);
	//PhysicsWorld::DEBUGDRAW_JOINT
	//scene->getPhysicsWorld()->setDebugDrawMask(PhysicsWorld::DEBUGDRAW_ALL);
    // 'layer' is an autorelease object
    auto layer = HelloWorld::create();


    // add layer as a child to scene
    scene->addChild(layer);

    // return the scene
    return scene;
}

// on "init" you need to initialize your instance
bool HelloWorld::init()
{
  
    // 1. super init first
    if ( !Layer::init() )
    {
        return false;
    }
    
   /* auto rootNode = CSLoader::createNode("MainScene.csb");
	
    addChild(rootNode);*/

	Size visibleSize = Director::getInstance()->getVisibleSize();
	Vec2 origin = Director::getInstance()->getVisibleOrigin();


	


	

        auto rootNode = CSLoader::createNode("MainScene.csb");
		Sprite * edgeBox = dynamic_cast<Sprite*>(rootNode->getChildByName("Default"));

		auto edgeBody = PhysicsBody::createEdgeBox(visibleSize, PHYSICS_MATERIAL1,3);
		edgeBody->setDynamic(false);
		edgeBox->setPhysicsBody(edgeBody);
		addChild(rootNode);

	      //   使用关节 实现绳子效果

		Sprite * nodes[10];
		PhysicsBody * bodys[10];
		PhysicsJointDistance * pjd[10];

		// 1. 固定第一个节点 

		nodes[0] = Sprite::create();
		Vec2 point(visibleSize.width / 2, 9* visibleSize.height /10);
		nodes[0]->setPosition(point);
		addChild(nodes[0]);
		bodys[0] = PhysicsBody::createCircle(20, PHYSICS_MATERIAL1);
		bodys[0]->setCategoryBitmask(0);
		bodys[0]->setDynamic(false);
		nodes[0]->setPhysicsBody(bodys[0]);
		
		for (int i = 1; i < 10; i++) {
			nodes[i] = Sprite::create("rope05HA.png");
			nodes[i]->setPosition(point.x+40*i,point.y);
			addChild(nodes[i]);
			bodys[i]= PhysicsBody::createCircle(20, PHYSICS_MATERIAL1);
			bodys[i]->setCategoryBitmask(0);
			nodes[i]->setPhysicsBody(bodys[i]);
			pjd[i - 1] = PhysicsJointDistance::construct(bodys[i - 1], bodys[i], Vec2(18,0), Vec2(-18, 0));
			world->addJoint(pjd[i - 1]);// 将关节加入世界
		}




		return true;
}

           

效果(这是失败的效果):

(四)cocos2d -关节的使用(绳子)使用方式 (绳子为例)

解决:

出现问题是因为在设置关节时,设置前后两个节点的关节作用锚点位置弄错了,都弄到各自的中心去了

一个节点的尺寸是 40x18 的

A-B

中间的**-** 表示关节

我们想做的当然是A的末端与B的起端相连接,达到下面的效果

而锚点默认是在sprite 的中间,也就是(0.5,0.5) //这是按照尺寸的百分比来的

锚点位置坐标也可以小于0,也可以大于1,也就是说锚点可以不在sprite 内部

(四)cocos2d -关节的使用(绳子)使用方式 (绳子为例)
pjd[i - 1] = PhysicsJointDistance::construct(bodys[i - 1], bodys[i], Vec2(18,0), Vec2(-18, 0));
// 由于 每个节点的尺寸都是40*18 ,我们通过指定关节连接作用的相对于锚点的一个位置.建立连接
Vec2(18,0): 关节的第一个点作用于A节点的相对于锚点靠右18个像素的位置
Vec2(-18,0):关节的第二个点作用于B节点的相对于锚点靠左18个像素的位置
达到的效果大体是A节点的末端与B节点的起端相连接,这点可以指定
scene->getPhysicsWorld()->setDebugDrawMask(PhysicsWorld::DEBUGDRAW_ALL); 来观察
           

开启 scene->getPhysicsWorld()->setDebugDrawMask(PhysicsWorld::DEBUGDRAW_ALL);

效果:

(四)cocos2d -关节的使用(绳子)使用方式 (绳子为例)

如果把那个相对位置设置大一些,可能更加直观,看出相邻两个节点的之间的关节作用位置(图中绿色的点)

设置为30吧

(四)cocos2d -关节的使用(绳子)使用方式 (绳子为例)

成功的效果:

(四)cocos2d -关节的使用(绳子)使用方式 (绳子为例)

完整的资源以及代码已上传至github

https://github.com/TopForethought/cocos2dx/tree/master/关节绳子

后序会尝试做一个带有悬挂系统的越野车,哈哈!

蹦蹦救护车已上线

(四)cocos2d -关节的使用(绳子)使用方式 (绳子为例)

代码资源:

https://github.com/TopForethought/cocos2dx/tree/master/关节-蹦蹦车

继续阅读