物理场景关节Chipmunk

//

//  PhysicsJoints2.hpp

//  day01

//

//  Created by MAC on 16/7/14.

//

//


#ifndef PhysicsJoints2_hpp

#define PhysicsJoints2_hpp


#include <stdio.h>

#include <iostream>

using namespace std;

#include "cocos2d.h"

using namespace cocos2d;

#include "ui/CocosGUI.h"

using namespace cocos2d::ui;


const int DRAG_BODYS_TAG =1;

class PhysicsJoints2:public Layer{

public:

    static Scene* createScene();

    bool init();

    CREATE_FUNC(PhysicsJoints2);

    void onEnter();

    void onExit();

    PhysicsWorld* getPhysicsWorld();

    Sprite* makeBall(Vec2 point, float radius, PhysicsMaterial material = PHYSICSSHAPE_MATERIAL_DEFAULT);

    Sprite* makeBox(Vec2 point, Size size, int color=0, PhysicsMaterial material = PHYSICSSHAPE_MATERIAL_DEFAULT);

private:

    Size visiableSize;

    Vec2 center;

    PhysicsBody* _touchBody;

};



#endif /* PhysicsJoints2_hpp */



//

//  PhysicsJoints2.cpp

//  day01

//

//  Created by MAC on 16/7/14.

//

//


#include "PhysicsJoints2.hpp"




Scene* PhysicsJoints2::createScene(){

    auto scene = Scene::createWithPhysics();

    //set the debug

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

    //设置重力(xy

    scene->getPhysicsWorld()->setGravity(Vec2(0, 0));

    auto layer = PhysicsJoints2::create();

    scene->addChild(layer);

    return scene;

}

bool PhysicsJoints2::init(){

    if (!Layer::init()) {

        return false;

    }

    visiableSize = Director::getInstance()->getVisibleSize();

    center = Vec2(visiableSize.width/2,visiableSize.height/2);//屏幕中心

    _touchBody = nullptr;

    

    

    auto dispatcher = Director::getInstance()->getEventDispatcher();

    auto touchListener = EventListenerTouchOneByOne::create();

    touchListener->onTouchBegan =  [=](Touch* _touch,Event* _touchEvent)->bool{

        PhysicsWorld* _physicsWorld = this->getPhysicsWorld();

        Vec2 location = _touch->getLocation();

        auto arr = _physicsWorld->getShapes(location);//物理世界中哪些形状包含这个点

        for (auto& obj : arr)

        {

            if ((obj->getBody()->getTag() == 1) )

            {

                _touchBody = obj->getBody();

                break;

            }

        }

        if (_touchBody) {

            return true;

        }

        return false;

    };

    

    touchListener->onTouchMoved =  [=](Touch* _touch,Event* _touchEvent){

        if (_touchBody) {

            _touchBody->getNode()->setPosition(_touch->getLocation());

        }

    };

    touchListener->onTouchEnded =  [=](Touch* _touch,Event* _touchEvent){

        _touchBody = nullptr;

    };

    

    dispatcher->addEventListenerWithSceneGraphPriority(touchListener, this);

    return true;

}


PhysicsWorld* PhysicsJoints2::getPhysicsWorld(){

    return Director::getInstance()->getRunningScene()->getPhysicsWorld();

}



