Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » What's wrong with this code?

This thread is locked; no one can reply to it. rss feed Print
What's wrong with this code?
blargmob
Member #8,356
February 2007
avatar

Howdy,

I made a small program to test angled sprite movement. It works and all, except for I can tell that on some angles when I shoot the laser or move the ship in the direction the ship points, it's off slightly. I'm using float variables as the speed for both the laser and the ship.
Here's is the code: (I am using allegro but I made a wrapper for it for C++, so it's easier to read. You should be able to decifer everything perfectly fine).

1#include "header.h"
2int main()
3{
4 TheApp.ColorDepth(24);
5 TheApp.GfxMode(GFX_SAFE,800,600);
6 TheApp.InstallMouse();
7 TheApp.InstallKeyboard();
8 TheApp.InstallTimer();
9 TheApp.InstallJoystick();
10 TheApp.InstallSound();
11
12 spaceship.LoadSprite("spaceship.bmp",59,48);
13 spaceship.x=385;
14 spaceship.y=285;
15 laser.LoadSprite("laser.bmp",10,10);
16 laser.x=415;
17 laser.y=305;
18
19 space.LoadSprite("space.bmp");
20
21 buffer.CreateSprite(800,600);
22
23 laserfire=false;
24 
25 while(! key[KEY_ESC])
26 {
27 if(key[KEY_RIGHT])
28 {
29 shipangle+=2;
30 }
31 if(key[KEY_LEFT])
32 {
33 shipangle-=2;
34 }
35 if(key[KEY_UP])
36 {
37 spaceship.xspeed = 8 * cos(((shipangle/.7111111)*M_PI/180));
38 spaceship.yspeed = 8 * sin(((shipangle/.7111111)*M_PI/180));
39 spaceship.x+=spaceship.xspeed;
40 spaceship.y+=spaceship.yspeed;
41 }
42 if(key[KEY_SPACE] && laserfire==false)
43 {
44 laser.xspeed = 8 * cos(((shipangle/.7111111)*M_PI/180));
45 laser.yspeed = 8 * sin(((shipangle/.7111111)*M_PI/180));
46 laser.x=spaceship.x;
47 laser.y=spaceship.y;
48 laserfire=true;
49 }
50 if(laser.x > TheApp.screenw || laser.y > TheApp.screenh ||
51 laser.x < 0 || laser.y < 0)
52 laserfire=false;
53
54 if(shipangle > 256)
55 shipangle=0;
56 if(shipangle < 0)
57 shipangle=256;
58
59 space.Render(buffer);
60 spaceship.Rotate(buffer,shipangle);
61 if(laserfire==true)
62 {
63 laser.x+=laser.xspeed;
64 laser.y+=laser.yspeed;
65 laser.Render(buffer);
66 }
67 textprintf(buffer.SPRITE,font,0,0,WHITE,"Ship Angle: %i",shipangle);
68 textprintf(buffer.SPRITE,font,0,10,WHITE,"Laser Xspeed: %f",laser.xspeed);
69 textprintf(buffer.SPRITE,font,0,20,WHITE,"Laser Yspeed: %f",laser.yspeed);
70 buffer.RenderToScreen();
71 rest(10);
72 }
73 
74 return 0;
75}
76 
77// Some Allegro magic to deal with WinMain().
78END_OF_MAIN();

---
"No amount of prayer would have produced the computers you use to spread your nonsense." Arthur Kalliokoski

CursedTyrant
Member #7,080
April 2006
avatar

spaceship.xspeed = 8 * cos(((shipangle/.7111111)*M_PI/180));
spaceship.yspeed = 8 * sin(((shipangle/.7111111)*M_PI/180));

spaceship.x+=spaceship.xspeed;
spaceship.y+=spaceship.yspeed;

What's shipangle/.7111111 doing there? AFAIK it should be like

spaceship.xspeed = 8*cos(shipangle*M_PI/180);
spaceship.yspeed = 8*sin(shipangle*M_PI/180);

, assuming that shipangle is in degrees, which, as far as I can see, is true. The same for the laser.

---------
Signature.
----
[My Website] | [My YouTube Channel]

blargmob
Member #8,356
February 2007
avatar

CursedTyrant said:

What's shipangle/.7111111 doing there?

It's there because shipangle is in allegro-degrees, not normal-degrees.

---
"No amount of prayer would have produced the computers you use to spread your nonsense." Arthur Kalliokoski

Kris Asick
Member #1,424
July 2001

In that case, you want:

spaceship.xspeed = 8 * cos(M_PI*2/256*shipangle);
spaceship.yspeed = 8 * sin(M_PI*2/256*shipangle);

With an additive value also applied based on which direction you want as 0.

--- Kris Asick (Gemini)
--- http://www.pixelships.com

--- Kris Asick (Gemini)
--- http://www.pixelships.com

CursedTyrant
Member #7,080
April 2006
avatar

Hm, I've never played with those. Still, this is the only line in your code where it could be wrong IMO. Maybe .7111111 is not 100% accurate (as it should be, anyway), which would explain your problem?

Then again, I never used allegro's rotating functions, so it's just a wild guess.

EDIT: Beaten, but it seems I was correct :)

---------
Signature.
----
[My Website] | [My YouTube Channel]

blargmob
Member #8,356
February 2007
avatar

