Sprite rotation

Started by
6 comments, last by Kr00pS 16 years, 5 months ago
Hello ! I'm trying to rotate a sprite on himself when the user presses keys like q or d. The sprite rotates but the rotation is very odd. I'm using D3DXMatrixTransformation2D() function. If I don't specify any rotation center, the sprite rotates around the left-top corner (0, 0). If I specify the rotation center like this: m_RotationCenter.x = (m_Sprite->GetPosition().x - (32/2)); m_RotationCenter.y = (m_Sprite->GetPosition().y - (32/2)); The rotation is odd and doesn't work. I think I'm giving a wrong rotation center to the function. Help me please Player.h

#pragma once

#include "inc.h"

#include "Sprite.h"

struct ANIM
{
	string name;
	RECT rect;

	ANIM(string name, RECT rect)
	{
		this->name = name;
		this->rect = rect;
	}
};

class Player
{
private:
	Sprite *m_Sprite;

	vector<ANIM *> m_Anims;

	ANIM *m_CurrentAnim;

	LPD3DXSPRITE m_SpriteObject;

	D3DXVECTOR2 m_RotationCenter;
	D3DXMATRIX m_RotationMatrix;
	int m_RotationAngle;

public:
	Player();
	~Player();

	void Draw();

	Sprite *GetSprite();

	void SetRotation(int alpha);
};


Player.cpp

#include "Player.h"

Player::Player()
{
	m_Sprite = new Sprite(GlobalVars::GetInstance()->GetGVarValue<string>("ms_matsprite"));

	for (int i = 0; i < GlobalVars::GetInstance()->GetGVarValue<int>("ms_p_anim_number"); i++)
	{
		static ostringstream oss;
		RECT rect;

		oss.str("");
		oss << "ms_p_" << i << "_name";
		string name = GlobalVars::GetInstance()->GetGVarValue<string>(oss.str());

		oss.str("");
		oss << "ms_p_" << i << "_x";
		int x = GlobalVars::GetInstance()->GetGVarValue<int>(oss.str());

		oss.str("");
		oss << "ms_p_" << i << "_y";
		int y = GlobalVars::GetInstance()->GetGVarValue<int>(oss.str());

		oss.str("");
		oss << "ms_p_" << i << "_w";
		int w = GlobalVars::GetInstance()->GetGVarValue<int>(oss.str());

		oss.str("");
		oss << "ms_p_" << i << "_h";
		int h = GlobalVars::GetInstance()->GetGVarValue<int>(oss.str());

		SetRect(&rect, x, y, w, h);

		if (name == "IDLE")
		{
			m_CurrentAnim = new ANIM(name, rect);
		}

		m_Anims.push_back(new ANIM(name, rect));
	}

	m_RotationAngle = 0;

	if (FAILED(D3DXCreateSprite(D3DManagement::GetInstance()->GetDevice(), &m_SpriteObject)))
	{
		MSG_ERROR("Can't create sprite");
	}

	m_RotationCenter.x = (m_Sprite->GetPosition().x - (32/2));
	m_RotationCenter.y = (m_Sprite->GetPosition().y - (32/2));

	D3DXMatrixTransformation2D(&m_RotationMatrix, NULL, 0, NULL, &m_RotationCenter, D3DXToRadian(m_RotationAngle), NULL);
}

Player::~Player()
{
	delete m_Sprite;

	for (int i = 0; i < m_Anims.size(); i++)
	{
		delete m_Anims;
		m_Anims.erase(m_Anims.begin()+i);
	}

	delete m_CurrentAnim;

	D3DSAFE_RELEASE(m_SpriteObject);
}

void Player::Draw()
{
	if (FAILED(m_SpriteObject->Begin(D3DXSPRITE_ALPHABLEND)))
	{
		MSG_ERROR("Can't begin draw");
	}

	m_SpriteObject->SetTransform(&m_RotationMatrix);
	m_Sprite->Draw(&m_Sprite->GetPosition(), &m_CurrentAnim->rect, m_SpriteObject);

	if (FAILED(m_SpriteObject->End()))
	{
		MSG_ERROR("Can't end draw");
	}
}

Sprite *Player::GetSprite()
{
	return m_Sprite;
}

void Player::SetRotation(int alpha)
{
	m_RotationAngle += alpha;

	if (m_RotationAngle >= 360)
	{
		m_RotationAngle = 0;
	}

	m_RotationCenter.x = (m_Sprite->GetPosition().x - (32/2));
	m_RotationCenter.y = (m_Sprite->GetPosition().y - (32/2));

	D3DXMatrixTransformation2D(&m_RotationMatrix, NULL, 0, NULL, &m_RotationCenter, D3DXToRadian(m_RotationAngle), NULL);
}


Thanks in advance [Edited by - Kr00pS on November 10, 2007 1:48:19 PM]
Advertisement
The rotation center is relative the sprite's local space, not world space. So the rotation center should be:

(SpriteSizeX / 2, SpriteSizeY / 2)
NextWar: The Quest for Earth available now for Windows Phone 7.
Don't work :'(

The sprite look at the left corner and turn around. :/
Odd. In fact, it shouldn't matter. As I understand it, D3DXMatrixTransformation2D() will use the center of the quad as the pivot for rotations if you specify NULL, anyway.
NextWar: The Quest for Earth available now for Windows Phone 7.
D3DXMATRIX mat;
D3DXMatrixIdentity( &mat );
D3DXMatrixRotationZ( &mat, D3DX_PI/2 );//rotate 90
g_pSprite->SetTransform( &mat );

sprite can only RotateZ..
Quote:Original post by syqking
D3DXMATRIX mat;
D3DXMatrixIdentity( &mat );
D3DXMatrixRotationZ( &mat, D3DX_PI/2 );//rotate 90
g_pSprite->SetTransform( &mat );

sprite can only RotateZ..

Same thing.
Sorry for the bump, but I don't find anything. Help please. :)
Now, I know what's the problem. The rotation works with this at any position:
m_RotationCenter.x = (m_Sprite->GetPosition().x + (32/2));
m_RotationCenter.y = (m_Sprite->GetPosition().y + (32/2));

I was using z and d keys to up and down the ordinate but if the sprite rotates and if after I want to move it, it modifies only the ordinate (it's normal). The coordinates are wrong and if I want to rotate the sprite again, the sprite moves anywhere.

I don't know how to solve this, help me please.

This topic is closed to new replies.

Advertisement