物理引擎Chipmunk--引力球

这篇博客介绍如何在Cocos2d-x中利用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);

private:

    Node * edgeShape;

    Size visiableSize;

    Vec2 center;

    PhysicsBody* _touchBody;

    DrawNode * draw;

};


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;

    //创建一个碰撞图形

    edgeShape=Node::create();

    //添加进图层

    this->addChild( edgeShape );

    

    

    

    auto Bg=Sprite::create();

    Bg->setScale(2);

    Bg->setPosition(Vec2(0, 0));

    edgeShape->addChild(Bg);

    

    

    

    auto body= PhysicsBody::createEdgeBox(Bg->getContentSize(),PHYSICSBODY_MATERIAL_DEFAULT,5);

    //恢复力和摩擦力

    body->getShape(0)->setRestitution(1.f);

    body->getShape(0)->setFriction(10.f);

    

    edgeShape->setPhysicsBody(body);

    //设置图开的位置在屏幕正中间

    edgeShape->setPosition(Vec2(visiableSize.width/2,visiableSize.height/2));

    

    

    

    

    //画线

    draw=DrawNode::create();

    edgeShape->addChild(draw);

    

    //中心图片

    auto centerBall=Sprite::create("ball2.jpg");

    centerBall->setScale(0.05);

    centerBall->addComponent(PhysicsBody::createCircle(centerBall->getContentSize().width / 2, PHYSICSSHAPE_MATERIAL_DEFAULT));

    centerBall->setPosition(Vec2(0,0));

    edgeShape->addChild(centerBall);

    

    auto sp1PhysicsBody = centerBall->getPhysicsBody();

    sp1PhysicsBody->setDynamic(false);

    sp1PhysicsBody->setTag(1);

    

    

    

    

    //移动的图片

    auto ball = Sprite::create("ball2.jpg");

    ball->setPosition(Vec2(0, 200));

    ball->setScale(0.05);

    edgeShape->addChild(ball);

    ball->addComponent(PhysicsBody::createCircle(ball->getContentSize().height /2, PHYSICSSHAPE_MATERIAL_DEFAULT));

    auto sp2PhysicsBody = ball->getPhysicsBody();

    sp2PhysicsBody->setTag(1);

    sp2PhysicsBody->getShape(0)->setMass(10);

    

    

    

    draw->drawLine(centerBall->getPosition(), ball->getPosition(), Color4F::YELLOW);

    draw->setLineWidth(2);

    schedule([=](float dt)

             {

                 //清除所有力

                 sp2PhysicsBody->resetForces();

                 //固定-移动的位置

                 Vec2 f=sp1PhysicsBody->getPosition() - sp2PhysicsBody->getPosition();

                 float forceX=f.x;

                 float forceY=f.y;

                 

                 //绝对值

                 float forceZ=sqrt(forceX*forceX+forceY*forceY);

                 float X=forceX/forceZ*20;

                 float Y=forceY/forceZ*20;

                 Vect force=Vect(X, Y);

                 //添加个力

                 sp2PhysicsBody->applyImpulse(force);

                 //画线

                 draw->clear();

                 //固定  移动  的点

                 draw->drawLine(centerBall->getPosition(), ball->getPosition(), Color4F::WHITE);

                 draw->setLineWidth(2);

                 cout<<"=="<<endl;

             }, "play1");

    

    

    

    

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

    auto touchListener = EventListenerTouchOneByOne::create();

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

        cout<<1<<endl;

        

        schedule([=](float dt)

                 {

                     Vec2 f=centerBall->getPosition() - ball->getPosition();

                     float forceX=f.x;

                     float forceY=f.y;

                     float forceZ=sqrt(forceX*forceX+forceY*forceY);

                     float X=forceX/forceZ*5;

                     float Y=forceY/forceZ*5;

                     Vect force=Vect(-Y, X);

                     sp2PhysicsBody->applyImpulse(force);

                     //                     Vect force1=Vect(X*2, Y*2);

                     //                     sp2PhysicsBody->applyImpulse(force1);

                     cout<<2<<endl;

                 }, "play2");

        return true;

    };

    

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

    };

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

        unschedule("play2");

        sp2PhysicsBody->setVelocity(Vec2(0, 0));

        

    };

    

    dispatcher->addEventListenerWithSceneGraphPriority(touchListener, this);

    

    

    

    return true;

}


PhysicsWorld* PhysicsJoints2::getPhysicsWorld(){

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

}



void PhysicsJoints2::onEnter(){

    Layer::onEnter();

    

    

}


void PhysicsJoints2::onExit(){

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

    Layer::onExit();

    

}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值