1. 程式人生 > >cocos2d-x 關於旋轉和移動的一點小技巧

cocos2d-x 關於旋轉和移動的一點小技巧

小白 get posit seq sso 解釋 pre create ron

你犯困嗎,恩。給你講個笑話提提神~


一對情侶去從林遊玩。被食人族捉住。食人族首領心情非常好。說你們假設想活命,就吃掉對方的大便。在他們回來的路上。女人終於忍不住停下。坐到石頭上哭起來。男人摟住她的肩膀。

女人別過臉去,幽幽的說:你不愛我,要不然剛才你不會拉這麼多。


(能呵呵嗎?)


================================================================================


一般在遊戲中我們避免不了處理旋轉或者子彈發射什麽的,就比方塔防遊戲來說吧,我們須要推斷敵人往哪裏走,炮塔就往哪裏轉,轉完然後朝著一個方向發射子彈

是一個方向而不是朝一個點,就比方保衛蘿蔔,子彈穿過怪物繼續朝那個方向飛行。直到飛往屏幕外才移除),以下來簡單分析一下實現的過程,須要涉及到一點點平面向量的數學知識。

(註意勻速)

1. 旋轉 : 朝著某個點的方向勻速旋轉

2.發射:讓子彈朝著某個點的方向勻速移動


我們來分步驟實現,先實現旋轉功能:


嗯,如今如果平面中有點A和點B,A是炮塔。B是敵人。如今我們須要讓炮塔A的方向朝著敵人B旋轉,由於炮塔放置的時候方向向上,所以我們要旋轉的角度為α,如圖


技術分享

如今首先,我們創建敵人和塔

//敵人
auto enemy = Sprite::create("enemy.png");
enemy->setPostion(Point(100,200));
this->addChild(enemy);

//塔
auto tower = Sprite::create("tower.png");
tower->setPostion(Point(200,100));
this->addChild(tower);

然後我們讓塔旋轉瞄準敵人,僅僅是為了能射它一臉(呵呵?)

//讓塔的方向旋轉對準敵人

//射擊方向向量
Point shootVector = enemy->getPosition() - tower->getPosition();
//向量標準化(即向量長度為1)
Point normalizedVector = ccpNormalize(shootVector) ;
//算出旋轉的弧度
float radians = atan2(normalizedVector.y, - normalizedVector.x);
//將弧度轉換成角度
float degree = CC_RADIANS_TO_DEGREES(radians);


//勻速旋轉須要我們設置一下速度。這裏如果旋轉速度為 2π (rad/s)
float rotateSpeed = 2 * M_PI;
//那麽旋轉1弧度所用時間為
float rotate_1rad_time = 1 / rotateSpeed;
//所以旋轉的時長為
float rotateDuration = fabs(radians * rotate_1rad_time);


//最後運行旋轉
_sprite->runAction(RotateTo::create(rotateDuration,degree- 90));

須要註意一下

(1)如果點A為塔,B為敵。則 向量 shootVector = OB -OA = AB

(2)atan2(y,x)是就是反正切函數。 算出的是 點(x,y)與x軸正方向的夾角,返回的是角的弧度值

(3)所以degree算出的角度事實上是與x軸正方向的夾角

(4)因為炮塔方向向上,所以 【旋轉的角度 α 】= degree - 90


如果你想不起來什麽是反正切,那沒關系,看以下如果和圖(再想不起來我僅僅能呵呵了)

如果 tan(α) = y / x , 則有 α = arctan(y / x)

技術分享


旋轉完後接下來我們再實現射擊功能:


如果有塔。子彈和敵人,位置如圖,我們須要把子彈由位置A沿著AB方向 勻速射到C(C點在屏幕外)


技術分享


我們先創建敵人,塔和子彈


//敵人
auto enemy = Sprite::create("enemy.png");
enemy->setPostion(Point(100,200));
this->addChild(enemy);

//塔
auto tower = Sprite::create("tower.png");
tower->setPostion(Point(200,100));
this->addChild(tower);

//子彈,和塔在一個位置
auto tower = Sprite::create("bullet.png");
tower->setPostion(Point(200,100));
this->addChild(tower);

然後這次我們真的射它一臉(再次呵呵)


//射擊方向向量
Point shootVector = enemy->getPosition() - bullet->getPosition();
//向量標準化(即向量長度為1)
Point normalizedVector = ccpNormalize(shootVector);
//移動長度向量
Point overShootVector = normalizedVector * 900;
//超出屏幕的點
Point offScreenPoint = bullet->getPosition() + overShootVector;

//如果速度為500(pix/s)
float moveSpeed = 500;
//移動時間
float moveDuration = overShootVector / moveSpeed;

//運行設計
auto move = MoveTo::create(moveDuration,offScreenPoint);
CallFunc* moveDone = CallFunc::create(CC_CALLBACK_0(shootFinish,this,bullet));
bullet->runAction(Sequence::create(move,moveDone,NULL));
射擊結束後移除子彈

//射擊結束後移除
void HelloWorld::shootFinish(Node* pNode){
    Sprite* bullet = (Sprite*)pNode;
    if(bullet != NULL)
        bullet->stopAllActions();
        this->removeChild(bullet);
}

稍稍解釋一下 :

(1)shootVector就是向量AB。

(2)overShootVector = (AB向量標準化)× 900 即得到 AC。比方說你設置的分辨率為 800 x 400 。那麽你能夠用標準化向量 × 你最大分辨率再大一點,這樣子向量就會超出屏幕之外並且長度又固定。

(3)然後依據向量OC = OA + AC ,算出要移動到的點offScreenPoint(即點C)。

(4)設置一下速度,長度一定了,所以時間 = 長度 / 速度 。


=====================================================


事實上也沒啥東西,純屬小白教程。。


轉載請註明出處:http://blog.csdn.net/shun_fzll/article/details/34430045






cocos2d-x 關於旋轉和移動的一點小技巧