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


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

(能呵呵吗?)

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

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

(注意匀速)

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 关于旋转和移动的一点小技巧相关推荐

  1. html网红旋转相册,掌握这些拍照小技巧,你分分钟能拍出“网红”照片

    "五一"假期快要来临,朋友圈里将会迎来一波晒旅游照风潮.如何在朋友圈众多游客照中脱颖而出?最近,记者在超红的app抖音上get到了不少"拍照好方法",而且拍照只 ...

  2. 在开发中总结的一点小技巧

    在平时的开发中,我们总会遇到各种各样的问题,在我们技术还不行的时候,也许不是什么大问题,但是一旦技术逐渐成熟,所写的程序逐渐变大了,那么我们就会面临着越来越多的挑战.1.如何快速认识一个新类及其方法 ...

  3. 使用VM虚拟机的一点小技巧

    今天想为朋友弄一个虚拟机系统文件,这样就可以直接拷贝过去,直接让他用了.哪成想电脑里的系统镜像文件不能用,也不知道是不是VM不支持,反正怎么着也引导不起来了. 无奈只好用硬件光驱来装虚拟系统,把200 ...

  4. 减少科研文章写作错误的一点小技巧

  5. java的循环中try catch的一点小技巧

    在循环中如果有异常被catch住,但是同时不想中断循环可以这样: for(int i=-1;i<3;i++){      try { System.out.println("resul ...

  6. 阅读源代码的一点小技巧

    1. 在跟踪源代码的时候,要追着源代码打断点,不然不知道每一步执行到那里. 有时候有的方法被多个地方调用,这时无法确认走哪个方法,改怎么办呢? 可以提前通过打调用栈的方式把整个流程弄通,然后在关键点打 ...

  7. 在ASP.NET使用javascript的一点小技巧

    我们在进行ASP.NET开发时,经常会用到一些javascript脚本,比如: private void Button1_Click(object sender, System.EventArgs e ...

  8. 管理Win2003sp1防火墙的一点小技巧

    在公司共享网络的服务器上2003SP1的补丁,系统自动重新设置防火墙,使得很多软件在局域网都无法访问服务器,尝试关闭防火墙然而系统把所有网络适配器的防火墙都关了,这是我们不想看到的,又试了试还有另外一 ...

  9. 对于shell脚本参数获取时的一点小技巧

    问题如下: 根据脚本参数的个数$#进行一个循环,在依次输出每个参数$1 $2 $3...... 我有一个循环变量i $i 取到这时的i为1,我想使用这个1再去调用$1,也是就是打印出第一个参数 就是$ ...

最新文章

  1. Nginx的配置文件
  2. http方法_像本地方法一样调用http服务,feign框架springboot项目实践
  3. single-number-ii
  4. JAVA学习篇--JSP实现原理
  5. Unity之计时器功能(转)
  6. (二)SpringBoot功能
  7. delphi 关闭时缩小到托盘_delphi 实现最小化系统托盘
  8. 基于Libevent最小根堆定时器的C++定时器实现
  9. 【算法】多路查找树 B树 B+树
  10. fabric监控linux自动化运维,自动化运维之Fabric系列(一)小试牛刀
  11. SQL语言基础【DDL、DML、DCL、DQL】
  12. AIX 6.1环境 yum的安装方法
  13. invoke-rc.d: initscript systemd-logind, action start failed
  14. torch.randn
  15. Java面试锦囊送给你!大厂门槛随便跨!
  16. 网易云android国内版,网易云音乐Android版产品体验报告
  17. 基于matlab的紧急疏散模型仿真的代码,基于matlab的疏散仿真程序简介.pdf
  18. IBM SPSS Modeler Social Network Analysis 的介绍和日常应用
  19. 经常见到的几个菜谱名字
  20. uniApp APP端调起微信支付失败errCode:-100的踩坑

热门文章

  1. SET NOCOUNT { ON | OFF }
  2. Windows下安装Python pyramid,并运行一个pyramid的Helloworld项目
  3. 你了解吗?小游戏和H5小游戏不是一码事
  4. HTML5学习笔记(三)
  5. 汇川PLC如何连接工业网关实现远程编程和远程上下载程序?
  6. Unity 3D 菜单栏快捷键详解
  7. 在gerrit上cherry pick多笔提交到一个仓库中
  8. 东南蒙纳士计算机复试,2016年东南大学——蒙纳士大学双硕士学位研究生复试通知...
  9. Qt+VTK+PCL图片转灰度图且以灰度为Y轴显示
  10. Leetcode_Map、Set