void PhysicsJoints2::onEnter(){

    Layer::onEnter();

    

    Vec2 offset = center; //屏幕中心

    Node* node = Node::create();

    PhysicsBody* box = PhysicsBody::create();

    node->addComponent(box);

    

    box->setDynamic(false); //静态

    node->setPosition(Point::ZERO);

    this->addChild(node);

    box->addShape(PhysicsShapeEdgeBox::create(Size(100, 100), PHYSICSSHAPE_MATERIAL_DEFAULT, 1, offset));

    

    

//    别针联合,如果两个机构固定在一起它们可以独立绕锚点运动.

//    auto sp1 = makeBall(center - Vec2(30, 0), 10);

//    auto sp1PhysicsBody = sp1->getPhysicsBody();

//    sp1PhysicsBody->setTag(1);

//    

//    auto sp2 = makeBall(center + Vec2(30, 0), 10);

//    auto sp2PhysicsBody = sp2->getPhysicsBody();

//    sp2PhysicsBody->setTag(1);

//    PhysicsJointPin* joint = PhysicsJointPin::construct(sp1PhysicsBody, sp2PhysicsBody, center);//连接

//    getPhysicsWorld()->addJoint(joint);

    

    //将两个机构在一个固定的融合点. 固定接头是非常有用的,它可以用于创建复杂的图形,他也可以被打散

//        auto sp1 = makeBall(center - Vec2(30, 0), 10);

//        auto sp1PhysicsBody = sp1->getPhysicsBody();

//        sp1PhysicsBody->setTag(1);

//    

//        auto sp2 = makeBox(center + Vec2(30, 0), Size(30, 10));

//        auto sp2PhysicsBody = sp2->getPhysicsBody();

//        sp2PhysicsBody->setTag(1);

//    

//        PhysicsJointFixed* joint = PhysicsJointFixed::construct(sp1PhysicsBody, sp2PhysicsBody, center);

//        getPhysicsWorld()->addJoint(joint);

    

    //该关节用于在两个刚体之间设置一个固定距离。

//        auto sp1 = makeBall(center - Vec2(30, 0), 10);

//        auto sp1PhysicsBody = sp1->getPhysicsBody();

//        sp1PhysicsBody->setTag(DRAG_BODYS_TAG);

//    

//        auto sp2 = makeBox(center + Vec2(30, 0), Size(30, 10));

//        auto sp2PhysicsBody = sp2->getPhysicsBody();

//        sp2PhysicsBody->setTag(DRAG_BODYS_TAG);

//    

//        PhysicsJointDistance* joint = PhysicsJointDistance::construct(sp1PhysicsBody, sp2PhysicsBody, Point::ZERO, Point::ZERO);

//        getPhysicsWorld()->addJoint(joint);

    

    //限制了两个物体之间的最大距离,就好像他们被一根绳子连接起来一样

//        auto sp1 = makeBall(center - Vec2(30, 0), 10);

//        auto sp1PhysicsBody = sp1->getPhysicsBody();

//        sp1PhysicsBody->setTag(DRAG_BODYS_TAG);

//    

//        auto sp2 = makeBox(center + Vec2(30, 0), Size(30, 10));

//        auto sp2PhysicsBody = sp2->getPhysicsBody();

//        sp2PhysicsBody->setTag(DRAG_BODYS_TAG);

//    

//        PhysicsJointLimit* joint = PhysicsJointLimit::construct(sp1PhysicsBody, sp2PhysicsBody, Point::ZERO, Point::ZERO, 30.0f, 60.0f);

//        getPhysicsWorld()->addJoint(joint);

    

    //用于连接两个刚体,其效果相当于一个弹簧

//        auto sp1 = makeBall(center - Vec2(30, 0), 10);

//        auto sp1PhysicsBody = sp1->getPhysicsBody();

//        sp1PhysicsBody->setTag(DRAG_BODYS_TAG);

//    

//        auto sp2 = makeBox(center + Vec2(30, 0), Size(30, 10));

//        auto sp2PhysicsBody = sp2->getPhysicsBody();

//        sp2PhysicsBody->setTag(DRAG_BODYS_TAG);

//    

//        PhysicsJointSpring* joint = PhysicsJointSpring::construct(sp1PhysicsBody, sp2PhysicsBody, Point::ZERO, Point::ZERO, 500.0f, 0.3f);

//        getPhysicsWorld()->addJoint(joint);

    

    //把第一个物体A连接到一条线上,把第二个物体连接到一个点上

//        auto sp1 = makeBall(offset - Vec2(30, 0), 10);

//        auto sp1PhysicsBody = sp1->getPhysicsBody();

//        sp1PhysicsBody->setTag(DRAG_BODYS_TAG);

//    

//        auto sp2 = makeBox(offset + Vec2(30, 0), Size(30, 10));

//        auto sp2PhysicsBody = sp2->getPhysicsBody();

//        sp2PhysicsBody->setTag(DRAG_BODYS_TAG);

//    

//        PhysicsJointGroove* joint = PhysicsJointGroove::construct(sp1PhysicsBody, sp2PhysicsBody, Vec2(30, 15), Vec2(30, -15), Vec2(-30, 0));

//        getPhysicsWorld()->addJoint(joint);

    

    

    //PhysicsJointSpring类似,但是刚体可以自由旋转

//        auto sp1 = makeBox(offset - Vec2(30, 0), Size(30, 10));

//        auto sp1PhysicsBody = sp1->getPhysicsBody();

//        sp1PhysicsBody->setTag(DRAG_BODYS_TAG);

//    

//        auto sp2 = makeBox(offset + Vec2(30, 0), Size(30, 10));

//        auto sp2PhysicsBody = sp2->getPhysicsBody();

//        sp2PhysicsBody->setTag(DRAG_BODYS_TAG);

//    

//        getPhysicsWorld()->addJoint(PhysicsJointPin::construct(sp1PhysicsBody, box, sp1->getPosition()));

//        getPhysicsWorld()->addJoint(PhysicsJointPin::construct(sp2PhysicsBody, box, sp2->getPosition()));

//        PhysicsJointRotarySpring* joint = PhysicsJointRotarySpring::construct(sp1PhysicsBody, sp2PhysicsBody, 3000.0f, 60.0f);

//        getPhysicsWorld()->addJoint(joint);

    

    //PhysicsJointLimit类似,但是刚体可以自由旋转

//        auto sp1 = makeBox(offset - Vec2(30, 0), Size(30, 10));

//        auto sp1PhysicsBody = sp1->getPhysicsBody();

//        sp1PhysicsBody->setTag(DRAG_BODYS_TAG);

//    

//        auto sp2 = makeBox(offset + Vec2(30, 0), Size(30, 10));

//        auto sp2PhysicsBody = sp2->getPhysicsBody();

//        sp2PhysicsBody->setTag(DRAG_BODYS_TAG);

//    

//        getPhysicsWorld()->addJoint(PhysicsJointPin::construct(sp1PhysicsBody, box, sp1->getPosition()));

//        getPhysicsWorld()->addJoint(PhysicsJointPin::construct(sp2PhysicsBody, box, sp2->getPosition()));

//        PhysicsJointRotaryLimit* joint = PhysicsJointRotaryLimit::construct(sp1PhysicsBody, sp2PhysicsBody, 0.0f,(float) M_PI_2);

//        getPhysicsWorld()->addJoint(joint);

    

    //就像一个连接器一样用来连接两个身体

//        auto sp1 = makeBox(offset - Vec2(30, 0), Size(30, 10));

//        auto sp1PhysicsBody = sp1->getPhysicsBody();

//        sp1PhysicsBody->setTag(DRAG_BODYS_TAG);

//    

//        auto sp2 = makeBox(offset + Vec2(30, 0), Size(30, 10));

//        auto sp2PhysicsBody = sp2->getPhysicsBody();

//        sp2PhysicsBody->setTag(DRAG_BODYS_TAG);

//    

//        getPhysicsWorld()->addJoint(PhysicsJointPin::construct(sp1PhysicsBody, box, sp1->getPosition()));

//        getPhysicsWorld()->addJoint(PhysicsJointPin::construct(sp2PhysicsBody, box, sp2->getPosition()));

//        PhysicsJointRatchet* joint = PhysicsJointRatchet::construct(sp1PhysicsBody, sp2PhysicsBody, 0.0f, (float)M_PI_2);

//        getPhysicsWorld()->addJoint(joint);

    

    //让两个刚体之间的旋转角速度保持一个常数

//        auto sp1 = makeBox(offset - Vec2(30, 0), Size(30, 10));

//        auto sp1PhysicsBody = sp1->getPhysicsBody();

//        sp1PhysicsBody->setTag(DRAG_BODYS_TAG);

//    

//        auto sp2 = makeBox(offset + Vec2(30, 0), Size(30, 10));

//        auto sp2PhysicsBody = sp2->getPhysicsBody();

//        sp2PhysicsBody->setTag(DRAG_BODYS_TAG);

//    

//        getPhysicsWorld()->addJoint(PhysicsJointPin::construct(sp1PhysicsBody, box, sp1->getPosition()));

//        getPhysicsWorld()->addJoint(PhysicsJointPin::construct(sp2PhysicsBody, box, sp2->getPosition()));

//        PhysicsJointGear* joint = PhysicsJointGear::construct(sp1PhysicsBody, sp2PhysicsBody, 0.0f, 2.0f);

//        getPhysicsWorld()->addJoint(joint);

//

    //PhysicsJointMotor用于保证两个物体的相对角速度是一个常数

        auto sp1 = makeBox(offset - Vec2(30, 0), Size(30, 10));

        auto sp1PhysicsBody = sp1->getPhysicsBody();

        sp1PhysicsBody->setTag(DRAG_BODYS_TAG);

    

    

      

        auto sp2 = makeBox(offset + Vec2(30, 0), Size(30, 10));

        auto sp2PhysicsBody = sp2->getPhysicsBody();

        sp2PhysicsBody->setTag(DRAG_BODYS_TAG);

    

        getPhysicsWorld()->addJoint(PhysicsJointPin::construct(sp1PhysicsBody, box, sp1->getPosition()));

        getPhysicsWorld()->addJoint(PhysicsJointPin::construct(sp2PhysicsBody, box, sp2->getPosition()));

        PhysicsJointMotor* joint = PhysicsJointMotor::construct(sp1PhysicsBody, sp2PhysicsBody, (float)M_PI_2);

        getPhysicsWorld()->addJoint(joint);

    

}


