如何通过计算新的x和y位置围绕其中心旋转精灵?

Sam*_*152 5 c++

我正在使用Dark GDK和C++创建一个简单的2D游戏.我正在旋转一个物体,但它从精灵的左上角旋转.

我有以下变量:

  • PlayerX的
  • PlayerY
  • PlayerWidth
  • PlayerHeight
  • RotateAngle(360> x> 0)

是否有一个算法可以修改精灵的枢轴点,比中心更好?

这是一个代码示例:

void Player::Move( void )
{

    if ( checkLeft() )
    {
        PlayerX -= PlayerSpeed;
        if ( PlayerX < 0 )
            PlayerX = 0;
    }

    if ( checkRight() )
    {
        PlayerX += PlayerSpeed ;
        if ( PlayerX > 800 - PlayerWidth )
            PlayerX = 800 - PlayerWidth;
    }

    if ( checkUp())
    {
        PlayerY -= PlayerSpeed;
        if ( PlayerY < 0 )
            PlayerY = 0;
    }

    if ( checkDown())
    {
        PlayerY += PlayerSpeed;
        if ( PlayerY > 600 -  PlayerHeight)
            PlayerY = 600 - PlayerHeight;
    }

    RotateAngle += 5;
    if(RotateAngle > 360)
        RotateAngle -=360;

    dbRotateSprite(Handle,RotateAngle);
    dbSprite ( 1 , PlayerX , PlayerY , Handle );
}
Run Code Online (Sandbox Code Playgroud)

编辑

我正在考虑为这个问题开辟一些声誉,我还没有得到一个适合我的答案.如果有人可以提供完成工作的实际代码示例,我会非常高兴.

Blindy回答的问题在于,无论我多么简单地来回翻译,spirte仍围绕左上角旋转并将其移动到绕左上角旋转的位置,然后将其移回到相同位置完成任何事情.以下是我认为的情况:

替代文字http://img248.imageshack.us/img248/6717/36512474.png

就这样,没有混淆我创造了一个正在发生的事情的图像.左边显示实际发生的情况,右边显示我需要发生的事情.

替代文字http://img101.imageshack.us/img101/1593/36679446.png

Bli*_*ndy 7

你需要做类似的事情:

  • 翻译( - playerx- playerwidth/ 2, - playery- playerheight/ 2)
  • 旋转 rotateangle
  • 翻译(playerx+ playerwidth/ 2,playery+ playerheight/ 2)

我们的想法是将你的精灵集中在原点上,然后围绕原点(glRotate)旋转,然后在你获得旋转的精灵后,将它转换回原位.

注意:如果您的精灵最初在原点周围"居中",但是角落不是精灵的实际中心,则首先将对象平移,使精灵的中心与原点居中.因此,如果你的精灵在原点的左上角,你会翻译(-playerwidth/2,-playerheight/2),然后旋转然后翻译(playerx,playery).


Tro*_*our 4

到目前为止,答案在告诉您应该如何完成方面是正确的,但我担心 Dark GDK API 似乎太原始,无法以这种简单的方式做到这一点。

不幸的是,dbRotateSprite无论精灵的变换如何,精灵都会围绕左上角旋转,这就是为什么您对其他建议没有运气的原因。要模拟围绕中心的旋转,您必须手动纠正精灵的位置,即您只需旋转精灵,然后将其移动,分两步过程。

我对 API 不熟悉,也不知道 y 是向上还是向下测量以及角度的测量方式如何,所以我将做出一些假设。如果像许多其他 2D 图形系统一样向下测量 y,并且从 x 轴测量角度,随着它从正 x 轴到正 y 轴增加,那么我相信正确的伪代码将如下所示

// PlayerX and PlayerY denote the sprite centre
// RotateAngle is an absolute rotation i.e. not a relative, incremental rotation

RotateAngle += 5;
RotateAngle %= 360;
RadiansRotate = (RotateAngle * PI) / 180;

dbRotateSprite( Handle, RotateAngle );

HalfSpriteWidth = dbSpriteWidth( Handle ) / 2;
HalfSpriteHeight = dbSpriteHeight( Handle ) / 2;

SpriteX = PlayerX
        - HalfSpriteWidth * cos(RadiansRotate)
        + HalfSpriteHeight * sin(RadiansRotate);
SpriteY = PlayerY
        - HalfSpriteHeight * cos(RadiansRotate)
        - HalfSpriteWidth * sin(RadiansRotate);

// Position the top left of the sprite at ( SpriteX, SpriteY )
dbSprite ( 1 , SpriteX , SpriteY , Handle );
Run Code Online (Sandbox Code Playgroud)