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

來源:互聯網
上載者:User

標籤:cocos2dx   cocos2d-x   旋轉   

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


一對情侶去從林遊玩,被食人族捉住。食人族首領心情很好,說你們如果想活命,就吃掉對方的大便。在他們回來的路上,女人終於忍不住停下,坐到石頭上哭起來。男人摟住她的肩膀。女人別過臉去,幽幽的說:你不愛我,要不然剛才你不會拉這麼多。


(能呵呵嗎?)


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


一般在遊戲中我們避免不了處理旋轉或者子彈發射什麼的,就比如塔防遊戲來說吧,我們需要判斷敵人往哪裡走,炮塔就往哪裡轉,轉完然後朝著一個方向發射子彈是一個方向而不是朝一個點,就比如保衛蘿蔔,子彈穿過怪物繼續朝那個方向飛行,直到飛往螢幕外才移除),下面來簡單分析一下實現的過程,需要涉及到一點點平面向量的數學知識。

(注意勻速)

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






聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.