博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
cocos2d-x 关于旋转和移动的一点小技巧
阅读量:5237 次
发布时间:2019-06-14

本文共 3137 字,大约阅读时间需要 10 分钟。

你犯困吗,恩。给你讲个笑话提提神~

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

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

(能呵呵吗?)

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

一般在游戏中我们避免不了处理旋转或者子弹发射什么的,就比方塔防游戏来说吧,我们须要推断敌人往哪里走,炮塔就往哪里转,转完然后朝着一个方向发射子弹是一个方向而不是朝一个点,就比方保卫萝卜,子弹穿过怪物继续朝那个方向飞行。直到飞往屏幕外才移除),以下来简单分析一下实现的过程,须要涉及到一点点平面向量的数学知识。

(注意匀速)

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

转载于:https://www.cnblogs.com/jzdwajue/p/6927010.html

你可能感兴趣的文章
P1107 最大整数
查看>>
1085 数字游戏
查看>>
C#使用反射获取对象变化的情况
查看>>
Java中HashMap、TreeMap和LinkedHashMap的比较
查看>>
黑马程序员11_网络
查看>>
EasyDarwin EasyClient开源流媒体播放器,支持多窗口显示
查看>>
EasyDarwin开源手机直播方案:EasyPusher手机直播推送,EasyDarwin流媒体服务器,EasyPlayer手机播放器...
查看>>
EasyPusher进行Android UVC外接摄像头直播推送实现方法
查看>>
Python 3: 加密简介
查看>>
《SQL Server 2012 T-SQL基础》读书笔记 - 4.子查询
查看>>
mysql-学习-13-20170619-MySQL备份恢复-xtrabackup-2
查看>>
kubernetes 测试 Mariadb gtid 主从复制.
查看>>
LVM 磁盘分区扩容
查看>>
第三十四篇、二维码扫描和生成
查看>>
应用程序无法正常启动错误(0xc000007b)
查看>>
kafka definitive guide - reading notes
查看>>
C++ 11 原子操作
查看>>
SpringBoot背景
查看>>
matplotlib基础整理
查看>>
JPA ---- EntityManager
查看>>