• 1.物理系统PhysicsWorld,RayCast


    

    1 3.0物理系统PhysicsWorld

    T07PhysicsWorld.h

    #ifndef __T07PhysicsWorld_H__

    #define __T07PhysicsWorld_H__

     

    #include "T32.h"

     

    class T07PhysicsWorld : public Layer

    {

    public:

        CREATE_FUNC(T07PhysicsWorld);

     

        bool init();

        Scene* getScene(){ return (Scene*)getParent(); }

    };

     

    #endif

    T07PhysicsWorld.cpp

    #include "T07PhysicsWorld.h"

     

     

    bool T07PhysicsWorld::init()

    {

        Layer::init();

     

        PhysicsBody* bodyA;

        PhysicsBody* bodyB;

     

        {

            //后面的三个參数值分别表示的是:密度,弹性值。摩擦力

            PhysicsBody* body = PhysicsBody::createCircle(20, PhysicsMaterial(1.0f, 1.0f, 0.0f));

            bodyA = body;

            //创建精灵

            Sprite* sprite = Sprite::create();

            //设置

            sprite->setPhysicsBody(body);

            addChild(sprite);

            //设置精灵的位置

            sprite->setPosition(winSize.width / 2, winSize.height / 2);

            //设置速度

            body->setVelocity(Vect(100, 200));

        }

     

        {

            PhysicsBody* body = PhysicsBody::createEdgeBox(winSize, PhysicsMaterial(1.0f, 1.0f, 0.0f));

            bodyB = body;

            Sprite* sprite = Sprite::create();

            addChild(sprite);

            sprite->setPhysicsBody(body);

            sprite->setPosition(winSize.width / 2, winSize.height / 2);

        }

     

        {

            bodyA->setContactTestBitmask(0x1);

            bodyB->setContactTestBitmask(0x1);

            bodyA->setGroup(1);

            bodyB->setGroup(2);

     

            //设置精灵的

            auto ev = EventListenerPhysicsContactWithBodies::create(bodyA, bodyB);

            ev->onContactBegin = [](PhysicsContact& contact){

                CCLog("Began Contact...........");

                return true;

            };

     

            _eventDispatcher->addEventListenerWithSceneGraphPriority(ev, this);

        }

     

        {

            auto ev = EventListenerPhysicsContactWithShapes::create(bodyA->getShapes().at(0),

                bodyB->getShapes().at(0));

     

            ev->onContactBegin = [](PhysicsContact& contact){

                CCLog("Shape Began Contact...........");

                return true;

            };

     

            _eventDispatcher->addEventListenerWithSceneGraphPriority(ev, this);

        }

     

        {

            auto ev = EventListenerPhysicsContactWithGroup::create(3);

            ev->onContactBegin = [](PhysicsContact& contact){

                CCLog("Group Began Contact...........");

                return true;

            };

            _eventDispatcher->addEventListenerWithSceneGraphPriority(ev, this);

     

        }

     

        return true;

    }

    TMenu.h

    #ifndef __TMenu_H__

    #define __TMenu_H__

     

    #include "T32.h"

     

    class TMenu : public Layer

    {

    public:

        CREATE_FUNC(TMenu);

     

        bool init();

     

        bool TouchBegan(Touch*, Event*);

    };

     

    #endif

    TMenu.cpp

    #include "TMenu.h"

    #include "TBack.h"

    #include "T01CPP11.h"

    #include "T02Vector.h"

    #include "T03Map.h"

    #include "T04Label.h"

    #include "T05Touch.h"

    #include "T06Box2D.h"

    #include "T07PhysicsWorld.h"

     

    static const char* title[] = {

        "T01CPP11",

        "T02Vector",

        "T04Label",

        "T05Touch",

        "T06Box2D",

        "T07PhysicsWorld"

    };

     

    bool TMenu::init()

    {

        Layer::init();

     

        Menu* menu = Menu::create();

        addChild(menu);

     

        for (int i = 0; i < sizeof(title) / sizeof(*title); ++i)

        {

            MenuItemFont* item = MenuItemFont::create(title[i], [](Ref* sender){

     

                MenuItem* item = (MenuItem*)sender;

                int i = item->getTag() - 1000;

                Layer* l = NULL;

     

                if (title[i] == "T01CPP11")   l = T01CPP11::create();

                if (title[i] == "T02Vector")   l = T02Vector::create();

                if (title[i] == "T04Label") l = T04Label::create();

                if (title[i] == "T05Touch") l = T05Touch::create();

                if (title[i] == "T06Box2D") l = T06Box2D::create();

                if (title[i] == "T07PhysicsWorld") l = T07PhysicsWorld::create();

     

                if (l)

                {

                    TBack* b = TBack::create();

                    Scene* s = Scene::createWithPhysics();

     

     

                    PhysicsWorld* world = s->getPhysicsWorld();

                    world->setDebugDrawMask(PhysicsWorld::DEBUGDRAW_ALL);

     

                    s->addChild(b);

                    s->addChild(l);

                    Director::getInstance()->pushScene(s);

                }

            });

            menu->addChild(item);

            item->setTag(1000 + i);

        }

     

        menu->alignItemsVertically();

     

        // 触摸

        auto ev = EventListenerTouchOneByOne::create();

    #if 0

        ev->onTouchBegan = [](Touch*, Event*){

            return true;

        };

    #endif

     

        //ev->onTouchBegan = std::bind(&TMenu::TouchBegan, this, std::placeholders::_1, std::placeholders::_2);

     

        ev->onTouchBegan = CC_CALLBACK_2(TMenu::TouchBegan, this);

     

        ev->onTouchMoved = [&](Touch* touch, Event*){

            setPositionY(getPositionY() + touch->getDelta().y);

        };

        _eventDispatcher->addEventListenerWithSceneGraphPriority(ev, this);

     

        return true;

    }

     

    bool TMenu::TouchBegan(/*TMEnu* this, */Touch*, Event*)

    {

        return true;

    }

    执行结果:

    射线的做法

    T08RayCast.h

    #ifndef __T08RayCast_H__

    #define __T08RayCast_H__

     

    #include "T32.h"

    class T08RayCast :public Layer

    {

    public:

        CREATE_FUNC(T08RayCast);

     

        bool init();

        void onEnter();

        void update(float);

     

        Sprite* _cat;

        int _angle;

        int _distance;

        float _nearDis;

        PhysicsShape* _food;

     

        DrawNode* _drawNode;

    };

     

    #endif

    T08RayCast.cpp

    #include "T08RayCast.h"

     

    void T08RayCast::onEnter()

    {

        Layer::onEnter();

     

        Scene* scene = (Scene*)getParent();

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

    }

     

    bool T08RayCast::init()

    {

        Layer::init();

     

        // 创建猫。猫不是Body,仅仅是一个简单的精灵

        {

            Sprite* cat = Sprite::create("CloseNormal.png");

            addChild(cat);

            cat->setPosition(winSize.width / 2, winSize.height / 2);

            _cat = cat;

        }

     

        // 投放食物。食物必须是body

        {

            auto ev = EventListenerTouchOneByOne::create();

            ev->onTouchBegan = [&](Touch* touch, Event*){

                //得到触摸点

                Vec2 pt = touch->getLocation();

                //创建一个圆形的PhysicsBody

                PhysicsBody* body = PhysicsBody::createCircle(10);

                Sprite* sprite = Sprite::create();

                sprite->setPhysicsBody(body);

                addChild(sprite);

                sprite->setPosition(pt);

     

                return true;

            };

            _eventDispatcher->addEventListenerWithSceneGraphPriority(ev, this);

        }

     

        {

            _angle = 0;      //角度

            _distance = 100; //距离

            _nearDis = _distance + 100;

            _food = NULL;

            _drawNode = NULL;

        }

        scheduleUpdate();

     

        return true;

    }

     

    void T08RayCast::update(float dt)

    {

        Scene* scene = (Scene*)getParent();

        PhysicsWorld* world = scene->getPhysicsWorld();

     

        //获得猫的位置

        Vec2 start = _cat->getPosition();

        Vec2 end;

     

        //当前时刻扫描到的终点位置

        end.x = start.x + sinf(_angle / 180.0 * M_PI)*_distance;

        end.y = start.y + cosf(_angle / 180.0 * M_PI)*_distance;

     

        // 显示扫描距离

        if (_drawNode) _drawNode->removeFromParent();

        //以下的代码用于画线段

        _drawNode = DrawNode::create();

        _drawNode->drawSegment(start, end, 1, Color4F(1, 0, 0, 1));

        addChild(_drawNode);

     

        // 扫描回调函数

        //bool(PhysicsWorld& world, const PhysicsRayCastInfo& info, void* data)

        auto callback = [&](PhysicsWorld& world, const PhysicsRayCastInfo& info, void* data){

     

            if (info.shape == NULL)

                return true;

     

            //假设点包括猫的点

            float dis = info.contact.getDistance(_cat->getPosition());

            if (dis < _nearDis)

            {

                _nearDis = dis;

                _food = info.shape;

            }

     

            // 扫描到一个就不要再继续了

            return false;

        };

        //通过rayCast画一条射线

        world->rayCast(callback, start, end, NULL);

     

        //每次角度加2

        _angle += 2;

        //假设角度为360

        if (_angle == 360)

        {

            //假设存在食物

            if (_food)

            {

                // 吃掉食物

                Node* node = _food->getBody()->getNode();

                //将猫的的位置数值到新的位置

                _cat->setPosition(node->getPosition());

                node->removeFromParent();

     

                _food = NULL;

                _nearDis = _distance + 100;

            }

     

            _angle = 0;

        }

    }

    执行结果:




    1 3.0物理系统PhysicsWorld


    T07PhysicsWorld.h

    #ifndef __T07PhysicsWorld_H__

    #define __T07PhysicsWorld_H__

     

    #include "T32.h"

     

    class T07PhysicsWorld : public Layer

    {

    public:

        CREATE_FUNC(T07PhysicsWorld);

     

        bool init();

        Scene* getScene(){ return (Scene*)getParent(); }

    };

     

    #endif

    T07PhysicsWorld.cpp

    #include "T07PhysicsWorld.h"

     

     

    bool T07PhysicsWorld::init()

    {

        Layer::init();

     

        PhysicsBody* bodyA;

        PhysicsBody* bodyB;

     

        {

            //后面的三个參数值分别表示的是:密度,弹性值。摩擦力

            PhysicsBody* body = PhysicsBody::createCircle(20, PhysicsMaterial(1.0f, 1.0f, 0.0f));

            bodyA = body;

            //创建精灵

            Sprite* sprite = Sprite::create();

            //设置

            sprite->setPhysicsBody(body);

            addChild(sprite);

            //设置精灵的位置

            sprite->setPosition(winSize.width / 2, winSize.height / 2);

            //设置速度

            body->setVelocity(Vect(100, 200));

        }

     

        {

            PhysicsBody* body = PhysicsBody::createEdgeBox(winSize, PhysicsMaterial(1.0f, 1.0f, 0.0f));

            bodyB = body;

            Sprite* sprite = Sprite::create();

            addChild(sprite);

            sprite->setPhysicsBody(body);

            sprite->setPosition(winSize.width / 2, winSize.height / 2);

        }

     

        {

            bodyA->setContactTestBitmask(0x1);

            bodyB->setContactTestBitmask(0x1);

            bodyA->setGroup(1);

            bodyB->setGroup(2);

     

            //设置精灵的

            auto ev = EventListenerPhysicsContactWithBodies::create(bodyA, bodyB);

            ev->onContactBegin = [](PhysicsContact& contact){

                CCLog("Began Contact...........");

                return true;

            };

     

            _eventDispatcher->addEventListenerWithSceneGraphPriority(ev, this);

        }

     

        {

            auto ev = EventListenerPhysicsContactWithShapes::create(bodyA->getShapes().at(0),

                bodyB->getShapes().at(0));

     

            ev->onContactBegin = [](PhysicsContact& contact){

                CCLog("Shape Began Contact...........");

                return true;

            };

     

            _eventDispatcher->addEventListenerWithSceneGraphPriority(ev, this);

        }

     

        {

            auto ev = EventListenerPhysicsContactWithGroup::create(3);

            ev->onContactBegin = [](PhysicsContact& contact){

                CCLog("Group Began Contact...........");

                return true;

            };

            _eventDispatcher->addEventListenerWithSceneGraphPriority(ev, this);

     

        }

     

        return true;

    }

    TMenu.h

    #ifndef __TMenu_H__

    #define __TMenu_H__

     

    #include "T32.h"

     

    class TMenu : public Layer

    {

    public:

        CREATE_FUNC(TMenu);

     

        bool init();

     

        bool TouchBegan(Touch*, Event*);

    };

     

    #endif

    TMenu.cpp

    #include "TMenu.h"

    #include "TBack.h"

    #include "T01CPP11.h"

    #include "T02Vector.h"

    #include "T03Map.h"

    #include "T04Label.h"

    #include "T05Touch.h"

    #include "T06Box2D.h"

    #include "T07PhysicsWorld.h"

     

    static const char* title[] = {

        "T01CPP11",

        "T02Vector",

        "T04Label",

        "T05Touch",

        "T06Box2D",

        "T07PhysicsWorld"

    };

     

    bool TMenu::init()

    {

        Layer::init();

     

        Menu* menu = Menu::create();

        addChild(menu);

     

        for (int i = 0; i < sizeof(title) / sizeof(*title); ++i)

        {

            MenuItemFont* item = MenuItemFont::create(title[i], [](Ref* sender){

     

                MenuItem* item = (MenuItem*)sender;

                int i = item->getTag() - 1000;

                Layer* l = NULL;

     

                if (title[i] == "T01CPP11")   l = T01CPP11::create();

                if (title[i] == "T02Vector")   l = T02Vector::create();

                if (title[i] == "T04Label") l = T04Label::create();

                if (title[i] == "T05Touch") l = T05Touch::create();

                if (title[i] == "T06Box2D") l = T06Box2D::create();

                if (title[i] == "T07PhysicsWorld") l = T07PhysicsWorld::create();

     

                if (l)

                {

                    TBack* b = TBack::create();

                    Scene* s = Scene::createWithPhysics();

     

     

                    PhysicsWorld* world = s->getPhysicsWorld();

                    world->setDebugDrawMask(PhysicsWorld::DEBUGDRAW_ALL);

     

                    s->addChild(b);

                    s->addChild(l);

                    Director::getInstance()->pushScene(s);

                }

            });

            menu->addChild(item);

            item->setTag(1000 + i);

        }

     

        menu->alignItemsVertically();

     

        // 触摸

        auto ev = EventListenerTouchOneByOne::create();

    #if 0

        ev->onTouchBegan = [](Touch*, Event*){

            return true;

        };

    #endif

     

        //ev->onTouchBegan = std::bind(&TMenu::TouchBegan, this, std::placeholders::_1, std::placeholders::_2);

     

        ev->onTouchBegan = CC_CALLBACK_2(TMenu::TouchBegan, this);

     

        ev->onTouchMoved = [&](Touch* touch, Event*){

            setPositionY(getPositionY() + touch->getDelta().y);

        };

        _eventDispatcher->addEventListenerWithSceneGraphPriority(ev, this);

     

        return true;

    }

     

    bool TMenu::TouchBegan(/*TMEnu* this, */Touch*, Event*)

    {

        return true;

    }

    执行结果:


    射线的做法


    T08RayCast.h

    #ifndef __T08RayCast_H__

    #define __T08RayCast_H__

     

    #include "T32.h"

    class T08RayCast :public Layer

    {

    public:

        CREATE_FUNC(T08RayCast);

     

        bool init();

        void onEnter();

        void update(float);

     

        Sprite* _cat;

        int _angle;

        int _distance;

        float _nearDis;

        PhysicsShape* _food;

     

        DrawNode* _drawNode;

    };

     

    #endif

    T08RayCast.cpp

    #include "T08RayCast.h"

     

    void T08RayCast::onEnter()

    {

        Layer::onEnter();

     

        Scene* scene = (Scene*)getParent();

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

    }

     

    bool T08RayCast::init()

    {

        Layer::init();

     

        // 创建猫,猫不是Body,仅仅是一个简单的精灵

        {

            Sprite* cat = Sprite::create("CloseNormal.png");

            addChild(cat);

            cat->setPosition(winSize.width / 2, winSize.height / 2);

            _cat = cat;

        }

     

        // 投放食物。食物必须是body

        {

            auto ev = EventListenerTouchOneByOne::create();

            ev->onTouchBegan = [&](Touch* touch, Event*){

                //得到触摸点

                Vec2 pt = touch->getLocation();

                //创建一个圆形的PhysicsBody

                PhysicsBody* body = PhysicsBody::createCircle(10);

                Sprite* sprite = Sprite::create();

                sprite->setPhysicsBody(body);

                addChild(sprite);

                sprite->setPosition(pt);

     

                return true;

            };

            _eventDispatcher->addEventListenerWithSceneGraphPriority(ev, this);

        }

     

        {

            _angle = 0;      //角度

            _distance = 100; //距离

            _nearDis = _distance + 100;

            _food = NULL;

            _drawNode = NULL;

        }

        scheduleUpdate();

     

        return true;

    }

     

    void T08RayCast::update(float dt)

    {

        Scene* scene = (Scene*)getParent();

        PhysicsWorld* world = scene->getPhysicsWorld();

     

        //获得猫的位置

        Vec2 start = _cat->getPosition();

        Vec2 end;

     

        //当前时刻扫描到的终点位置

        end.x = start.x + sinf(_angle / 180.0 * M_PI)*_distance;

        end.y = start.y + cosf(_angle / 180.0 * M_PI)*_distance;

     

        // 显示扫描距离

        if (_drawNode) _drawNode->removeFromParent();

        //以下的代码用于画线段

        _drawNode = DrawNode::create();

        _drawNode->drawSegment(start, end, 1, Color4F(1, 0, 0, 1));

        addChild(_drawNode);

     

        // 扫描回调函数

        //bool(PhysicsWorld& world, const PhysicsRayCastInfo& info, void* data)

        auto callback = [&](PhysicsWorld& world, const PhysicsRayCastInfo& info, void* data){

     

            if (info.shape == NULL)

                return true;

     

            //假设点包括猫的点

            float dis = info.contact.getDistance(_cat->getPosition());

            if (dis < _nearDis)

            {

                _nearDis = dis;

                _food = info.shape;

            }

     

            // 扫描到一个就不要再继续了

            return false;

        };

        //通过rayCast画一条射线

        world->rayCast(callback, start, end, NULL);

     

        //每次角度加2

        _angle += 2;

        //假设角度为360

        if (_angle == 360)

        {

            //假设存在食物

            if (_food)

            {

                // 吃掉食物

                Node* node = _food->getBody()->getNode();

                //将猫的的位置数值到新的位置

                _cat->setPosition(node->getPosition());

                node->removeFromParent();

     

                _food = NULL;

                _nearDis = _distance + 100;

            }

     

            _angle = 0;

        }

    }

    执行结果:


     




     

  • 相关阅读:
    R语言与医学统计图形-【25】ggplot图形分面
    R语言与医学统计图形-【21】ggplot2标题
    R语言与医学统计图形-【24】ggplot位置调整函数
    R语言与医学统计图形-【23】ggplot2坐标系转换函数
    R语言与医学统计图形-【22】ggplot2统计变换函数
    R语言与医学统计图形-【20】ggplot2图例
    Android开发教程
    寒假来临,开启脚本语言的学习
    汇编语言学习资料
    SORT函数的使用方法(转载)
  • 原文地址:https://www.cnblogs.com/jzssuanfa/p/6940729.html
Copyright © 2020-2023  润新知