Kris Asick said:

In that case, you want:

spaceship.xspeed = 8 * cos(M_PI*2/256*shipangle);
spaceship.yspeed = 8 * sin(M_PI*2/256*shipangle);With an additive value also applied based on which direction you want as 0.

I tried that, and it was still a bit off.

---
"No amount of prayer would have produced the computers you use to spread your nonsense." Arthur Kalliokoski

BAF
Member #2,981
December 2002
avatar

Where did you get the .711111 from?

blargmob
Member #8,356
February 2007
avatar

BAF said:

Where did you get the .711111 from?

Each normal-degree is .7111111111111111111 etc. of an allegro-degree. To convert, you divide the allegro-degrees by .7111111111 etc.:)

---
"No amount of prayer would have produced the computers you use to spread your nonsense." Arthur Kalliokoski

Kris Asick
Member #1,424
July 2001

Quote:

I tried that, and it was still a bit off.

What exactly are you setting M_PI to? If you're only setting it to 3.14, try adding as many significant digits as you can.

M_PI = 3.141592654

You may also try casting to avoid conversion order problems.

spaceship.xspeed = 8 * cos(M_PI*2/256*(float)shipangle);
spaceship.yspeed = 8 * sin(M_PI*2/256*(float)shipangle);

Lastly, xspeed and yspeed must be floating point values for any realm of accuracy, and so must the x and y coordinates of the object. If they're not, change those immediately.

--- Kris Asick (Gemini)
--- http://www.pixelships.com

--- Kris Asick (Gemini)
--- http://www.pixelships.com

BAF
Member #2,981
December 2002
avatar

What is the M_PI/180 for then? It seems like you are doing a ton of funky conversions.

blargmob
Member #8,356
February 2007
avatar

Kris Asick said:

What exactly are you setting M_PI to? If you're only setting it to 3.14, try adding as many significant digits as you can.

M_PI = 3.141592654

You may also try casting to avoid conversion order problems.

spaceship.xspeed = 8 * cos(M_PI*2/256*(float)shipangle);
spaceship.yspeed = 8 * sin(M_PI*2/256*(float)shipangle);

Lastly, xspeed and yspeed must be floating point values for any realm of accuracy, and so must the x and y coordinates of the object. If they're not, change those immediately.

M_PI is already set to.....something. I didn't set it. It set itself.
If I make the X and Y cords float value instead of int, I get an error when I pass the values to draw_sprite() and other render functions.???

---
"No amount of prayer would have produced the computers you use to spread your nonsense." Arthur Kalliokoski

BAF
Member #2,981
December 2002
avatar

What's the error? You probably have to cast to an int, which isn't really a big deal.

blargmob
Member #8,356
February 2007
avatar

BAF said:

You probably have to cast to an int

Cast to an int? What?

---
"No amount of prayer would have produced the computers you use to spread your nonsense." Arthur Kalliokoski

Kris Asick
Member #1,424
July 2001

Quote:

If I make the X and Y cords float value instead of int, I get an error when I pass the values to draw_sprite() and other render functions.

You need to cast floating point values to integers for those functions like so:

draw_sprite(buffer.SPRITE,spaceship.SPRITE,(int)spaceship.x,(int)spaceship.y);
.

That should do it.

Some compilers handle simple casts like that automatically, others don't.

--- Kris Asick (Gemini)
--- http://www.pixelships.com

--- Kris Asick (Gemini)
--- http://www.pixelships.com

BAF
Member #2,981
December 2002
avatar

Compilers won't handle casts. They will automatically promote values to more precision (coercion), but you have to explicitly cast if you are losing precision.

Kris Asick
Member #1,424
July 2001

Quote:

Compilers won't handle casts.

You sure about that? I happen to know for a fact that the error blargmob is getting wouldn't happen in MSVC 6.0, which is the compiler I use. I pass floating point values routinely to Allegro functions without casting them and they work perfectly fine. But I know from reading other posts that not all compilers do that.

--- Kris Asick (Gemini)
--- http://www.pixelships.com

--- Kris Asick (Gemini)
--- http://www.pixelships.com

blargmob
Member #8,356
February 2007
avatar

Ah Ha! I just had to make everything a float value and cast as int. Thanks guys, problem solved.;D;D;D;D;D;D
;D;D;D;D;D;D;D;D;D;D;D;D;D;D;D;D;D;D;D;D
;D;D;D;D;D;D;D

---
"No amount of prayer would have produced the computers you use to spread your nonsense." Arthur Kalliokoski

BAF
Member #2,981
December 2002
avatar

Quote:

You sure about that? I happen to know for a fact that the error blargmob is getting wouldn't happen in MSVC 6.0, which is the compiler I use. I pass floating point values routinely to Allegro functions without casting them and they work perfectly fine. But I know from reading other posts that not all compilers do that.

I should have said "AFAIK" and "any standards compliant compiler." I think I'm covered now.

Also, I vote for smiley free week again.

gnolam
Member #2,030
March 2002
avatar

Yes, it was a while ago now, wasn't it? I'll get right on it. ;)
(Smiley added for ironic effect)

--
Move to the Democratic People's Republic of Vivendi Universal (formerly known as Sweden) - officially democracy- and privacy-free since 2008-06-18!

Go to: