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代码

该代码即testcpp工程给出的代码。不再赘述。

时间: 2024-10-21 19:09:19

Cocos2d-x3.1TestCpp之NewRenderTest Demo分析的相关文章

Cocos2d-x3.1TestCpp之MotionStreakTest Demo分析

1.构成代码 VisibleRect.h VisibleRect.cpp AppDelegate.h AppDelegate.cpp HelloWorldScene.h HelloWorldScene.cpp MotionStreakDemo.h MotionStreakDemo.cpp 2.代码分析 (1)VisibleRect.Appdelegate的代码均为TestCpp提供代码: (2)HelloWorldScene.cpp中只需把上一篇Cocos2d-x3.1TestCpp之NewRe

XMPP协议实现即时通讯底层书写 (二)-- IOS XMPPFramework Demo+分析

我希望,This is a new day! 在看代码之前,我认为你还是应该先整理一下心情,来听我说几句: 首先,我希望你是在早上边看这篇blog,然后一边開始动手操作,假设你仅仅是看blog而不去自己对照项目,作用不是非常大.一日之计在于晨,所以怀着一颗对技术渴望,激动的.亢奋的心情去学习.你才干有所得. 嗯,就拿鄙人当时做项目来说,每天早上起来的第一件事情.就是研究XMPPFramework作者的代码,依照模块来分析和模仿书写.睡觉的时候还在思考,分析.总结... 当然我并非说每一个Dev

google closure--继承模块二:goog.base()demo分析

昨天已经讲到了goog.inherits(),主要负责通过为子构造函数原型对象通过原型链继承父构造函数的原型对象的方法,完成继承.这样继承只完成了原型对象的继承,看看之前的那张图: 是不是感觉父构造函数好像没什么用处啊,还记得上篇文章,构建一个超级对象的设想吗?这个要依赖另一个API,goog.base(). 在看源代码之前让我们看看一个简单的demo,温习一下goog.inherit(),这个demo还可以帮助我们了解goog.base()可以做些什么. demo代码: 输出结果: 分析: 先

qml demo分析(clocks-时钟)

一.效果展示 效果如图1所示,时钟列表支持鼠标左右拖动,带有黑色背景的是晚上时钟,无黑色背景的是白天时钟 二.源码分析 1.main.cpp文件中只包含了一个宏,该宏的具体解释请看qml 示例中的关键宏文章 2.时钟项 1 Item { 2 id : clock 3 width: { 4 if (ListView.view && ListView.view.width >= 200) 5 return ListView.view.width / Math.floor(ListView

qml demo分析(rssnews-常见新闻布局)

一.效果展示 今儿来分析一篇常见的ui布局,完全使用qml编写,ui交互效果友好,如图1所示,是一个常见的客户端新闻展示效果,左侧是一个列表,右侧是新闻详情. 图1 新闻效果图 二.源码分析 首先先来总体分析下该示例代码的工程目录,如图2所示,总共有6个qml文件.其中BusyIndicator和组件是qml已经存在的组件,NewsDelegate组件是新闻详情页中的一项,CategoryDelegate组件是左侧列表中的一项,RssFeeds组件是左侧新闻列表数据源,rssnews文件是主程序

MATLAB R2016a computer vision toolbox 的 demo分析

2016/05/24 随便看了下几个demo,现在函数都搞的全部封装起来了,不太好,但是还是要借鉴demo里头的总体思路 Structure From Motion From Two Views 1,Read a Pair of Images 读入两幅图像 2,Load Camera Parameters 载入相机参数(用的相机标定app预先弄好的) 3,Remove Lens Distortion 纠正透镜畸变 4,Find Point Correspondences Between The

qml demo分析(photosurface-图片涅拉)

阅读qml示例代码已有一小段时间,也陆续的写了一些自己关于qml示例代码的理解,可能由于自己没有大量的qml开发经验,总感觉复杂的ui交互qml处理起来可能会比较棘手,但事实总是会出人意料,今天我们就来分析一个关于油耗交互的qml代码.从毕业后就一直从事qt的相关开发,一直在使用QWidget窗口做产品,看多了qml后才发现原来还有这么好的ui开发利器,完全的数据和展示分离,ui可以做到想怎么变怎么变,没有了QBoxLayout的帮助(同样是约束),ui再也不用那么死板,对于灵活.绚丽的桌面程序

iOS 3D 之 SceneKit框架Demo分析

Scene Kit 是Apple 向 OS X 开发者们提供的 Cocoa 下的 3D 渲染框架. Scene Kit 建立在 OpenGL 的基础上,包含了如光照.模型.材质.摄像机等高级引擎特性,这些组件都是面向对象的,你可以用熟悉的 Objective-C 或 Swift 语言来编写代码.假如你用过 OpenGL 最早的版本,那时还没有 shader,只能苦逼的使用各种底层受限制的 API 开发.而 Scene Kit 就好了很多,对于大多数需求 (甚至像动态阴影等高级特性),使用它提供的

niftynet Demo分析 -- brain_parcellation

brain_parcellation 论文详细介绍 通过从脑部MR图像中分割155个神经结构来验证该网络学习3D表示的效率 目标:设计一个高分辨率和紧凑的网络架构来分割体积图像中的精细结构 特点:大多数存在的网络体系结构都遵循完全卷积下行-向上采样路径.具有高空间分辨率的低层次特征首先被下采样用于更高层次的特征抽象;然后对特征图进行上采样,以实现高分辨率分割.本论文提出了一种新的3D架构,它包含了整个层的高空间分辨率特征图,并且可以在广泛的接受领域中进行训练 验证:通过从T1加权MR图像中自动进