首页 > 代码库 > Cocos2d-x3.1TestCpp之MotionStreakTest 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之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"; }

技术分享技术分享

Cocos2d-x3.1TestCpp之MotionStreakTest Demo分析