• 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之NewRenderTest Demo分析代码中HelloWorldScene.cpp中touchEvent函数中的NewRendererDemo换成本次Demo的基类MotionStreakDemo

    3、MotionStreakDemo代码分析

    (1).h文件
    #include "cocos2d.h"
    #include "ui/CocosGUI.h"
    #include "VisibleRect.h"
    USING_NS_CC;
    using namespace ui;
    //基类Scene,全部測试Demo继承Layer。均载入到该基类Scene上。点击上一个、下一个、当前标签均通过场景切换来实现页面变化
    class MotionStreakDemo : public Scene
    {
    public:
        CREATE_FUNC(MotionStreakDemo);
        virtual bool init();
    };
    
    class BaseTest : public cocos2d::Layer
    {
    public:
        CREATE_FUNC(BaseTest);
        std::string title() const;//标题
        virtual std::string subtitle() const;//副标题
        
        void restartCallback(Ref* sender);//又一次执行当前test
        void nextCallback(Ref* sender);//下一个test
        void backCallback(Ref* sender);//上一个test
        void modeCallback(Ref* sender);
        virtual bool init();
        void menuCloseCallback(cocos2d::Ref* pSender);//关闭菜单回调函数
        
    protected:
        MotionStreak* streak;
    };
    //第一个test,相似于地球绕着太阳转的效果
    class MotionStreakTest1 : public BaseTest
    {
    public:
        CREATE_FUNC(MotionStreakTest1);
        virtual bool init();
        void onUpdate(float delta);
        virtual std::string subtitle() const override;
    protected:
        Node* _root;
        Node* _target;
    };
    //第二个test。相似于画板
    class MotionStreakTest2 : public BaseTest
    {
    public:
        CREATE_FUNC(MotionStreakTest2);
        virtual bool init();
        void onTouchesMoved(const std::vector<Touch*>& touches,Event* event);
        virtual std::string subtitle() const override;
    protected:
        Node* _root;
        Node* _target;
    };
    
    //第三个test,见下图执行效果
    class Issue1358 : public BaseTest
    {
    public:
        CREATE_FUNC(Issue1358);
        virtual bool init();
        void update(float delta);
        virtual std::string subtitle() const override;
    protected:
        Vec2 _center;
        float _radius;
        float _angle;
    };

    #define CL(__className__) [](){ return __className__::create();}//宏定义,new出类。并返回
    #define CLN(__className__) [](){ auto obj = new __className__(); obj->autorelease(); return obj; }
    
    //索引。用于推断上一个或下一个
    static int sceneIdx = -1;
    //函数指针数组
    static std::function<Layer*()> createFunctions[] =
    {
            CL(MotionStreakTest1),
            CL(MotionStreakTest2),
            CL(Issue1358),
    };
    //获取数组的大小
    #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;
    }
    
    //基类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 "MotionStreak"; } //副标题 std::string BaseTest::subtitle() const { return "MotionStreak"; } //又一次运行当前test void BaseTest::restartCallback(Ref* sender) { log("restart!"); auto s = new MotionStreakDemo();//首先创建一个Scene,然后将当前的test s->addChild(restartTest());//Layer载入到当前Scene Director::getInstance()->replaceScene(s);//场景切换,第一个场景切换的是HelloWorld中创建的Scene s->release(); } //下一个test void BaseTest::nextCallback(Ref* sender) { log("next!"); auto s = new MotionStreakDemo(); s->addChild(nextTest()); Director::getInstance()->replaceScene(s); s->release(); } //上一个test void BaseTest::backCallback(Ref* sender) { log("back!"); auto s = new MotionStreakDemo(); s->addChild(prevTest()); Director::getInstance()->replaceScene(s); s->release(); } void BaseTest::modeCallback(cocos2d::Ref *sender) { bool fastMode = streak->isFastMode(); streak->setFastMode(!fastMode); } bool MotionStreakDemo::init() { bool bRet = false; do{ CC_BREAK_IF(!Scene::init()); auto layer = nextTest(); addChild(layer); bRet = true; }while(0); return bRet; } bool MotionStreakTest1::init() { bool bRet = false; do{ CC_BREAK_IF(!BaseTest::init()); auto winSize = Director::getInstance()->getWinSize(); _root = Sprite::create("r1.png"); log("_root.x = %lf,_root.y = %lf",_root->getAnchorPoint().x,_root->getAnchorPoint().y); _root->setPosition(Vec2(winSize.width/2,winSize.height/2)); addChild(_root,1); _target = Sprite::create("r1.png"); log("_target = %lf,_target.y = %lf",_target->getAnchorPoint().x,_target->getAnchorPoint().y); _root->addChild(_target); _target->setPosition(Vec2(winSize.width/4,0)); //运动纹理。參数依次为消失时间,最小段。宽度,颜色,纹理图片 streak = MotionStreak::create(2, 3, 100, Color3B::GREEN, "streak.png"); addChild(streak); schedule(schedule_selector(MotionStreakTest1::onUpdate)); //效果相似地球环绕太阳转的效果 auto a1 = RotateBy::create(2, 360); auto action1 = RepeatForever::create(a1); auto motion = MoveBy::create(2, Vec2(100,0)); _root->runAction(RepeatForever::create(Sequence::create(motion,motion->reverse(), NULL))); _root->runAction(action1); //颜色渐变 auto colorAction = RepeatForever::create(Sequence::create( TintTo::create(0.2f, 255, 0, 0), TintTo::create(0.2f, 0, 255, 0), TintTo::create(0.2f, 0, 0, 255), TintTo::create(0.2f, 0, 255, 255), TintTo::create(0.2f, 255, 255, 0), TintTo::create(0.2f, 255, 0, 255), TintTo::create(0.2f, 255, 255, 255), NULL)); streak->runAction(colorAction); bRet = true; }while(0); return bRet; } void MotionStreakTest1::onUpdate(float delta) { streak->setPosition(_target->convertToWorldSpace(Vec2::ZERO)); } std::string MotionStreakTest1::subtitle() const { return "MotionStreak test 1"; } //相似画板效果,线条自己主动消失 bool MotionStreakTest2::init() { bool bRet = false; do{ CC_BREAK_IF(!BaseTest::init()); //开启多点触摸 auto listener = EventListenerTouchAllAtOnce::create(); listener->onTouchesMoved = CC_CALLBACK_2(MotionStreakTest2::onTouchesMoved,this); Director::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraphPriority(listener, this); auto winSize = Director::getInstance()->getWinSize(); streak = MotionStreak::create(3, 3, 64, Color3B::WHITE, "streak.png"); addChild(streak); streak->setPosition(Vec2(winSize.width/2,winSize.height/2)); bRet = true; }while(0); return bRet; } void MotionStreakTest2::onTouchesMoved(const std::vector<Touch *> &touches, cocos2d::Event *event) { //依据触摸位置,画线 auto touchLocation = touches[0]->getLocation(); streak->setPosition(touchLocation); } std::string MotionStreakTest2::subtitle() const { return "MotionStreak test 2"; } bool Issue1358::init() { bool bRet = false; do{ CC_BREAK_IF(!BaseTest::init()); auto winSize = Director::getInstance()->getWinSize(); //运动纹理。參数依次为消失时间。最小段,宽度,颜色。纹理图片 streak = MotionStreak::create(2, 3, 50, Color3B::GREEN, "icon.png"); addChild(streak); _center = Vec2(winSize.width/2,winSize.height/2); _radius = winSize.width/3; _angle = 0.0f; //帧间隔0秒,可是推荐使用scheduleUpdate(); schedule(schedule_selector(Issue1358::update),0); bRet = true; }while(0); return bRet; } void Issue1358::update(float delta) { _angle += 1.0f; streak->setPosition(Vec2(_center.x + cosf(_angle/180*M_PI)*_radius,_center.y+sinf(_angle/180*M_PI)*_radius)); } std::string Issue1358::subtitle() const { return "MotionStreak test 3"; }



  • 相关阅读:
    vscode入门使用教程(页面调试)
    .net core3.1开始页面实时编译
    Ubuntu 编辑文件、安装、删除软件等常用命令(持续更新)
    .NetCore3.1中的WebApi如何配置跨域
    PC电脑端如何多开Skype,一步搞定!
    简单几步为博客园添加动态动漫妹子
    如何在SqlServer中使用层级节点类型hierarchyid
    Entity framework Core 数据库迁移
    牛客网剑指offer【Python实现】——part1
    Linux实战——Shell编程练习(更新12题)
  • 原文地址:https://www.cnblogs.com/wgwyanfs/p/6748275.html
Copyright © 2020-2023  润新知