Skip to main content
GameDev.net gamedev.net
🔒 Locked

2D rotation acceleration problems??

Started by wicked357 Feb 19, 2009 at 10:13 PM 2 replies 750+ views
Original Post
wicked357
wicked357
Ok I have been here before asking about rotation of sprites in 2D, I got some great suggestions and I took a long break and now I jumped back into it and got a rotation of my sprite and it rotates perfectly. Now my acceleration wont accelerate in the direction I am facing, anyone got an idea on how to resolve this without me ending up taking a long break again and coming back to it?? Here is my code

LPDIRECT3DTEXTURE9 sprite_image;
SPRITE image;

LPD3DXSPRITE sprite_handler;

	image.position.x = 500.0f;
	image.position.y = 600.0f;
	image.position.z = 0.0f;
	image.direction.x = 0;
	image.direction.y = 0;
	image.speed.x = 0.0f;
	image.speed.y = 0.0f;
	image.SPRITE_SPEED = 1;
	image.MOVE_UP = -1;
	image.MOVE_DOWN = 1;
	image.MOVE_LEFT = -1;
	image.MOVE_RIGHT = 1;


	static float xrot = 0.0f;
	static float yrot = 0.0f;
	static float zrot = 0.0f;
if (GetTickCount() - start >= 30)
    {
        //reset timing
        start = GetTickCount();

		if(KEY_DOWN(VK_UP))
		{
			image.speed.y += image.SPRITE_SPEED;
			image.direction.y = (float)image.MOVE_UP;
			if(image.speed.y >= 8.0f)
				image.speed.y = 8.0f;
		}
		else if(KEY_DOWN(VK_DOWN))
		{
			image.speed.y -= 0.20f;
			if(image.speed.y <= 0)
				image.speed.y = 0;
		}
		if(KEY_DOWN(VK_LEFT))
		{
			zrot -= 5.0f;
		}
		else if(KEY_DOWN(VK_RIGHT))
		{
			zrot += 5.0f;
		}

		image.position.y += image.direction.y * image.speed.y;

	}

        //start rendering
    if (d3ddev->BeginScene())
    {
		//erase the entire background
        d3ddev->StretchRect(back, NULL, backbuffer, NULL, D3DTEXF_NONE);

        //start sprite handler
        sprite_handler->Begin(D3DXSPRITE_ALPHABLEND);

		D3DSURFACE_DESC desc;

		sprite_image->GetLevelDesc(0, &desc);

		const int centerX = desc.Width >> 1;
		const int centerY = desc.Height >> 1;

		D3DXMATRIX rotate, trans, scale, result;

		D3DXMatrixIdentity(&result);

		D3DXMatrixTranslation(&trans, (float)-centerX, (float)-centerY, 0);

		D3DXMatrixMultiply(&result, &result, &trans);

		D3DXMatrixScaling(&scale, 1, 1, 1);

		D3DXMatrixMultiply(&result, &result, &scale);

		D3DXMatrixRotationZ(&rotate, D3DXToRadian(zrot));

		D3DXMatrixMultiply(&result, &result, &rotate);

		D3DXMatrixTranslation(&trans, (float)+centerX, (float)+centerY, 0);

		D3DXMatrixMultiply(&result, &result, &trans);

		D3DXMatrixTranslation(&trans, image.position.x, image.position.y, 0);

		D3DXMatrixMultiply(&result, &result, &trans);

		sprite_handler->SetTransform(&result);

		sprite_handler->Draw(sprite_image, NULL, NULL, NULL, D3DCOLOR_XRGB(255, 255, 255));

        //stop drawing
        sprite_handler->End();

        //stop rendering
        d3ddev->EndScene();
    }
shaolinspin
shaolinspin
You need to rotate the acceleration vector before adding it to the sprite's velocity. I assume you define an angle of zero as being when the sprite points straight upwards towards the top of the screen, and from your code, an anticlockwise rotation is negative.

For a start, your approach to storing the physical properties is a bit confusing. Try to have a vector for position, one for velocity and one for acceleration. Store the sprite's forwards acceleration as a floating point number. You shouldn't need a variable to store direction, that's what vectors are for.

When the sprite is at angle zrot and you press UP, you first need to work out the x and y acceleration. Currently you are just adding to the y position, which will always make the sprite move up or down relative to the screen. The actual acceleration will be a vector (with both x and y components) given by:

acc.x = acceleration*sin(zrot);
acc.y = acceleration*cos(zrot);

Edit: If you're using the y-axis pointing downwards convention (i.e. 0,0 is the top left of your coordinate system), then acc.y = -acceleration*cos(zrot);

(Remember to convert your degrees to radians first! For reversing, just negate the equations)

Then add the acceleration to the velocity vector, and add the velocity vector to the position vector.

Also, I'd avoid using GetTickCount() - use timeGetTime() instead as it has better resolution.

Hope this helps, if I'm not being clear enough please say so!
wicked357
wicked357
Thanks for the tips. I'll be sure to try messing around with this when I get home later.
wicked357
wicked357
Okay, I have tried adding what you suggested to my code. I don't know if I am just fried or what, but I can't seem to get this to do anything close to right. I have tried many different ways to implement that to my code and I'm unable to figure this out. position and speed is a vector2 and I added acc as a vector2. I tried replacing GetTickCount() with timeGetTime() and it doesn't work I get errors.

Here are my errors:
Error	1 error LNK2001: unresolved external symbol __imp__timeGetTime@0 game.obj sprite_movementError	2 fatal error LNK1120: 1 unresolved externals sprite_movement.exe	sprite_movement

This is my movement code:
if (GetTickCount() - start >= 30){    //reset timing    start = GetTickCount();    if(KEY_DOWN(VK_UP)) //accelerate    {	image.speed += image.acc;    }    else if(KEY_DOWN(VK_DOWN)) //deccelerate    {	image.speed.y -= 0.20f;	if(image.speed.y <= 0)	image.speed.y = 0;    }    if(KEY_DOWN(VK_LEFT)    {	zrot -= 5.0f;    }    else if(KEY_DOWN(VK_RIGHT))    {	zrot += 5.0f;    }    image.acc.x = image.acc.x*sin(zrot);    image.acc.y = -image.acc.y*cos(zrot);    image.position.x += image.speed.x;    image.position.y += image.speed.y;}

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.