cocos2dx下的曲線拉抻 以及 曲線鏈接多點

先上圖,就是這種效果c++

QQ20180323-173338.gif

作到這種效果的第一個難點是將圖片按曲線路徑去拉伸並傳過固定的點去繪製曲線算法

所幸已經有人爲咱們寫好了算法,這裏http://discuss.cocos2d-x.org/...,謝謝這位大神!ui

把裏面的cpp文件和h文件下載下來放進項目裏就好,接下來就是怎麼去用
按着裏面的例子:this

if(auto spline = TexturedSpline::create(path, 10, "brick.jpg")
{
    addChild(spline);
    spline->setPosition(center);
}

其中path是一個 std::vector<Vec2> ,用來盛放曲線須要傳過的點,10能夠理解爲曲線的圓滑程度,brick.jpg是你要拉伸的原圖,做者從網上扒來的圖分享給你們spa

line.png

要注意圖片的像素長和寬要是2的倍數,否則會報錯code

按着上面的例子作,你可能會發現曲線並無穿越你想要的點,這是由於錨點的問題,咱們將曲線位置和錨點從新設置一下就行了:orm

_touchLine->setPosition(Vec2(0, 0));
        _touchLine->setAnchorPoint(Vec2(0, 0));

就像這樣,就能夠用世界座標直接去生成曲線了。
到目前爲止曲線都是靜態的,下面咱們來看看怎麼去作動態:
首先在h文件裏設定一點東西blog

virtual void draw(cocos2d::Renderer *renderer, const cocos2d::Mat4 &transform, uint32_t flags);
    void onDraw(const cocos2d::Mat4 &transform, bool transformUpdated);
    cocos2d::CustomCommand _customCommand;
//上面的是cocos2dx 3.x重寫draw的相關聲明

    bool _makeLine;                              //判斷是否在畫線的狀態
    std::vector<Vec2> _pointArray;               //裝選擇到的字母sprite的座標
    Vec2 _touchPoint;                            //你當前touch的座標
    TexturedSpline* _touchLine;                  //那根曲線
    
    void addLinePoint(Vec2 point);               //加入選擇到的字母的座標
    void deletePoint();                          //刪除選擇到的字母的座標
    void removeTouchLine();                      //刪除曲線

cpp文件:事件

void GameScene::addLinePoint(Vec2 point)
{
    //因爲繪製曲線的path不能小於四個點,因此當第一次點擊時,往裏面先塞三個相同的點
    if (_pointArray.size() < 4) {
        _pointArray.push_back(point);
        _pointArray.push_back(point);
        _pointArray.push_back(point);
    }
    _pointArray.push_back(point);
    _makeLine = true;
}

void GameScene::deletePoint()
{
    _pointArray.pop_back();
    if (_pointArray.size() < 4) {
        _makeLine = false;
    }
}

void GameScene::removeTouchLine()
{
    _pointArray.clear();
    _makeLine = false;
}

void GameScene::draw(cocos2d::Renderer *renderer, const cocos2d::Mat4 &transform, uint32_t flags)
{
    _customCommand.init(zOrderLetters);
    _customCommand.func = CC_CALLBACK_0(GameScene::onDraw, this, transform, flags);
    renderer->addCommand(&_customCommand);
}

void GameScene::onDraw(const cocos2d::Mat4 &transform, bool transformUpdated)
{
    Director *director = Director::getInstance();

    director->pushMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW);
    director->loadMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW, transform);
    
    if (_touchLine != NULL) {
        this->removeChild(_touchLine);
        _touchLine = NULL;
    }
    if (_makeLine) {
        std::vector<Vec2> path;
        path.insert(path.end(), _pointArray.begin(), _pointArray.end());
        path.push_back(_touchPoint);
        //思路是這樣的,每次繪製曲線的路徑是各個被選中字母的座標 + 你當前觸控的座標
        _touchLine = TexturedSpline::create(path, 50, "line.png");
        this->addChild(_touchLine,2);
        _touchLine->setPosition(Vec2(0, 0));
        _touchLine->setAnchorPoint(Vec2(0, 0));
    }
    director->popMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW);
}

用法是:
1.在touch事件中記錄_touchPoint
2.當檢測到點到添加字母時執行addLinePoint 開始繪製曲線
3.當須要刪除字母座標的時候執行deletePoint
4.檢測到用戶鬆手時執行removeTouchLine 結束繪製圖片

做者剛玩cocos2dx和c++半個月,確定有寫得不周全的地方,若是您有更好的想法請多與我交流

相關文章
相關標籤/搜索