cocos2d-x v3.9 关于RotateTo和SkewTo的疑问

原创 2015年11月19日 11:01:32

最近在研究cocos2d-x v3.9的RotateTo时遇到了个问题,不知道是否算是Bug。

首先说一下我理解的RotateTo。RotateTo不关心精灵当前的角度,将精灵旋转至指定的角度。无论指定的角度是多少,最终旋转的角度一定在-360°~360°之间。进一步,我认为如果指定的角度为正角度则应按照顺时针方向将精灵旋转至指定角度;如果指定的角度为负角度,则应按照逆时针方向。

例如精灵的初始角度为0°,指定旋转角度为1090°,则实际应按照顺时针旋转10°(1090 % 360);又或者精灵的初始角度为0°,指定旋转角度为-591°,则实际应按照逆时针旋转231°(591 % 360)。

实际情况:比如精灵的初始角度均为0°。
1、

auto myRotateTo = RotateTo::create(3, 270);
mySprite->runaction(myRotateTo);

效果:以逆时针旋转90°。

2、

auto myRotateTo = RotateTo::create(3, -181);
mySprite->runaction(myRotateTo);

效果:以顺时针旋转179°。
看起来是遵循了就近原则,从当前角度到指定角度走了个最近路程。看一下源码:

void RotateTo::calculateAngles(float &startAngle, float &diffAngle, float dstAngle)
{
    // 将startAngle更新为对360.0°求余的角度。
    // 比如startAngle传进来是721.7°,更新后为1.7°。
    if (startAngle > 0)
    {
        startAngle = fmodf(startAngle, 360.0f);
    }
    else
    {
        startAngle = fmodf(startAngle, -360.0f);
    } 

    diffAngle = dstAngle - startAngle;    // 得到目标角度与起始角度之间的差值。
    if (diffAngle > 180)
    {
        diffAngle -= 360;
    }
    if (diffAngle < -180)
    {
        diffAngle += 360;
    }
}

初步证实了,是就近原则那么个意思。如果顺时针的旋转角度大于180°了,那从逆时针方向转更近,逆时针方向的同理。
可真的是这样吗?继续测试。

3、

auto myRotateTo = RotateTo::create(3, 640);
mySprite->runaction(myRotateTo);

效果:以顺时针旋转280°。如果遵循就近原则,应该按照逆时针旋转80°。

4、

auto myRotateTo = RotateTo::create(3, -541);
mySprite->runaction(myRotateTo);

效果:以逆时针旋转181°。如果遵循就近原则,应该按照顺时针旋转179°。

5、

auto myRotateTo = RotateTo::create(3, 899);
mySprite->runaction(myRotateTo);

效果:以顺时针旋转539°。这更没什么就近原则之说了,起码效果上是多转了一圈。

6、

auto myRotateTo = RotateTo::create(3, -731);
mySprite->runaction(myRotateTo);

效果:以逆时针旋转371°。同上,没有就近原则之说,起码效果上多转了一圈。

**至此做个总结:
精灵的初始角度为0°,
当 -540° <= 指定的角度 <= 540°时,旋转遵循就近原则,旋转的角度在360°之内。
当 541° < 指定的角度 < 720° 或者 -720° < 指定的角度 < -541° 时,旋转不遵循就近原则,旋转的角度在360°之内。
当 指定的角度 >= 720° 或者 指定的角度 <= -720° 时,旋转的角度在360°之外,即起码多旋转了一圈,也就无法谈及是否遵循就近原则了。**

如果按照我理解的RotateTo,RotateTo::calculateAngles()应该是如下形式:

void RotateTo::calculateAngles(float &startAngle, float &diffAngle, float dstAngle)
{
    diffAngle = fmodf(dstAngle, 360) - fmodf(startAngle, 360);
    diffAngle = fmodf(diffAngle, 360);

    if(((diffAngle < 0) && (dstAngle >= 0)) || ((diffAngle > 0) && (dstAngle < 0)))
    {
        if(diffAngle > 0)
            diffAngle -= 360;
        else
            diffAngle += 360;
    }

    return ;
}

SkewTo在计算变化角度的时候也有同样的问题。此外,SkewTo在对X轴的变化角度取余的时候为何对180°求余?

if (_startSkewX > 0)
{
    _startSkewX = fmodf(_startSkewX, 180.f);    // 180°?
}
else
{
    _startSkewX = fmodf(_startSkewX, -180.f);    // 180°?
}

这样会导致问题。举个简单的例子,比如我让X轴从181°变换到191°,

sprite->setSkewX(181);
auto skewto = SkewTo::create(3, 191, 0);
sprite->runAction(skewto);

本意只是想让X轴沿顺时针方向变化10°,单实际的效果是X轴沿逆时针方向变化了170°。

版权声明:本文为博主原创文章,未经博主允许不得转载。

Cocos2d-x 3.2 Lua示例 ActionTest(动作测试)

Cocos2d-x 3.2 Lua示例 ActionTest(动作测试) Cocos2d-x官方真够给力的,3.1.1还没有熟悉完,3.2就出来,本篇博客继续介绍Cocos2d-x的Lua示例,关于3...
  • wwj_748
  • wwj_748
  • 2014年07月29日 23:43
  • 31144

cocos2dx之CCRotateTo、CCRotateBy

我学习的这个版本是2.0版的,后面版本都已经更新了,所以在使用改变CCRotateTO、CCRotateBy改变运动需要借助其他的成员方法,下面的例子是在2.0编写的: void MyActionR...

cocos2d-x实例学习(5)之SkewTo&SkewBy

SkewTo&SkewBy概念 SkewTo:把某一CCSprite歪斜到某一值 SkewBy:把某一CCSprite歪斜多少值,它有一个方法reverse,它让对象按原路径返回 S...

cocos2d-x实例学习(3)之RotateTo&RotateBy

概念 RotateTo:把某一CCSprite旋转到某一角度 RotateBy:把某一CCSprite旋转某个角度,它有一个方法reverse,它让对象按原路径旋转回 使用方式 ...

Cocos2dx中RotateTo对旋转方向的处理

今天在写个demo的时候意外发现了一个跟rotate相关的有趣的事情。 如果我们想要将一个物体旋转朝向另外一个物体的时候,一般都会采用如下的方法: // 通过tan值求arctan来得到旋转角...

cocos2d-x 动作的分类与使用

原本计划是把动作的概念理清,并分类介绍如何使用,但是网上
  • decajes
  • decajes
  • 2014年05月13日 20:49
  • 5278

制作了一个cocos2d-x下沿y轴旋转任意角度的精灵对象

制作了一个cocos2d-x下沿y轴旋转任意角度的精灵对象 (2013-05-23 21:39:27) 转载▼ 标签: cocos2d-x y轴 旋转 ccspr...

cocos2d-x实例学习(7)之同时使用rotate,skew,scale

本实例演示了同时使用CCRotateTo,CCSkewTo,CCScaleTo来实现动态效果,代码如下 CCSize boxSize = CCSizeMake(100.0f, 100.0...

AForge学习笔记(8):AForge.Imaging.ColorReduction

BurkesColorDithering:用于实现伴有巴克斯误差扩散的色彩抖动。所谓色彩抖动即是根据调色板中的最匹配色替换原始图像颜色,在此过程中由于匹配色与原始色存在差值,因此产生误差,这些误差会进...

LUA 基础语法相关

1 table.sort 下面是两个错误排序函数: local t = { [1] = {id=1,name="1"}, [2] = {id=2,name="2"}, [3] = {id=4...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:cocos2d-x v3.9 关于RotateTo和SkewTo的疑问
举报原因:
原因补充:

(最多只允许输入30个字)