如何通过闭合新的x和y位置来旋转sprite的中心? [英] How do you rotate a sprite around its center by caclulating a new x and y position?

查看:120
本文介绍了如何通过闭合新的x和y位置来旋转sprite的中心?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用Dark GDK和C ++来创建一个简单的2D游戏。我旋转一个对象,但它旋转从sprite的左上角。



我有以下变量可用:




  • 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;
}

旋转角度+ = 5;
if(RotateAngle> 360)
RotateAngle - = 360;

dbRotateSprite(Handle,RotateAngle);
dbSprite(1,PlayerX,PlayerY,Handle);
}

编辑

我正在考虑为这个问题打开一些声誉,我还没有得到一个适合我的答案。如果有人可以提供一份实际的代码样本来完成这项工作,我会很高兴。



Blindy的回答的问题是,无论我多么简单地来回翻译它,螺旋仍然围绕左上角旋转,并将它移动到旋转的地方左上角,然后将其移回到相同的位置什么都不做。这是我相信会发生的事情:





只是这样没有混乱,我已经创造了一个正在发生的事情的形象。左侧显示了实际发生的情况,右侧显示了我需要发生的事情。



解决方案

到目前为止的答案是正确的, em> ,但恐怕Dark GDK API似乎太原始了,无法以这种简单的方式做。



不幸的是 dbRotateSprite 旋转左上角的精灵,而不管精灵的变换,这就是为什么你没有运气与其他建议。要模拟围绕中心的旋转,必须手动修正sprite的位置,即只需旋转sprite,然后将其作为两步过程移动。



I不熟悉API,我不知道y是测量向上还是向下,以及测量角度的方式,所以我要做一些假设。如果y像许多其他2D图形系统一样被测量,并且从x轴随着其从正x轴到正y轴的增加而测量角度,则我相信正确的伪码将看起来像

  // PlayerX和PlayerY表示sprite中心
// RotateAngle是一个绝对旋转, 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);

//定位sprite的左上角(SpriteX,SpriteY)
dbSprite(1,SpriteX,SpriteY,Handle);


I'm using Dark GDK and C++ to create a simple 2d game. I'm rotating an object but it rotates from the top left corner of the sprite.

I have the following variables available:

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

Is there an algorithm that will modify the pivot point of the sprite, preferable to the center?

Here is a small code sample:

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 );
}

Edit

I'm considering opening up some reputation for this question, I have yet to be provided with an answer that works for me. If someone can provide an actual code sample that does the job, I'd be very happy.

The problem with Blindy's answer is that no matter how much I simply translate it back or forth, the spirte still rotates around the top left hand corner and moving it somewhere rotating around the top left corner, then moving it back to the same position accomplishes nothing. Here is what I believe to be going on:

Just so there is no confusion I have created a an image of what is going on. The left shows what is actually happening and the right shows what I need to happen.

解决方案

The answers so far are correct in telling you how it should be done but I fear that the Dark GDK API seems to be too primitive to be able to do it that simple way.

Unfortunately dbRotateSprite rotates the sprite about the top left regardless of the sprite's transform which is why you're having no luck with the other suggestions. To simulate rotation about the centre you must manually correct the position of the sprite i.e. you simply have to rotate the sprite and then move it as a two-step process.

I'm not familiar with the API and I don't know if y is measured up or down and which way the angle is measured so I'm going to make some assumptions. If y is measured down like many other 2D graphics systems, and the angle is measured from the x-axis increasing as it goes from the positive x-axis to the positive y-axis, then I believe the correct psuedo-code would look like

// 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 );

这篇关于如何通过闭合新的x和y位置来旋转sprite的中心?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