9 Replies - 759 Views - Last Post: 25 June 2012 - 12:33 AM Rate Topic: -----

#1 alpha_x  Icon User is offline

  • D.I.C Head

Reputation: 6
  • View blog
  • Posts: 50
  • Joined: 03-May 11

Sprite Rotation corresponding to Mouse Location

Posted 23 June 2012 - 11:13 PM

Hey all,

I have been reading a book about DirectX game development and I just recently learned about Sprite transforms and the like. Anyways, I challenged myself to rotate the character according to where the mouse pointer is on the screen and have run into a few hiccups.

The method I decided to use was:

- Store the mouse location in a POINT variable
- Use GetCursorPos(LPPOINT) to store the current location of the cursor
- Upon each Game_Update(which occurs all the time), change the rotation of the sprite via using atan2() to get the angle that the sprite is facing.
- Rotate the sprite in Game_Update()

For some reason, the image is not rotated where the mouse pointer is yet my method seems logical or have I missed something crucial.

Here is an image so you can see:

[The red line should be in the same direction as where my mouse pointer is, X is the location that the mouse pointer was at]



Posted Image


Here is the code that implements the steps above:

/*
  Beginning Game Programming, Thid Edition
  MyGame.cpp
  Rotate_Scale_Demo
  */

#include "MyDirectX.h"
#include <string>
#include <math.h>
using namespace std;

const string APPTITLE = "Sprite Rotation and Scaling Demo";
const int SCREENW = 1024;
const int SCREENH = 768;
LPDIRECT3DTEXTURE9 sunflower;
D3DCOLOR color;
int frame = 0, columns,width,height;
int startframe,endframe,starttime=0,delay;



//FPS Calculations
DWORD dwFrames;
DWORD dwCurrentTime;
DWORD dwLastUpdateTime;
DWORD dwElapsedTime;
string FPS; 
bool Game_Init(HWND window)
{
	//zero out timer variables
	dwFrames = 0;
	dwCurrentTime = 0;
	dwLastUpdateTime = 0;
	dwElapsedTime = 0;


	//initialize Direct3D
	Direct3D_Init(window,SCREENW,SCREENH,false);

	//initialize DirectInput
	DirectInput_Init(window);

	//load the sprite image
	sunflower = LoadTexture("sunflower.bmp");

	return true;
}

void Game_Run(HWND window)
{
	static float scale = 0.001f;
	static float r = 0;
	static float s = 1.0f;

	//make sure the Direct3D device is valid
	if (!d3ddev) return;

	//update input devices
	DirectInput_Update();

	//clear the scene
	d3ddev->Clear(0,NULL,D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0,0,100), 1.0f, 0);
	d3ddev->ColorFill(backbuffer,NULL,D3DCOLOR_XRGB(0,255,0));
	//start rendering

	if (d3ddev->BeginScene())
	{
		
		//begin sprite rendering
	spriteobj->Begin(D3DXSPRITE_ALPHABLEND);

	//****************MOUSE STUFF EXTRA:**********************
	
	//set rotation and scaling
	GetCursorPos(&absCursorPos);
	double mx = absCursorPos.x;
	double my=  absCursorPos.y;
	 r = (float)(atan2(my, mx));
        //***************************
	s += scale;
	if (s < 0.1 || s > 1.25f) scale *= -1;

	//draw sprite
	width = height = 512;
	frame = 0;
	columns = 1;
	color = D3DCOLOR_XRGB(255,255,255);
	Sprite_Transform_Draw(sunflower,300,150,width,height,frame,columns,r,s,color);
	//end sprite rendering
	spriteobj->End();
	dwFrames++;
	dwCurrentTime = GetTickCount();
	dwElapsedTime = dwCurrentTime - dwLastUpdateTime;

	if (dwElapsedTime >= 1000) 
	{
		FPS = (UINT)(dwFrames * 1000.0 / dwElapsedTime);
		dwFrames = 0;
		dwLastUpdateTime = dwCurrentTime;
   //Print out FPS
	}
	//stop rendering
	d3ddev->EndScene();
	d3ddev->Present(NULL,NULL,NULL,NULL);
	}

//exit when escape key is pressed
if (Key_Down(DIK_ESCAPE)) gameover = true;

