Dear Sirs,
some weeks ago I found Amarillions great tutorial and i leand a lot from it.
I was really fascinated, so i decided to translate your tutorial into german.
Now i'm trying to translate and update the codes too. I want to translate them into C++ with grphics.h(WinBGIM), C++ with SFML, C++ with SDL, C++ with Allegro 5, Java, Java-Script, Blitz 3D, Blitz Max, FreeBasic and Pure Basic. Perhaps there are more coding languages to come. But i've got a problem with the circ7 (home_in) from the homing missiles example. My rocket hit the target for only one time, a second time the rocket misses the target. When i set the target_x and the target_y manually (for example),
the rocket misses it's target every time.
Perhaps you can have a look at the code and help me find out what's wrong????!!!!
I used CodeBlocks as IDE and the totally simple grphics.h(WinBGIM) as graphical engine.
Here the full code:
I applied the whole project, compressed with 7Zip, to this e-mail.
Best regards and thx a lot for your great Tutorial and your help,
Merlin
You can't use int for the angles. Change them to double, i.e.:
double angle = 0; double target_angle;
And then just remove the stuff with 0xffffff as you are not using itofix anymore, i.e.:
if (fmod(angle - target_angle, 2 * pi) < pi) { angle -= angle_stepsize; }
Lastly, angle_stepsize of 1 is a very large angle, you probably want 1 * pi / 180 instead.
Btw. "Grösse" is not a German word except in Switzerland/Liechtenstein, you probably want to use "Größe" for a general audience.
Dear Elias,
i changed my code, but now "rien ne vas plus". The rocket is missing its target every time?!
My Code:
Thanx a lot for your advice,
Merlin
int angle_stepsize = 1* PI / 180;
This has a value of exactly zero, because the computation gives around 0.017 and then you store it as an integer. Change the variable to a double.
Also, you may want to get the habit of typing literal numbers with a decimal point when you want floating computation (ie 1.0 * PI / 180.0). Here you have no problem, but there is a huge difference between 1/2 * x and 1.0/2.0 * x.
Edit: Edit: In fact you'll also need to set x and y as doubles, because your steps are tiny (1 pixel), so this part :
will modify x or y by a maximum of 1 pixel at a time.
Great, it's nice to see my tutorial is still useful to people!
Audric has the right answer for your problem. Be careful for rounding floating point values. The tutorial recommends fixed point values, which is a bit outmoded and also makes it all Allegro 4 specific. Perhaps I should update it one of these days. Nowadays, I would say (directly contradicting the tutorial): use double/float instead of fixed.
If you manage to get the code right for the various graphics library, I can reference them in the article if you like.
Dear Audric and Amarillion,
i changed everything to double but now, sadly the rocket flies in a circle and never hits the target.??????
@Amarillion
It's very friendy from you to reference me in your article, let me finish it and i will send you the codes!:D
Here the code:
Thanks for for help and advice,
Merlin_MLN
It's possible that if the turning speed (i.e. angle_stepsize) is slow compared to the speed (i.e. length), you can never turn fast enough to reach the target. (Think of the international space station constantly turning towards earth, but missing it because it moves so fast)
Try increasing the angle_stepsize, or decreasing the speed (-> length). Does that help?
No Amarillion, the rocket is still flying on a circle!
I'm really not understanding what I'm doing wrong!???:-[
Thanx a lot for your advice,
Merlin
if ((angle - target_angle, 2*PI) < PI)
Did you lose the fmod there? The idea is this:
angle = 90, target_angle = 0, fmod(90, 360) = 90 -> angle = angle - 1 = 89
angle = 270, target_angle = 0, fmod(270, 360) = 270 -> angle = angle + 1 = 271
angle = 0, target_angle = 90, fmod(-90, 360) = 270 -> angle = angle - 1 = 359
Without the fmod you always turn left and fly in a circle. Did you actually read the original article?
Dear Sirs,
here is a working version of the code (with fixed)!!!!
I will provide a (double) version as soon as possible!
@Elias
Yes i really lost the fmod(), I think I lost it while I did copy&paste or so!
Sure I read the original article . Next time I will pay more attention!!!!
Thanks for your help and advice,
Merlin
The tutorial recommends fixed point values, which is a bit outmoded and also makes it all Allegro 4 specific. Perhaps I should update it one of these days. Nowadays, I would say (directly contradicting the tutorial): use double/float instead of fixed.
Just comment that I find fixed-point still useful. You don't need to check values to know if angle overflows the circle, you can do fast calculations with bit operations and if you need to get a lot of cos/sin values in a row the use of an array would be faster (depending on the CPU cache, of course).
Just my opinion.
Fixed-point and custom formats are actually very common in AAA studios. For one reason, the self-wrapping feature Niunio mentioned.
You'll see SINGLE BYTE, unsigned floats in places where memory bandwidth is key and the underlying DATA being represented can both survive the granularity, as well as take advantage of domains smaller than all real numbers, such as unsigned. For an easy example. If your number can't be outside 0.0 to 1.0, a float or double wastes bits. (In areas where that data is a bottleneck.)
That said, >90% of us don't need them for an indie game where computing resources usually far exceed our ability to create content that exploits them. (Barring stupid decisions like using algorithms of unnecessarily high time-complexity.)
float is actually very dangerous if you don't make sure to wrap it back into the 2pi range. It takes only a few 1000 rotations in the same direction otherwise before accuracy drops down to full angles.
It's even worse with x/y positions... if your level is big enough that you can reach around pixel 200,000 then you're down to 2 decimal points, i.e.:
float x = 300000; float y = x + 0.01; if (y > x) // false if (y == x) // true
It will probably mean while your physics work perfectly fine close to the center you get very strange behavior farther away. Of course simply using double instead of float should fix that in most cases
Likewise,
Fun fact: At 16,777,216, floats no longer have the resolution to increment by one.
The code:
for(float i = 0; i <= 16,777,216 + 1; i++) //16,777,216 + 1 = 16,777,216 (rounded down)
will never terminate.
So you should never rely on a float for an integer value that exceeds that value. And likewise, for decimal numbers that you care about that exceed the precision. And on the flip side, you CAN use a float for things like array indices if you need to. (Using float x for position in space, and when you land on a space station, you x = the map array index.) But it's still probably a bad idea unless you NEED that optimization...
It will probably mean while your physics work perfectly fine close to the center you get very strange behavior farther away
I had that happen to me, even with doubles. I was making a 2-D KSP using actual universe scale dimensions. It would fall apart adding a small distance every frame (velocity) at huge distances. fixed point are great for that in the sense that their precision never changes where ever you are in the grid.
I still wonder sometimes why CPU's don't natively support fixed operations.
All good points. But I think I should at least update the article to explain the pros and cons. And for a beginner tutorial, fixed vs float might be too much of a distraction of the real point, which is about trigonometry. Maybe I should write a separate article on fixed vs float.
All good points. But I think I should at least update the article to explain the pros and cons. And for a beginner tutorial, fixed vs float might be too much of a distraction of the real point, which is about trigonometry. Maybe I should write a separate article on fixed vs float.
Agree.
Oh yeah, I don't think it's be great for the article. I was just talking about some cool stuff I learned about fixed/float.
I'm bookmarking this thread. I had used these functions in A4 for turrets that always face the player, but now that I am reviewing this material again with much more experience I can appreciate better the ingenuity of using integers in lieu of floats when granularity is low. I feel like this would be great in saving data or networking, so you can send 1-2 bytes of data for a float instead of 4+ bytes.