Shmup design question: int vs float/double

Started by
8 comments, last by matrisking 13 years, 10 months ago
Hey all,

I've been working on writing a 2D shoot 'em up in C++/SDL. Pretty much everything coordinate-related is type "int", which makes things very easy when conceptualizing the conversion from an in-game coordinate to a pixel on the screen. However, the limitations of int are quickly becoming apparent.

- All game objects contain xVelocity and yVelocity members that correspond to "number of pixels moved per frame". This in itself severely limits the number of options I have for bullet speed.
- My function that fires bullets "at" a gameObject ends up being horribly inaccurate as I'm essentially doing trig on ints.
- When doing collision detection, I end up converting the relevant variables to double anyways.

When looking at issues like this, it seems obvious that ints aren't the way to go. However, I have two primary concerns about switching to float/double:

1) Performance. The long term goal for this engine is bullet hell, and if I'm moving, updating, and detecting collisions for tons of floats instead of ints, am I going to have performance issues?

2) Displaying everything on the screen. I have absolutely NO idea how something like this would work. Do I just round all the coordinate values that I'm going to display on the screen? This seems a little inaccurate when precision movement/dodging will play an integral role in the game.


Am I worrying about nothing? Computers are fast, and pixels are really small. This is my first real-time game, so I'm not sure how valid these concerns are.

So... to int or not to int? Thanks in advance!



Edit: Typo
Advertisement
Use floats not doubles.

Look up a fast float->int conversion if you're worried about performance when you need to convert between the two types.
Your CPU can process floats at an astounding speed. They might be slower than integers, but given the limitations of integers it is clear it is comparing apples to oranges.

I can't imagine the updating will tax your CPU, even if the screen were literally covered in bullets.

You can cast the floats to integers when drawing, or you can round them. It doesn't really matter, provided you are consistent. Remember, mathematical rounding is a convention, and an arbitrary one at that. The user will never be able to tell which you use.
Quote:Original post by rip-off
You can cast the floats to integers when drawing, or you can round them. It doesn't really matter, provided you are consistent. Remember, mathematical rounding is a convention, and an arbitrary one at that. The user will never be able to tell which you use.


You most definitely want to round the coordinates, not truncate them:
int ix(fx + 0.5f);


For example, when a bullet is at x=15.9f, you want to display it at x=16, not x=15. Technically speaking, yes, it's only a one pixel difference, but it will become very annoying for any moderate gamer because collisions will appear to be happening just a slight moment earlier than they should be.
If you program carefully you can use either.

If you do not get enough precision on ints you can scale them differently thus use a fix point scheme.

On a modern processor however floats and double precision is fast enough not to worry about performance.

Things to avoid though are having to much divisions in the innermost loops.

For instance if you divide a float by a constant a/0.1234567f it is better to write a*8.1f.

And also never compute anything more often than its needed..move as much computations out to outermost loops.


For the sinus if you stick with integers...
You need to convert the integer to a float or double since they usually take radians as input thus a full circle is 2*pi. thus do something like this for float..

Assume you have an integer angle

#define PI 3.14159265358979f
#define ONE_TURN_FOR_INTEGER_ANGLE 123.0f

int angle;
float result;

result=sinf(2.0f*PI*(((float)angle)/ONE_TURN_FOR_INTEGER_ANGLE);

Then of course you need to scale the result and turn it to integer again for your other integer stuff..also add your own number for one full turn instead of 123.0f...
Also use math library pi M_PI is better..

1) Performance....

It`s not about performance, but more of quality!
(I`d say that if you make exposion with 10 M+ partickes, and it looks skit, you have failed!)
Use less bullets, but make illusion of heavy rain of lead and rockets! (cheat!)

2) Displaying everything on the screen. I have absolutely NO idea how something like this would work. Do I just round all the coordinate values that I'm going to display on the screen? This seems a little inaccurate when precision movement/dodging will play an integral role in the game.


1280x720+ res, 50+ fps and motion blur, and there is no human who can see invidual pixel errors :D

/Tyrian
Quote:Original post by matrisking
Am I worrying about nothing?
Yes.
Pragmatically, just use float. I can't see you having so many entities and particles that it should ever become a problem -- I think you'd hit overdraw long before the actual transformation of coordinates becomes a problem, at least on any relatively modern system (read mid-tier Pentium 3, possibly older).

If you happen to be developing on something older or more limited (or just for the heck of it) you could also look into fixed-point math -- essentially, you scale all integer values up by some number of bits, and then you get than many bits of sub-unit precision. Float is probably still faster on modern machines, but if your platform didn't have an FPU, or it was needed for something else, then it would make sense.

throw table_exception("(? ???)? ? ???");

If you are using less than 10000 bullets (an absurd amount) you have absolutely nothing to worry about in this regard.
Thanks to everyone that replied. I ended up switching all the coordinate variables to float and everything seems to be working well. Actually, everything seems to be working GREAT, the collision detection feels a little better and the "fire at" functions are 10x more accurate with no noticeable performance hit.

Thanks again!

This topic is closed to new replies.

Advertisement