Sign in to follow this  
d h k

EASY: Strange Formula Issue

Recommended Posts

d h k    439
Hello everybody, I've been having great progress in the last day and now I recently added health bars to my "RTS-like" game. Anyways, over the player object I draw a white healthbar consisting of four lines creating a long rectangle that goes from the left of the player to the right, basically just like the healhbar over units in C&C. Comming to the point, I then try to draw the content of the healthbar in the white box. I use this code:
DrawLine ( globals.screen, player.position_x, player.position_y - 6,
player.position_x + ( ( player.health / 100 ) * 32 ), player.position_y - 6 );
But it ONLY works when the player.health value equals 100. First I thought it may be a rounding error, but when I tried setting player.health to 50 ( that would return 0.5 * 32 = 16 ) it still won't work; it will only display 1 pixel far ( so it returned 0 from the formula obviosly when it should've returned 16 )... But the formula is right, it should work perfectly, what am I doing wrong? The error might be something really dumb, it's about three in the morning here and I didn't get much sleep yesterday... [Edited by - d h k on June 12, 2005 4:20:43 AM]

Share this post


Link to post
Share on other sites
nprz    692
If player.health is an int, it is probably casting it to an int when it does the division. so try something like float(player.health / 100) instead of just player.health / 100. I'm not positive, maybe float(player.health) / 100, might work as well.

Share this post


Link to post
Share on other sites
d h k    439
Thanks for the quick response but both your suggestions did not change anything at all...

[Edited by - d h k on June 12, 2005 4:05:06 AM]

Share this post


Link to post
Share on other sites
nprz    692
OK, I tested the first suggestion and that doesn't work, but

( float(player.health) / 100.0 ) * 32

should work. unless it needs something really extreme like
float( float(player.health) / 100.0 ) * 32

Share this post


Link to post
Share on other sites
d h k    439
Thank you, it worked now. I forgot that I also set the initial player.health to somehting like 2 or so to debug something, that's why I first thought it wouldn't work...

Thanks again.

EDIT: By the way, is there anyway to get around the warnings: "warning C4244: 'argument' : Possible data loss ( converting 'float' to 'unsigned char' )" ?
I receive this warning for everytime I use the float ( ... ) command.

[Edited by - d h k on June 12, 2005 4:12:17 AM]

Share this post


Link to post
Share on other sites
Programmer16    2321
Quote:
Original post by d h k
EDIT: By the way, is there anyway to get around the warnings: "warning C4244: 'argument' : Possible data loss ( converting 'float' to 'unsigned char' )" ?
I receive this warning for everytime I use the float ( ... ) command.


#pragma warning(disable: 4244) // disables
//at the end of the code
#pragma warning(default: 4244) // enables



I believe that is correct.

Edit: Oops, I don't really use these that much (so I forgot that instead of ',' you need to use ':').

[Edited by - Programmer16 on June 11, 2005 8:19:43 PM]

Share this post


Link to post
Share on other sites
d h k    439
Those #pragma expressions just added two more warnings... Both of them are "warning C4081: ':' expected; ',' found"...

Anything I can do against THAT, except disable warning 4081? :)

EDIT: I found the error. :) That was an easy one... Just had to READ the error message...

[Edited by - d h k on June 12, 2005 4:23:55 AM]

Share this post


Link to post
Share on other sites
Zahlman    1682
Yeah, it's complaining about the cast back from the float result into an integral value (char is an integral, numeric type after all).

Actually though there's a much simpler way to go about it - just do the multiplication first and then the division :) I'll let you think about why it makes a difference. ;)

Share this post


Link to post
Share on other sites
d h k    439
Thanks for your reply, Zahlmann. I suppose your way is better; when you don't disable warnings it just doesn't have this hacking feel to it.

I do it your way now and it does not create any warnings or anything, but it gives wierd results. With player.health equals 100 it's fine, but once I put it to 99 or anything lower it seems to expand further to the right instead of becoming smaller... Although with my calculator the formula works fine...

Here's the code:


DrawLine ( globals.screen, player.position_x, player.position_y - 6,
player.position_x + ( ( 100 * 32 ) / player.health ), player.position_y - 6 );


[Edited by - d h k on June 12, 2005 4:00:49 AM]

Share this post


Link to post
Share on other sites
QuestOfDreams    122
(player.health/100)*32 is not the same as (100*32)/player.health!
player.health*32/100 would be the correct formula
(or with with floats and casts: (unsigned char)(player.health*0.32f) )
remember that an integer division always cuts off the decimal places (no rounding!)

Share this post


Link to post
Share on other sites
Zahlman    1682
Quote:
Original post by d h k
Thanks for your reply, Zahlmann. I suppose your way is better; when you don't disable warnings it just doesn't have this hacking feel to it.

I do it your way now and it does not create any warnings or anything, but it gives wierd results. With player.health equals 100 it's fine, but once I put it to 99 or anything lower it seems to expand further to the right instead of becoming smaller... Although with my calculator the formula works fine...

Here's the code:


DrawLine ( globals.screen, player.position_x, player.position_y - 6,
player.position_x + ( ( 100 * 32 ) / player.health ), player.position_y - 6 );


Er. You still want the health to be in the numerator and 100 to be in the denominator. It should be like:


DrawLine ( globals.screen, player.position_x, player.position_y - 6,
player.position_x + ( ( player.health * 32 ) / 100 ), player.position_y - 6 );


Although, this really makes more sense as a method on the Player:


player.drawHealth(globals.screen);

// in the Player's class

void Player::drawHealth(Screen target) {
// first calculate width and y-position of the bar so that it isn't all one
// huge expression
int health_y = position_y - 6;
int health_w = position_x + ( ( health * 32 ) / 100 );
DrawLine(target, position_x, health_y, position_x + health_w, health_y);
}


See how it eliminates all the "player." spam? :)

Share this post


Link to post
Share on other sites
d h k    439
Allright, I finally got it. DOn't know why I messed up that formula, I guess I tried the correct formula in the calculator but then forgot to change it in the code or something stupid as that...

Thanks everybody.

Oh, and I will make it a method in player once I can find some time, right now I have lots of things in my code that can be better grouped together in functions/structures/methods...

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