if (Mouse_Button(0)) {
	/*
	   int mx = Mouse_X();
    if (mx < 0) AbsMousePosition.x -= (float)(Mouse_X());
    else if (mx > 0) AbsMousePosition.x += (float)(Mouse_X());

		   int my = Mouse_Y();
    if (my < 0) AbsMousePosition.y -= (float)(Mouse_Y());
    else if (my > 0) AbsMousePosition.y += (float)(Mouse_Y());
	*/
//	AbsMousePosition.x += (float)(Mouse_X());
 //   AbsMousePosition.y += (float)(Mouse_Y());

}
}

void Game_End()
{
	//free memory and shut down
	sunflower->Release();

	DirectInput_Shutdown();
	Direct3D_Shutdown();
}





Any help is appreciated, thanks!

This post has been edited by alpha_x: 23 June 2012 - 11:14 PM


Is This A Good Question/Topic? 0
  • +

Replies To: Sprite Rotation corresponding to Mouse Location

#2 ButchDean  Icon User is online

  • Ex-Pro Games Programmer
  • member icon


Reputation: 877
  • View blog
  • Posts: 3,344
  • Joined: 26-November 10

Re: Sprite Rotation corresponding to Mouse Location

Posted 24 June 2012 - 06:16 AM

What do you know of Euler Angles?
Was This Post Helpful? 1
  • +
  • -

#3 alpha_x  Icon User is offline

  • D.I.C Head

Reputation: 6
  • View blog
  • Posts: 50
  • Joined: 03-May 11

Re: Sprite Rotation corresponding to Mouse Location

Posted 24 June 2012 - 06:30 AM

Not much, I was thinking of using trigonometry, I've edited my code; Am I on the right track?


GetCursorPos(&p); //get cursor position relative to screen
if (ScreenToClient(window, &p)) //ScreenToClient returns cursor position relative to the window
{

	double mx = p.x;
	double my = p.y;
	double q = (float)(atan2(my - 150, mx - 300)); //where I assume 150 and 300 seem to be the center
	r = q;
}
	
	 



where p is a global POINT. The sprite rotates according to mouse movement but is not facing exactly where the cursor is. Sorry to bother, just rather stumped on this.
Was This Post Helpful? 0
  • +
  • -

#4 ButchDean  Icon User is online

  • Ex-Pro Games Programmer
  • member icon


Reputation: 877
  • View blog
  • Posts: 3,344
  • Joined: 26-November 10

Re: Sprite Rotation corresponding to Mouse Location

Posted 24 June 2012 - 08:09 AM

That's why you need to learn about Euler Angles.
Was This Post Helpful? 2
  • +
  • -

#5 alpha_x  Icon User is offline

  • D.I.C Head

Reputation: 6
  • View blog
  • Posts: 50
  • Joined: 03-May 11

Re: Sprite Rotation corresponding to Mouse Location

Posted 24 June 2012 - 08:12 AM

Oh ok, I just thought there might be a solution with trigonometry but I couldn't really get that one. I will start reading up about Euler Angles, any links to tutorials that you think are good would be appreciated.

Thanks again

BTW: My game is in 2D, left that bit out sorry!

This post has been edited by alpha_x: 24 June 2012 - 08:13 AM

Was This Post Helpful? 0
  • +
  • -

#6 alpha_x  Icon User is offline

  • D.I.C Head

Reputation: 6
  • View blog
  • Posts: 50
  • Joined: 03-May 11

Re: Sprite Rotation corresponding to Mouse Location

Posted 24 June 2012 - 08:44 AM

I phoned my professor for some help on the project and he insisted to me that Euler Angles are not necessary for this 2D Demo.

He gave me a bit of help but the image still does not point in the right direction:

	//double rat = atan(384-mx, 512-my);
	double o = 512 - p.y;
	double a =  p.x - 512;

	double rat = o / a; //ratio
	double ang = atan(rat); //tan function
	double rAng = toDegrees(ang); //get degrees
	if (a < 0) {
		rAng += 180; 
	}
	if (o < 0 && a > 0) {
		rAng +=360;
	}
	double q =toRadians(rAng); //convert to radians
	r = q; //set rotation transform



Here is my code for toRadians and toDegrees:

double toDegrees(double radians) 
{
	return (radians * (180.0/3.1415926535)); 
}

double toRadians(double degrees) 
{
	return (degrees *(3.1415926535/180.0)); //where 3.1415... is PI
}



