• Cocos2d-x3.1TestCpp之NewRenderTest Demo分析


    1、代码构成

    VisibleRect.h
    VisibleRect.cpp
    AppDelegate.h
    AppDelegate.cpp
    HelloWorldScene.h
    HelloWorldScene.cpp
    NewRenderTest.h
    NewRenderTest.cpp

    2、HelloWorld代码

    #include "cocos2d.h"
    #include "ui/CocosGUI.h"
    USING_NS_CC;
    using namespace ui;
    
    class HelloWorld : public cocos2d::Layer
    {
    public:
        // there's no 'id' in cpp, so we recommend returning the class instance pointer
        static cocos2d::Scene* createScene();
    
        // Here's a difference. Method 'init' in cocos2d-x returns bool, instead of returning 'id' in cocos2d-iphone
        virtual bool init();  
        
        // a selector callback
        void menuCloseCallback(cocos2d::Ref* pSender);
        void touchEvent(Ref *pSender, cocos2d::ui::Widget::TouchEventType type);
    
        // implement the "static create()" method manually
        CREATE_FUNC(HelloWorld);
    };

    #include "HelloWorldScene.h"
    #include "NewRenderTest.h"
    USING_NS_CC;
    
    Scene* HelloWorld::createScene()
    {
        // 'scene' is an autorelease object
        auto scene = Scene::create();
        
        // '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;
        }
        
        Size visibleSize = Director::getInstance()->getVisibleSize();
        Vec2 origin = Director::getInstance()->getVisibleOrigin();
    
        /////////////////////////////
        // 2. add a menu item with "X" image, which is clicked to quit the program
        //    you may modify it.
    
        // add a "close" icon to exit the progress. it's an autorelease object
        auto closeItem = MenuItemImage::create(
                                               "CloseNormal.png",
                                               "CloseSelected.png",
                                               CC_CALLBACK_1(HelloWorld::menuCloseCallback, this));
        
    	closeItem->setPosition(Vec2(origin.x + visibleSize.width - closeItem->getContentSize().width/2 ,
                                    origin.y + closeItem->getContentSize().height/2));
    
        // create menu, it's an autorelease object
        auto menu = Menu::create(closeItem, NULL);
        menu->setPosition(Vec2::ZERO);
        this->addChild(menu, 1);
    
        auto text = Text::create();
        text->setString("click");
        text->setFontSize(40);
        text->setPosition(Vec2(200,200));
        addChild(text);
        text->addTouchEventListener(CC_CALLBACK_2(HelloWorld::touchEvent, this));
        
        return true;
    }
    
    void HelloWorld::touchEvent(cocos2d::Ref *pSender, cocos2d::ui::Widget::TouchEventType type)
    {
        switch (type) {
            case cocos2d::ui::Widget::TouchEventType::ENDED:
            {
                auto temp = NewRendererDemo::create();
                Director::getInstance()->replaceScene(temp);
                break;
            }
            default:
                break;
        }
    }
    
    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");
        return;
    #endif
    
        Director::getInstance()->end();
    
    #if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
        exit(0);
    #endif
    }

    3、NewRendererTest代码

    #include "cocos2d.h"
    #include "ui/CocosGUI.h"
    #include "VisibleRect.h"
    #include "../cocos2d/cocos/renderer/CCRenderer.h"
    USING_NS_CC;
    using namespace ui;
    //宏定义,用于NewClippingNodeTest
    #define kTagSpriteBatchNode 100
    #define kTagClipperNode     101
    #define kTagContentNode     102
    //父类Scene。首先执行HelloWorld中的Scene,然后该Scene类replace HelloWorld使用的Scene
    class NewRendererDemo : public Scene
    {
    public:
        CREATE_FUNC(NewRendererDemo);
        virtual bool init();
    };
    //父类Layer,该Layer载入NewRenderDemo所创建的Scene上
    class BaseTest : public cocos2d::Layer
    {
    public:
        CREATE_FUNC(BaseTest);
        virtual std::string title() const;//标题
        virtual std::string subtitle() const;//副标题
    
        virtual void restartCallback(Ref* sender);//又一次执行当前test
        virtual void nextCallback(Ref* sender);//下一个test
        virtual void backCallback(Ref* sender);//上一个test
        
        virtual bool init();
        void menuCloseCallback(cocos2d::Ref* pSender);//关闭菜单回调函数
    };
    //基类Layer,全部測试Demo均继承自该类,而该类继承自BaseTest。BaseTest继承自Layer
    class MultiSceneTest : public BaseTest
    {
    public:
        CREATE_FUNC(MultiSceneTest);
        virtual std::string title() const;
        virtual std::string subtitle() const;
        
        virtual void restartCallback(Ref* sender);
        virtual void nextCallback(Ref* sender);
        virtual void backCallback(Ref* sender);
    };
    //第一个測试
    class NewSpriteTest : public MultiSceneTest
    {
    public:
        CREATE_FUNC(NewSpriteTest);
        virtual std::string title() const;
        virtual std::string subtitle() const;
        virtual bool init();
        void createSpriteTest();
        void createNewSpriteTest();
        void onTouchesEnded(const std::vector<Touch*>& touches,Event* event);
    };
    //第二个測试
    class GroupCommandTest : public MultiSceneTest
    {
    public:
        CREATE_FUNC(GroupCommandTest);
        virtual bool init();
        virtual std::string title() const override;
        virtual std::string subtitle() const override;
    };
    //第三个測试
    class NewSpriteBatchTest : public MultiSceneTest
    {
    public:
        CREATE_FUNC(NewSpriteBatchTest);
        virtual bool init();
        virtual std::string title() const override;
        virtual std::string subtitle() const override;
    
        void onTouchesEnded(const std::vector<Touch*>& touches,Event* event);
        void addNewSpriteWithCoords(Vec2 p);
    };
    //第四个測试
    class NewClippingNodeTest : public MultiSceneTest
    {
    public:
        CREATE_FUNC(NewClippingNodeTest);
        virtual bool init();
        virtual std::string title() const override;
        virtual std::string subtitle() const override;
        
        void onTouchesBegan(const std::vector<Touch*>& touches,Event* event);
        void onTouchesMoved(const std::vector<Touch*>& touches,Event* event);
        void onTouchesEnded(const std::vector<Touch*>& touches,Event* event);
        
    protected:
        bool _scrolling;
        Vec2 _lastPoint;
    };
    
    //第五个測试
    class NewDrawNodeTest : public MultiSceneTest
    {
    public:
        CREATE_FUNC(NewDrawNodeTest);
        virtual bool init();
        virtual std::string title() const override;
        virtual std::string subtitle() const override;
    };
    //第六个測试
    class NewCullingTest : public MultiSceneTest
    {
    public:
        CREATE_FUNC(NewCullingTest);
        virtual std::string title() const override;
        virtual std::string subtitle() const override;
        virtual bool init();
    protected:
        bool onTouchBegan(Touch*,Event* event);
        void onTouchMoved(Touch* touch,Event* event);
        Vec2 _lastPos;
    };
    //第七个測试
    class VBOFullTest : public MultiSceneTest
    {
    public:
        CREATE_FUNC(VBOFullTest);
        virtual bool init();
        virtual std::string title() const override;
        virtual std::string subtitle() const override;
    };

    #include "NewRenderTest.h"
    #include "HelloWorldScene.h"
    //宏定义,实现类的创建
    #define CL(__className__) [](){ return __className__::create();}
    #define CLN(__className__) [](){ auto obj = new __className__(); obj->autorelease(); return obj; }
    //基类Layer。实现关闭按钮、下一个測试、当前測试、下一个測试菜单项的布局与事件响应
    bool BaseTest::init()
    {
        bool bRet = true;
        do{
            CC_BREAK_IF(!Layer::init());
            
            Size visibleSize = Director::getInstance()->getVisibleSize();
            Vec2 origin = Director::getInstance()->getVisibleOrigin();
            
            /////////////////////////////
            // 2. add a menu item with "X" image, which is clicked to quit the program
            //    you may modify it.
            
            // add a "close" icon to exit the progress. it's an autorelease object
            auto closeItem = MenuItemImage::create(
                                                   "CloseNormal.png",
                                                   "CloseSelected.png",
                                                   CC_CALLBACK_1(BaseTest::menuCloseCallback, this));
            closeItem->setPosition(Vec2(origin.x + visibleSize.width - closeItem->getContentSize().width/2 ,
                                        origin.y + visibleSize.height - closeItem->getContentSize().height/2));
            
            // create menu, it's an autorelease object
            auto menu1 = Menu::create(closeItem, NULL);
            menu1->setPosition(Vec2::ZERO);
            this->addChild(menu1, 1);
    
            std::string str = title();
            const char * pTitle = str.c_str();
            TTFConfig ttfConfig("tahoma.ttf", 35);
            auto label = Label::createWithTTF(ttfConfig,pTitle);
            addChild(label, 9999);
            label->setPosition( Vec2(VisibleRect::center().x, VisibleRect::top().y - 30) );
            
            std::string strSubtitle = subtitle();
            if( ! strSubtitle.empty() )
            {
                ttfConfig.fontFilePath = "tahoma.ttf";
                ttfConfig.fontSize = 30;
                auto l = Label::createWithTTF(ttfConfig,strSubtitle.c_str());
                addChild(l, 9999);
                l->setPosition( Vec2(VisibleRect::center().x, VisibleRect::top().y - 100) );
            }
            
            auto item1 = MenuItemFont::create("backCallback", CC_CALLBACK_1(BaseTest::backCallback, this) );
            auto item2 = MenuItemFont::create("restartCallback", CC_CALLBACK_1(BaseTest::restartCallback, this) );
            auto item3 = MenuItemFont::create("nextCallback", CC_CALLBACK_1(BaseTest::nextCallback, this) );
            
            auto menu = Menu::create(item1, item2, item3, NULL);
            
            menu->setPosition(Vec2::ZERO);
            item1->setPosition(Vec2(VisibleRect::center().x - item2->getContentSize().width*2, VisibleRect::bottom().y+item2->getContentSize().height/2));
            item2->setPosition(Vec2(VisibleRect::center().x, VisibleRect::bottom().y+item2->getContentSize().height/2));
            item3->setPosition(Vec2(VisibleRect::center().x + item2->getContentSize().width*2, VisibleRect::bottom().y+item2->getContentSize().height/2));
            
            addChild(menu, 9999);
            
            bRet = true;
        }while(0);
        return bRet;
    }
    
    void BaseTest::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");
        return;
    #endif
        
        Director::getInstance()->end();
        
    #if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
        exit(0);
    #endif
    }
    //标题
    std::string BaseTest::title() const
    {
    	return "";
    }
    //副标题
    std::string BaseTest::subtitle() const
    {
    	return "";
    }
    //又一次运行当前test
    void BaseTest::restartCallback(Ref* sender)
    {
    	log("override restart!");
    }
    //下一个test
    void BaseTest::nextCallback(Ref* sender)
    {
    	log("override next!");
    }
    //上一个test
    void BaseTest::backCallback(Ref* sender)
    {
    	log("override back!");
    }
    //索引,用于推断上一个或下一个
    static int sceneIdx = -1;
    //Layer* nextSpriteTestAction();//下一个
    //Layer* backSpriteTestAction();//上一个
    //Layer* restartSpriteTestAction();//当前
    //函数指针数组
    static std::function<Layer*()> createFunctions[] =
    {
        CL(NewSpriteTest),
        CL(NewSpriteBatchTest),
        CL(GroupCommandTest),
        CL(NewClippingNodeTest),
        CL(NewDrawNodeTest),
        CL(NewCullingTest),
        CL(VBOFullTest),
    };
    //获取数组的大小
    #define MAX_LAYER (sizeof(createFunctions) / sizeof(createFunctions[0]))
    //下一个
    Layer* nextTest()
    {
        sceneIdx++;
        sceneIdx = sceneIdx % MAX_LAYER;//循环判定
        auto layer = (createFunctions[sceneIdx])();//调用函数指针数组中sceneIdx的函数
    //    layer->autorelease();
        return layer;
    }
    //同上
    Layer* prevTest()
    {
        sceneIdx--;
        int total = MAX_LAYER;
        if(sceneIdx < 0)
        {
            sceneIdx += total;
        }
        auto layer = (createFunctions[sceneIdx])();
    //    layer->autorelease();
        return layer;
    }
    //同上
    Layer* restartTest()
    {
        auto layer = (createFunctions[sceneIdx])();
    //    layer->autorelease();
        return layer;
    }
    //基类Scene,各DemoTest的Layer的容器,每一个DemoTest分别使用一个Scene
    bool NewRendererDemo::init()
    {
        bool bRet = false;
        do{
            CC_BREAK_IF(!Scene::init());
            
            auto layer = nextTest();//首先运行第一个test
            addChild(layer);
            
            bRet = true;
        }while(0);
        return bRet;
    }
    //基类Layer
    std::string MultiSceneTest::title() const
    {
        return "New Renderer";
    }
    
    std::string MultiSceneTest::subtitle() const
    {
        return "MultiSceneTest";
    }
    //事件回调
    void MultiSceneTest::restartCallback(cocos2d::Ref *sender)
    {
        auto s = new NewRendererDemo();//首先创建一个Scene。然后将当前的test
        s->addChild(restartTest());//Layer载入到当前Scene
        Director::getInstance()->replaceScene(s);//场景切换,第一个场景切换的是HelloWorld中创建的Scene
        s->release();
    }
    //事件回调,原理同上
    void MultiSceneTest::nextCallback(cocos2d::Ref *sender)
    {
        auto s = new NewRendererDemo();
        s->addChild(nextTest());
        Director::getInstance()->replaceScene(s);
        s->release();
    }
    //事件回调,原理同上
    void MultiSceneTest::backCallback(cocos2d::Ref *sender)
    {
        auto s = new NewRendererDemo();
        s->addChild(prevTest());
        Director::getInstance()->replaceScene(s);
        s->release();
    }
    //第一个test
    bool NewSpriteTest::init()
    {
        bool bRet = false;
        do{
            CC_BREAK_IF(!MultiSceneTest::init());
            
            log("MAX_LAYER = %lu",MAX_LAYER);
            auto touchListener = EventListenerTouchAllAtOnce::create();//事件监听
            touchListener->onTouchesEnded = CC_CALLBACK_2(NewSpriteTest::onTouchesEnded,this);
            createSpriteTest();
            createNewSpriteTest();
            
            bRet = true;
        }while(0);
        return bRet;
    }
    
    void NewSpriteTest::createSpriteTest()
    {
        auto winSize = Director::getInstance()->getWinSize();
        
        Sprite* parent = Sprite::create("grossini.png");
        parent->setPosition(winSize.width/4,winSize.height/2);
        Sprite* child1 = Sprite::create("grossinis_sister1.png");
        child1->setPosition(0.0f,-20.0f);
        Sprite* child2 = Sprite::create("grossinis_sister2.png");
        child2->setPosition(20.0f,-20.0f);
        Sprite* child3 = Sprite::create("grossinis_sister1.png");
        child3->setPosition(40.0f,-20.0f);
        Sprite* child4 = Sprite::create("grossinis_sister2.png");
        child4->setPosition(60.0f,-20.0f);
        Sprite* child5 = Sprite::create("grossinis_sister2.png");
        child5->setPosition(80.0f,-20.0f);
        Sprite* child6 = Sprite::create("grossinis_sister2.png");
        child6->setPosition(100.0f,-20.0f);
        Sprite* child7 = Sprite::create("grossinis_sister2.png");
        child7->setPosition(120.0f,-20.0f);
        Sprite* child8 = Sprite::create("grossinis_sister2.png");
        child8->setPosition(140.0f,-20.0f);
        
        parent->addChild(child1);
        parent->addChild(child2);
        parent->addChild(child3);
        parent->addChild(child4);
        parent->addChild(child5);
        parent->addChild(child6);
        parent->addChild(child7);
        parent->addChild(child8);
        addChild(parent);
    }
    
    void NewSpriteTest::createNewSpriteTest()
    {
        auto winSize = Director::getInstance()->getWinSize();
        
        Sprite* parent = Sprite::create("grossini.png");
        parent->setPosition(winSize.width*2/3, winSize.height/2);
        
        Sprite* child1 = Sprite::create("grossinis_sister1.png");
        child1->setPosition(0.0f,-20.0f);
        Sprite* child2 = Sprite::create("grossinis_sister2.png");
        child2->setPosition(20.0f,-20.0f);
        Sprite* child3 = Sprite::create("grossinis_sister1.png");
        child3->setPosition(40.0f,-20.0f);
        Sprite* child4 = Sprite::create("grossinis_sister2.png");
        child4->setPosition(60.0f,-20.0f);
        Sprite* child5 = Sprite::create("grossinis_sister2.png");
        child5->setPosition(80.0f,-20.0f);
        Sprite* child6 = Sprite::create("grossinis_sister2.png");
        child6->setPosition(100.0f,-20.0f);
        Sprite* child7 = Sprite::create("grossinis_sister2.png");
        child7->setPosition(120.0f,-20.0f);
        Sprite* child8 = Sprite::create("grossinis_sister2.png");
        child8->setPosition(140.0f,-20.0f);
        
        parent->addChild(child1);
        parent->addChild(child2);
        parent->addChild(child3);
        parent->addChild(child4);
        parent->addChild(child5);
        parent->addChild(child6);
        parent->addChild(child7);
        parent->addChild(child8);
        addChild(parent);
    }
    
    void NewSpriteTest::onTouchesEnded(const std::vector<Touch *> &touches, cocos2d::Event *event)
    {
        
    }
    
    std::string NewSpriteTest::title() const
    {
        return "Renderer";
    }
    
    std::string NewSpriteTest::subtitle() const
    {
        return "SpriteTest";
    }
    //工具类,通过finename创建Sprite对象
    class SpriteInGroupCommand : public Sprite
    {
    protected:
        GroupCommand _spriteWrapperCommand;
    public:
        static SpriteInGroupCommand* create(const std::string filename);//创建函数
        virtual void draw(Renderer* renderer,const Mat4 &transform,bool transformUpdated) override;
    };
    
    SpriteInGroupCommand* SpriteInGroupCommand::create(const std::string filename)
    {
        SpriteInGroupCommand* sprite = new SpriteInGroupCommand();
        sprite->initWithFile(filename);
        sprite->autorelease();
        return sprite;
    }
    void SpriteInGroupCommand::draw(cocos2d::Renderer *renderer, const cocos2d::Mat4 &transform, bool transformUpdated)
    {
        CCASSERT(renderer, "Renderer is null");
        _spriteWrapperCommand.init(_globalZOrder);
        renderer->addCommand(&_spriteWrapperCommand);
        renderer->pushGroup(_spriteWrapperCommand.getRenderQueueID());
        Sprite::draw(renderer, transform, transformUpdated);
        renderer->popGroup();
    }
    //第二个test
    bool GroupCommandTest::GroupCommandTest::init()
    {
        bool bRet = false;
        do{
            CC_BREAK_IF(!MultiSceneTest::init());
            
            auto sprite = SpriteInGroupCommand::create("grossini.png");//使用工具类创建对象
            Size winSize = Director::getInstance()->getWinSize();
            sprite->setPosition(Vec2(winSize.width/2,winSize.height/2));
            addChild(sprite);
            bRet = true;
        }while(0);
        return bRet;
    }
    std::string GroupCommandTest::title() const
    {
        return "Renderer";
    }
    std::string GroupCommandTest::subtitle() const
    {
        return "GroupCommandTest: You should see a sprite";
    }
    //第三个test
    bool NewSpriteBatchTest::init()
    {
        bool bRet = false;
        do{
            CC_BREAK_IF(!MultiSceneTest::init());
            //事件监听
            auto touchListener = EventListenerTouchAllAtOnce::create();
            touchListener->onTouchesEnded = CC_CALLBACK_2(NewSpriteBatchTest::onTouchesEnded,this);
            Director::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraphPriority(touchListener, this);//加入到事件分发器
            auto batchNode = SpriteBatchNode::create("grossini_dance_atlas.png");//使用SpriteBatchNode创建对象
            addChild(batchNode,0,kTagSpriteBatchNode);
            bRet = true;
        }while(0);
        return bRet;
    }
    
    std::string NewSpriteBatchTest::title() const
    {
        return "Renderer";
    }
    std::string NewSpriteBatchTest::subtitle() const
    {
        return "SpriteBatchTest";
    }
    void NewSpriteBatchTest::onTouchesEnded(const std::vector<Touch *> &touches, cocos2d::Event *event)
    {
        for(auto &touch : touches)
        {
            auto location = touch->getLocation();
            addNewSpriteWithCoords(location);
        }
    }
    
    void NewSpriteBatchTest::addNewSpriteWithCoords(cocos2d::Vec2 p)
    {
        auto batchNode = static_cast<SpriteBatchNode*>(getChildByTag(kTagSpriteBatchNode));
        
        int idx = (int)(CCRANDOM_0_1() * 1400 / 100);
        log("idx = %d",idx);
        int x = (idx%5)*85;
        int y = (idx%5)*121;
        
        auto sprite = Sprite::createWithTexture(batchNode->getTexture(),Rect(x,y,85,121));//随机获取资源文件里的Sprite对象
        batchNode->addChild(sprite);
        sprite->setPosition(Vec2(p.x,p.y));
        //随机运行动作
        ActionInterval* action;
        float random = CCRANDOM_0_1();
        if(random < 0.20)
            action = ScaleBy::create(3, 2);
        else if (random < 0.40)
            action = RotateBy::create(3, 360);
        else if (random < 0.60)
            action = Blink::create(1, 3);
        else if (random < 0.8)
            action = TintBy::create(2, 0, -255, -255);
        else
            action = FadeOut::create(2);
        
        auto action_back = action->reverse();
        auto seq = Sequence::create(action,action_back, NULL);
        sprite->runAction(RepeatForever::create(seq));
    }
    //第四个test
    bool NewClippingNodeTest::init()
    {
        bool bRet;
        do{
            CC_BREAK_IF(!MultiSceneTest::init());
            
            auto winSize = Director::getInstance()->getWinSize();
            auto clipper = ClippingNode::create();//创建剪裁对象
            clipper->setTag(kTagClipperNode);
            clipper->setContentSize(Size(200, 200));//设置setContentSize(),点击该区域就可以实现content的移动,它的size与模板stencil的Size没有关系。仅仅要点击区域在clipper设置的ContentSize内就可以拖动content的图片,好像。设置的contentSize越大,content图片越小。

    不知道为什么? clipper->ignoreAnchorPointForPosition(false); clipper->setAnchorPoint(Vec2::ANCHOR_MIDDLE); clipper->setPosition(Vec2(winSize.width/2,winSize.height/2)); clipper->runAction(RepeatForever::create(RotateBy::create(1, 45)));//旋转 addChild(clipper); clipper->setAlphaThreshold(0.05f);//属性设置 auto stencil = Sprite::create("grossini.png"); stencil->ignoreAnchorPointForPosition(false); stencil->setAnchorPoint(Vec2::ANCHOR_MIDDLE); clipper->setStencil(stencil);//模板设置 //模板也可为DrawNode,可凝视掉上面stencil的定义,取消此处凝视。查看效果 // auto stencil = DrawNode::create(); // Vec2 rectangle[4]; // rectangle[0] = Vec2(0, 0); // rectangle[1] = Vec2(clipper->getContentSize().width, 0); // rectangle[2] = Vec2(clipper->getContentSize().width, clipper->getContentSize().height); // rectangle[3] = Vec2(0, clipper->getContentSize().height); // // Color4F white(1, 1, 1, 1); // stencil->drawPolygon(rectangle, 4, white, 1, white); // clipper->setStencil(stencil); //设置剪裁检点要显示的内容 auto content = Sprite::create("HelloWorld.png"); content->setTag(kTagContentNode); content->ignoreAnchorPointForPosition(false); content->setAnchorPoint(Vec2::ANCHOR_MIDDLE); content->setPosition(Vec2(clipper->getContentSize().width/2,clipper->getContentSize().height/2)); clipper->addChild(content); _scrolling = false; //此处为測试用的。与demo无关 auto sprite = Sprite::create("grossini.png"); sprite->setPosition(Vec2(winSize.width/4,winSize.height/2)); addChild(sprite); //多点触摸事件处理 auto listener = EventListenerTouchAllAtOnce::create(); listener->onTouchesBegan = CC_CALLBACK_2(NewClippingNodeTest::onTouchesBegan,this); listener->onTouchesMoved = CC_CALLBACK_2(NewClippingNodeTest::onTouchesMoved,this); listener->onTouchesEnded = CC_CALLBACK_2(NewClippingNodeTest::onTouchesEnded,this); Director::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraphPriority(listener, this); bRet = true; }while(0); return bRet; } void NewClippingNodeTest::onTouchesBegan(const std::vector<Touch *> &touches, cocos2d::Event *event) { Touch* touch = touches[0]; auto clipper = this->getChildByTag(kTagClipperNode); Vec2 point = clipper->convertToNodeSpace(Director::getInstance()->convertToGL(touch->getLocation())); log("point.w = %f,point.h = %f",point.x,point.y); auto rect = Rect(0,0,clipper->getContentSize().width,clipper->getContentSize().height); log("clipper.w = %f,clipper.h = %f",clipper->getContentSize().width,clipper->getContentSize().height); _scrolling = rect.containsPoint(point); _lastPoint = point; } //使content图片尾随触摸点移动 void NewClippingNodeTest::onTouchesMoved(const std::vector<Touch *> &touches, cocos2d::Event *event) { if(!_scrolling) return; Touch* touch = touches[0]; auto clipper = this->getChildByTag(kTagClipperNode); auto point = clipper->convertToNodeSpace(Director::getInstance()->convertToGL(touch->getLocationInView())); Vec2 diff = point - _lastPoint; auto content = clipper->getChildByTag(kTagContentNode); content->setPosition(content->getPosition() + diff); _lastPoint = point; } void NewClippingNodeTest::onTouchesEnded(const std::vector<Touch *> &touches, cocos2d::Event *event) { if(!_scrolling) return; _scrolling = false; } std::string NewClippingNodeTest::title() const { return "New Renderer"; } std::string NewClippingNodeTest::subtitle() const { return "ClipNode"; } //第五个test bool NewDrawNodeTest::init() { bool bRet = false; do{ CC_BREAK_IF(!MultiSceneTest::init()); auto winSize = Director::getInstance()->getWinSize(); auto parent = Node::create(); // parent->setPosition(winSize.width/2,winSize.height/2); addChild(parent); auto rectNode = DrawNode::create(); Vec2 rectangle[4]; rectangle[0] = Vec2(-50,-50); rectangle[1] = Vec2(50,-50); rectangle[2] = Vec2(50,50); rectangle[3] = Vec2(-50,50); Color4F white(1,1,1,1); rectNode->drawPolygon(rectangle, 4, white, 1, white);//使用DrawNode创建对象 rectNode->setPosition(winSize.width/4,winSize.height/4); parent->addChild(rectNode); bRet = true; }while(0); return bRet; } std::string NewDrawNodeTest::title() const { return "New Renderer"; } std::string NewDrawNodeTest::subtitle() const { return "DrawNode"; } //第六个test bool NewCullingTest::init() { bool bRet = false; do{ CC_BREAK_IF(!MultiSceneTest::init()); auto winSize = Director::getInstance()->getWinSize(); auto sprite = Sprite::create("btn-about-normal-vertical.png"); sprite->setRotation(5); sprite->setPosition(Vec2(winSize.width/2,winSize.height/3)); sprite->setScale(2); addChild(sprite); auto sprite2 = Sprite::create("btn-about-normal-vertical.png"); sprite2->setRotation(-85); sprite2->setPosition(Vec2(winSize.width/2,winSize.height*2/3)); sprite2->setScale(2); addChild(sprite2); //触摸事件处理 auto listener = EventListenerTouchOneByOne::create(); listener->setSwallowTouches(true); listener->onTouchBegan = CC_CALLBACK_2(NewCullingTest::onTouchBegan,this); listener->onTouchMoved = CC_CALLBACK_2(NewCullingTest::onTouchMoved, this); Director::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraphPriority(listener, this); bRet = true; }while(0); return bRet; } bool NewCullingTest::onTouchBegan(cocos2d::Touch *touch, cocos2d::Event *event) { auto pos = touch->getLocation(); _lastPos = pos; return true; } //移动Layer void NewCullingTest::onTouchMoved(cocos2d::Touch *touch, cocos2d::Event *event) { auto pos = touch->getLocation(); auto offset = pos - _lastPos; auto layerPos = getPosition(); auto newPos = layerPos + offset; setPosition(newPos); _lastPos = pos; } std::string NewCullingTest::title() const { return "New Render"; } std::string NewCullingTest::subtitle() const { return "Drag the layer to test the result of culling"; } //该測试没发现使用的意义 bool VBOFullTest::init() { bool bRet = false; do{ CC_BREAK_IF(!MultiSceneTest::init()); auto winSize = Director::getInstance()->getWinSize(); Node* parent = Node::create(); parent->setPosition(Vec2(winSize.width/2, winSize.height/2)); addChild(parent); log("Renderer::VBO_SIZE = %d",Renderer::VBO_SIZE); for(int i = 0; i < Renderer::VBO_SIZE * 2; ++i) { Sprite* sprite = Sprite::create("grossini_dance_01.png"); sprite->setPosition(Vec2(i,0)); parent->addChild(sprite); } bRet = true; }while(0); return bRet; } std::string VBOFullTest::title() const { return "New Renderer"; } std::string VBOFullTest::subtitle() const { return "VBO full test,everything should render normally"; }

    4、VisibleRect代码

            该代码即testcppproject给出的代码。不再赘述。



  • 相关阅读:
    浅谈 Nginx 的内部核心架构设计
    项目中常用的19条MySQL优化
    Redis分布式锁的正确实现方式
    C# 读取XML文件示例
    C# LINQ to XML示例
    最新的极光推送服务器端代码(java服务器后台向手机端自定义推送消息)
    极光推送>>java SDK服务端集成后台项目(使用详解)
    关于如何在Listener中注入service和ServletContextListener源码分析
    mysql 去除重复 Select中DISTINCT关键字的用法 在使用mysql时,有时需要查询出某个字段不重复的记录,虽然mysql提供 有distinct这个关键字来过滤掉多余的重复记录只保留一条,但往往只用它来返回不重复记录的条数,而不是用它来返回不重记录的所有值。其原因是 distinct只能返回它的目标字段,而无法返回其它字段,这个问题让我困扰了很久,用distinct不能解决的话,
    Spring 整合 Quartz 实现动态定时任务
  • 原文地址:https://www.cnblogs.com/yxwkf/p/5413910.html
Copyright © 2020-2023  润新知