先上圖,就是這種效果

QQ20180323-173338.gif
做到這種效果的第一個難點是將圖片按曲線路徑去拉伸并傳過固定的點去繪制曲線
索性已經(jīng)有人為我們寫好了算法,這里http://discuss.cocos2d-x.org/t/beding-warping-sprites-by-bezier/33758/8,謝謝這位大神!
把里面的cpp文件和h文件下載下來放進項目里就好,接下來就是怎么去用
按著里面的例子:
if(auto spline = TexturedSpline::create(path, 10, "brick.jpg")
{
addChild(spline);
spline->setPosition(center);
}
其中path是一個 std::vector<Vec2> ,用來盛放曲線需要傳過的點,10可以理解為曲線的圓滑程度,brick.jpg是你要拉伸的原圖,作者從網(wǎng)上扒來的圖分享給大家

line.png
要注意圖片的像素長和寬要是2的倍數(shù),不然會報錯
按著上面的例子做,你可能會發(fā)現(xiàn)曲線并沒有穿越你想要的點,這是因為錨點的問題,我們將曲線位置和錨點重新設(shè)置一下就好了:
_touchLine->setPosition(Vec2(0, 0));
_touchLine->setAnchorPoint(Vec2(0, 0));
就像這樣,就可以用世界坐標(biāo)直接去生成曲線了。
到目前為止曲線都是靜態(tài)的,下面我們來看看怎么去做動態(tài):
首先在h文件里設(shè)定一點東西
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的相關(guān)聲明
bool _makeLine; //判斷是否在畫線的狀態(tài)
std::vector<Vec2> _pointArray; //裝選擇到的字母sprite的坐標(biāo)
Vec2 _touchPoint; //你當(dāng)前touch的坐標(biāo)
TexturedSpline* _touchLine; //那根曲線
void addLinePoint(Vec2 point); //加入選擇到的字母的坐標(biāo)
void deletePoint(); //刪除選擇到的字母的坐標(biāo)
void removeTouchLine(); //刪除曲線
cpp文件:
void GameScene::addLinePoint(Vec2 point)
{
//由于繪制曲線的path不能小于四個點,所以當(dāng)?shù)谝淮吸c擊時,往里面先塞三個相同的點
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);
//思路是這樣的,每次繪制曲線的路徑是各個被選中字母的坐標(biāo) + 你當(dāng)前觸控的坐標(biāo)
_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.當(dāng)檢測到點到添加字母時執(zhí)行addLinePoint 開始繪制曲線
3.當(dāng)需要刪除字母坐標(biāo)的時候執(zhí)行deletePoint
4.檢測到用戶松手時執(zhí)行removeTouchLine 結(jié)束繪制
作者剛玩cocos2dx和c++半個月,肯定有寫得不周全的地方,如果您有更好的想法請多與我交流