void PhysicsJoints2::onExit(){

    Director::getInstance()->getEventDispatcher()->removeEventListenersForTarget(this);

    Layer::onExit();

    

}


Sprite* PhysicsJoints2::makeBall(Vec2 point, float radius, PhysicsMaterial material)

{

    Sprite* ball = Sprite::create("ball.png");

    ball->setScale(0.13f * radius);

    ball->addComponent(PhysicsBody::createCircle(ball->getContentSize().width / 2, material));

    ball->setPosition(Vec2(point.x, point.y));

    this->addChild(ball);

    return ball;

}


Sprite* PhysicsJoints2::makeBox(Vec2 point, Size size, int color, PhysicsMaterial material)

{

    bool yellow = false;

    if (color == 0)

        yellow = CCRANDOM_0_1() > 0.5f;

    else

        yellow = color == 1;

    

    auto box = yellow ? Sprite::create("YellowSquare.png") : Sprite::create("CyanSquare.png");

    box->setScaleX(size.width / 100.0f);

    box->setScaleY(size.height / 100.0f);

    box->addComponent(PhysicsBody::createBox(box->getContentSize(), material));

    box->setPosition(Vec2(point.x, point.y));

    this->addChild(box);

    return box;

}















猜你喜欢

转载自blog.csdn.net/qq_41939248/article/details/80573221