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" |
2 | int 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(). |
78 | END_OF_MAIN(); |
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.
What's shipangle/.7111111 doing there?
It's there because shipangle is in allegro-degrees, not normal-degrees.
In that case, you want:
With an additive value also applied based on which direction you want as 0.
--- Kris Asick (Gemini)
--- http://www.pixelships.com
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
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.
Where did you get the .711111 from?
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.:)
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.
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
What is the M_PI/180 for then? It seems like you are doing a ton of funky conversions.
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.???
What's the error? You probably have to cast to an int, which isn't really a big deal.
You probably have to cast to an int
Cast to an int? What?
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
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.
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
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
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.
Yes, it was a while ago now, wasn't it? I'll get right on it.
(Smiley added for ironic effect)