I do not want to be spoon-fed, just a point in the right direction.
Sorry to bother!

This post has been edited by alpha_x: 24 June 2012 - 08:48 AM

Was This Post Helpful? 0
  • +
  • -

#7 ButchDean  Icon User is online

  • Ex-Pro Games Programmer
  • member icon


Reputation: 877
  • View blog
  • Posts: 3,344
  • Joined: 26-November 10

Re: Sprite Rotation corresponding to Mouse Location

Posted 24 June 2012 - 09:33 AM

There are several reasons why your approach will not work:

1. Your rotations will need to be about the origin (as in 'world space origin), or your results will be undefined.
2. You are not making use of vectors.
3. If you were using vectors you would be able to use rotation matrices.

Your professor should have made you aware of this stuff, just telling you that 'Euler Angles are not necessary' isn't good enough.
Was This Post Helpful? 1
  • +
  • -

#8 alpha_x  Icon User is offline

  • D.I.C Head

Reputation: 6
  • View blog
  • Posts: 50
  • Joined: 03-May 11

Re: Sprite Rotation corresponding to Mouse Location

Posted 24 June 2012 - 10:30 AM

Ok, I am using vectors now and have created a generic function to handle drawing transformed sprites.

void Sprite_Transform_Draw(LPDIRECT3DTEXTURE9 image, int x, int y, int width, int height, int frame, int columns, float rotation, float scaling, D3DCOLOR color)
{
	//create a scale vector
	D3DXVECTOR2 scale (scaling, scaling);

	//create a translate vector
	D3DXVECTOR2 trans (x , y);

	//set center by diving width and height by two
	D3DXVECTOR2 center ((float) (width * scaling) / 2, (float) (height * scaling) / 2);
	//D3DXVECTOR2 center ((float) (1024 / 2), (float)(768/2));
	//create 2D Transformation matrix
	D3DXMATRIX mat;
	D3DXMatrixTransformation2D(&mat, NULL, 0, &scale, &center, rotation, &trans);

	//tell sprite object to use the transform
	spriteobj -> SetTransform(&mat);

	//calculate frame location in source image
	int fx = (frame % columns) * width;
	int fy = (frame / columns) * height;
	RECT srcRect = {fx,fy,fx+width,fy+height};

	//draw the sprite frame
	spriteobj->Draw(image,&srcRect,NULL,NULL,color);
}



I managed to rotate the player using the left and right arrow keys like so:
//rotateAngle is global to this cpp file
	 r = toRadians(rotateAngle);
	Sprite_Transform_Draw(sunflower,300,150,width,height,frame,columns,r,s,color);

//Further down where I handle Input using DINPUT8
if (Key_Down(DIK_LEFT)) rotateAngle -= 1;

if (Key_Down(DIK_RIGHT)) rotateAngle += 1;




But I am still struggling with how to figure out the angle of inclination between where my player is and the mouse cursor. Any ideas?

Sorry again but thanks for all the help ButchDean! I hope to have this little problem solved soon.
Was This Post Helpful? 0
  • +
  • -

#9 ButchDean  Icon User is online

  • Ex-Pro Games Programmer
  • member icon


Reputation: 877
  • View blog
  • Posts: 3,344
  • Joined: 26-November 10

Re: Sprite Rotation corresponding to Mouse Location

Posted 24 June 2012 - 10:43 AM

If I understand what you're trying to do, the tail end of your vector will be the center of origin for the player, and the head of the vector will be the current location of the mouse - that will form your vector.

You should be able to work it out from there.
Was This Post Helpful? 0
  • +
  • -

#10 alpha_x  Icon User is offline

  • D.I.C Head

Reputation: 6
  • View blog
  • Posts: 50
  • Joined: 03-May 11

Re: Sprite Rotation corresponding to Mouse Location

Posted 25 June 2012 - 12:33 AM

I messed around with it a bit and this was my solution:
double mx = p.x;
double my = p.y;  
double q = (float)(atan2(mx-300,150-my)); /300 and 150 are the sprite's static x and y value
r = q; //r corresponds to rotation matrix



I think I was calculating the angle of inclination wrong...
Here is the result,

Posted Image


So far it seems to be working or is it not?

This post has been edited by alpha_x: 25 June 2012 - 12:44 AM

Was This Post Helpful? 0
  • +
  • -

Page 1 of 1