Sign in to follow this  
Hassanbasil

few questions about sprites

Recommended Posts

Hello, mates. first question is, how to draw text over the sprite? I'm trying to draw text on my sprites, but it seems the texture is being drawn over the text, how can i make the text be over the texture? here's my render code:
		Sprite->Begin ( D3DXSPRITE_ALPHABLEND );

		if ( bText )
		{
			RECT rc;
			rc.left = text.x;
			rc.top = text.y;
			TEXTMETRICA met;
			text.font->GetTextMetricsA ( &met );
			rc.right = rc.left+(strlen(text.Text)*met.tmHeight) + 10;
			rc.bottom = rc.top+met.tmHeight+10;
			text.font->DrawTextA ( Sprite, text.Text, 300, &rc, DT_NOCLIP, text.color );
		}

		D3DXMATRIX mat;

		D3DXMatrixTransformation2D ( &mat, NULL, 0.0, &D3DXVECTOR2 ( fScale/100, fScale/100 ),
			&D3DXVECTOR2 ( rotX, rotY ), D3DXToRadian ( fAngle ), &D3DXVECTOR2 ( X, Y ) );

		Sprite->SetTransform ( &mat );

		Sprite->Draw ( texture.tex, NULL, NULL, NULL, diffuse );

		Sprite->End ( );





if i set first ID3DXSprite::Draw() parameter to NULL, i see the text ( and obviously no texture ), but how can i show both, text and texture? second question is, how to move a sprite, and how to point it to a specific x,y coordinates? i currently have the following:
void hxSprite::Move ( int units )
{
	X -= sin ( fAngle )*units;
	Y -= cos ( fAngle )*units;
}
void hxSprite::Point ( int x, int y )
{
	float DX   = x - X+rotX;
	float DY   = y - Y+rotY;
	float DIST = sqrt ( (DX*DX) + (DY*DY) );
	if( DIST > 0 )
		fAngle = atan2f ( DX, DY );
}





both of them have weird behaviors, i believe my maths are wrong, note that fAngle is the sprite angle thanks a lot. -Hassan

Share this post


Link to post
Share on other sites
The easiest solution to drawing text on top of your sprite is to move the DrawTextA() call outside of the End() call of your sprite, and pass NULL as the sprite parameter of DrawTextA().


Sprite->Begin ( D3DXSPRITE_ALPHABLEND );

D3DXMATRIX mat;

D3DXMatrixTransformation2D ( &mat, NULL, 0.0, &D3DXVECTOR2 ( fScale/100, fScale/100 ),
&D3DXVECTOR2 ( rotX, rotY ), D3DXToRadian ( fAngle ), &D3DXVECTOR2 ( X, Y ) );

Sprite->SetTransform ( &mat );

Sprite->Draw ( texture.tex, NULL, NULL, NULL, diffuse );

Sprite->End ( );

if ( bText )
{
RECT rc;
rc.left = text.x;
rc.top = text.y;
TEXTMETRICA met;
text.font->GetTextMetricsA ( &met );
rc.right = rc.left+(strlen(text.Text)*met.tmHeight) + 10;
rc.bottom = rc.top+met.tmHeight+10;
text.font->DrawTextA ( NULL, text.Text, 300, &rc, DT_NOCLIP, text.color );
}






This is because ID3DXSprite does a few internal optimizations by default - one of these is sorting by texture. Chances are that it's drawing the text before it draws your sprite.

As for your second question, what exactly are you trying to do? To draw a sprite at a specific location, you use D3DXMatrixTransformation2D() to build a transformation matrix and call SetTransform() on your sprite object to tell it what transform to use. You have done this in your first snippet of code, so I am confused as to what your question is.

Share this post


Link to post
Share on other sites
so the text cannot be a part of the sprite? then what is the sprite parameter for? oh well then, is it possible to draw text to a texture?

as for the second question, my sprite has a position (x,y) and an angle, using them, i want to be able to move my sprite forward and point it.

as for moving forward, lets say the angle is 0, that means it's pointing upwards, so i want to move it upwards n units, if the angle is 45, move it to top right, etc.

as for pointing, it's clear isnt it? i have an angle, when i call Point() function, i want the angle to be facing the x,y coordinates passed as parameters

Share this post


Link to post
Share on other sites
Quote:
Original post by Hassanbasil
so the text cannot be a part of the sprite? then what is the sprite parameter for? oh well then, is it possible to draw text to a texture?


It can, but because of internal optimizations, it will probably draw the text before any of your sprites. There's really no reason to worry about it unless it's causing a severe performance drop, and in this case it shouldn't.

Quote:
Original post by Hassanbasil
as for the second question, my sprite has a position (x,y) and an angle, using them, i want to be able to move my sprite forward and point it.

as for moving forward, lets say the angle is 0, that means it's pointing upwards, so i want to move it upwards n units, if the angle is 45, move it to top right, etc.

as for pointing, it's clear isnt it? i have an angle, when i call Point() function, i want the angle to be facing the x,y coordinates passed as parameters

If you want to move a sprite, you'll need a location and velocity. You sort of do this, but it would be easier to have separate vectors for location and velocity. Then, hxSprite::Move() becomes as simple as location += velocity;.

Polar->Rectangular coordinate formulas are
x = ρ*cos(θ)
y = ρ*sin(θ)

You seem to have these in reverse and are subtracting them instead of adding them. I can't really see anything wrong with hxSprite::Point(). Perhaps someone else can tell you what's wrong there.

Share this post


Link to post
Share on other sites
atan2f is declared like this:

float atan2f(
float y,
float x
);

Are you sure you don't need to swap y and x?

Then you wrote

float DX = x - X+rotX;
float DY = y - Y+rotY;



x and X are positions, I don't know if the name is misleading but why there are rotX and rotY (rotations?).

About performance, if you just want to check if x == X and y == Y, don't use sqrt that it's one of the most heavy functions you can call. And probably atan2f will check this case for you anyway (test it).

Ah and this test

if( DIST > 0 )


feels bad. DIST is a float, writing 0 like that is an integer. There may be some odd rounding behind the scenes (source of bugs or just loss of speed).

Remember to always put .0f when needed.
So try

if( DIST > 0.0f )

Share this post


Link to post
Share on other sites
main reason for drawing text over a sprite is for the rotation, so the text can be rotated with the sprite, but if im gonna use another sprite for the text, this just..well, not neat? i really want the text to be a part of the texture, so i can even write text to object's textures, not just sprites

both functions doesn't work properly now :

void hxSprite::Move ( float units )
{
if ( !vaild )
{
MainCore->PostError ( this, "invaild sprite ( or sprite havnt been created yet", false );
return;
}
X += ( cos ( fAngle ) * units );
Y += ( sin ( fAngle ) * units );
}
void hxSprite::Point ( int x, int y )
{
if ( !vaild )
{
MainCore->PostError ( this, "invaild sprite ( or sprite havnt been created yet", false );
return;
}
float DX = x - X+(rotX*(fScaleX/100));
float DY = y - Y+(rotY*(fScaleY/100));
if ( X == DX && Y == DY )
return;
fAngle = D3DXToDegree ( atan2f ( DY, DX ) );
}



point works sometimes, and sometimes not
move goes in a totally wrong way

anyway, i think i might do it better using a forward vector, but how can i extract the angle out of the vector for D3DXMatrixTransformation2D ?

Share this post


Link to post
Share on other sites
Where you get fAngle here, you went from radians to degrees.

fAngle = D3DXToDegree ( atan2f ( DY, DX ) );



But the input of the sin and cos functions (remember to use sinf and cosf on floats) are radians.

About move funcion, I can't see nothing wrong but it may be that your origin and the direction of the positive axis aren't the ones you expect. Usually X axis is from left to right but Y can vary (top-down or bottom-up). Try to change the sign of Y. Or if not, please detail more "totally wrong way" ;)

Share this post


Link to post
Share on other sites
made my move functions like:

X += ( cos ( D3DXToRadian ( fAngle ) ) * units );
Y += ( sin ( D3DXToRadian ( fAngle ) ) * units );




it bugs out at some degree's, or lets say MOST degrees, so it doesnt move, dunno how to explain it as there are various bugs at various degree's ( it the degree is 0 or 90 or -90 or 180, it works fine, others, either doesnt move, or moves in a wrong direction )

EDIT: it seems the problem is in converting from float to int, since x/y can only be integers, sometimes sin and cos returns low values, and they become zero when they are converted, solved:


void hxSprite::Move ( float units )
{
if ( !vaild )
{
MainCore->PostError ( this, "invaild sprite ( or sprite havnt been created yet )", false );
return;
}
if ( units == 0 )
return;

float xm, ym;
xm = ( cos ( D3DXToRadian ( fAngle ) ) * units );
ym = ( sin ( D3DXToRadian ( fAngle ) ) * units );

if ( xm < 1.0f && xm > 0.0f )
xm = 1.0f;
if ( ym < 1.0f && ym > 0.0f )
ym = 1.0f;

if ( xm > -1.0f && xm < 0.0f )
xm = -1.0f;
if ( ym > -1.0f && ym < 0.0f )
ym = -1.0f;

X += xm;
Y += ym;
}

Share this post


Link to post
Share on other sites
pointing also work fine now, thank you everyone who replied.

only one thing left which is writing over textures (or sprites), how can it be done?

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this