I'm able to rotate my sprite with:
if(key[KEY_Q]) _angle--; if(key[KEY_E]) _angle++; rotate_sprite(buffer, _sprite, _position.X, _position.Y, itofix(_angle));
I have a vector for the position of the sprite. Using the above to rotate, how can I get the direction vector so when I move forward it moves the direction that the sprite is rotated? I'd sure it's fairly easy and I just can't find anything.
Or, based on the angle, how can I get the direction vector?
You should have a velocity on the x and y axis for the sprite, and then do this:
Where speed is the speed by which the sprite should be moving. Then you update the x and y values by the vx,vy values:
_position.X += vx; _position.Y += vy;
And youre done!
Oh ok. I do have a velocity, and I also have a direction vector, but it seems since I have the angle variable I don't need the direction vector. Thanks.
Also, that would call cos() and sin() each cycle. I imagine I could call those and store the value in a variable only when I rotate right?
What variables do I need these declared as? I'm getting errors about fixed and such and when I make the angle 'fix' and the vectors float or anything else I get strange results.
I have my angle init to 0 and when I use that to move forward it moves right. ie I have it so when you press the W key it sets the speed value to > 0 to start the movement.
1. Yes you could calculate the new position only when the ship is rotated. That is a good idea.
2. Well sin() and cos() take floats. So you could make _angle a float and then use ftofix() when calling rotate_sprite().
3. Hmm... Dont know about this one. Try starting with 90 degrees.
OK, I must be missing something. Here is my player code, would be great if someone could take a look and let me know what I'm doing wrong.
The sprite does rotate, but the direction of moving doesn't work correctly.
1 | class Vector2D |
2 | { |
3 | private: |
4 | public: |
5 | float X, Y; |
6 | }; |
7 | |
8 | |
9 | class Player |
10 | { |
11 | private: |
12 | BITMAP *_sprite; |
13 | Vector2D _position; |
14 | Vector2D _velocity; |
15 | Vector2D _direction; |
16 | float _angle; |
17 | float _speed; |
18 | bool _moveForward; |
19 | public: |
20 | Player() |
21 | { |
22 | _moveForward = false; |
23 | _speed = 0; |
24 | _angle = 90; |
25 | _position.X = SCREEN_W/2; |
26 | _position.Y = SCREEN_H/2; |
27 | _direction.X = cos(_angle); |
28 | _direction.Y = sin(_angle); |
29 | _sprite = load_bitmap("C:\\player.bmp",0); |
30 | } |
31 | void draw(BITMAP *buffer) |
32 | { |
33 | rotate_sprite(buffer, _sprite, _position.X, _position.Y, ftofix(_angle)); |
34 | } |
35 | void move() |
36 | { |
37 | //_velocity.X = _direction.X * _speed; |
38 | //_velocity.Y = _direction.Y * _speed; |
39 | |
40 | _velocity.X = cos(_angle) * _speed; |
41 | _velocity.Y = sin(_angle) * _speed; |
42 | |
43 | _position.X += _velocity.X; |
44 | _position.Y += _velocity.Y; |
45 | } |
46 | void input() |
47 | { |
48 | if(key[KEY_Q]) |
49 | { |
50 | _angle--; |
51 | _direction.X = cos(_angle); |
52 | } |
53 | if(key[KEY_E]) |
54 | { |
55 | _angle++; |
56 | _direction.Y = sin(_angle); |
57 | } |
58 | |
59 | if(key[KEY_W] && !_moveForward) |
60 | { |
61 | _speed = .5; |
62 | _moveForward = true; |
63 | } |
64 | else if(!key[KEY_W] && _moveForward) |
65 | { |
66 | _speed = 0; |
67 | _moveForward = false; |
68 | } |
69 | } |
70 | }; |
For your move() function doesn't seem to be truly using your _velocity. I would suggest something similar to:
Could you also explain
the direction of moving doesn't work correctly
and say WHAT isn't working?
I must be missing something. That looks the same except you have ) after speed which shouldn't compile since there is no matching (.
and say WHAT isn't working?
I don't know what isn't working or what it's doing. I just know it's not moving it in the right direction. When my guy is facing up, and I try to move (I don't rotate yet) then he goes right.
[EDIT]
OK, something that seems odd. When the angle is 0, cos(angle) is returning a 1, and that gets multiplies by the speed which is .5 making the _velocity.X = to .5, which isn't right I'm thinking, because that makes my image go right, when the image I have visually is pointing up.
What direction is your BITMAP *_sprite stored? You may need to rotate the sprite's image by 90 degrees. The "unturned" direction should be facing right when you have _angle=0.0, it should be facing up when _angle=PI/2 (or in the case of Allegro rotations, 128/2, or 64.0).
And the ")" artifact was something that happened when copying/pasting; sorry. I'll edit my post and fix that typo.
EDIT: Sorry; I guess I had not correctly read your code post, so I had re-keyed what you already had.
So please disregard that first bit; I thought your math was wrong, but it turns out, you were correct all along. The relevant thing is that I think your sprite is simply turned 90 degrees. What direction does it go if you use your Q/E keys and accelerate? Does it go "straight" and even rotate correctly, but simply have the bitmap facing the wrong direction?
My bitmap is stored normally I guess. I created a top down bitmap where you are looking directly down on a person. So you see hit head, shoulders, adn a gun that is pointing "up" or forward.
When angle is 0 the image is facing up. In my code I init angle to 0, and it uses that in rotate_sprite. So if angle is 0 it seems rotate_sprite just draws it normally (up), but moving makes it go right. So how do I rotate my bitmap yet not the angle? Seems I need the bitmap to be facing right at first.
When I move and rotate, sometimes it seems to go the right away and sometimes it doesn't. Seems odd.
[EDIT]
Ok, I rotated the image in the paint editor so now it starts out looking right. So now if I move forward and don't rotate it works by moving right and looks visually right. BUT, if I press Q once then move again the character starts moving up/left, when visually he should move up/right.
Hmm maybe it's because the sprite is rotating around the top/left corner instead of the center of the sprite? I assume rotate_sprite() is doing the rotation around the center of the sprite, and my cos()/sin() is doing it around the top/left of teh sprite.
[EDIT] Nevermind, I read wrong
1 | Player::Player() |
2 | { |
3 | _moveForward = false; |
4 | _speed = 0.0; |
5 | _angle = 0.0; |
6 | _position.X = SCREEN_W/2; |
7 | _position.Y = SCREEN_H/2; |
8 | _direction.X = cos(_angle); |
9 | _direction.Y = sin(_angle); |
10 | _sprite = load_bitmap("player.bmp",0); |
11 | } |
12 | |
13 | void Player::draw(BITMAP *buffer) |
14 | { |
15 | rotate_sprite(buffer, _sprite, _position.X, _position.Y, ftofix(_angle * 128.0)); |
16 | } |
17 | |
18 | |
19 | void Player::move() |
20 | { |
21 | _velocity.X = cos(_angle * M_PI) * _speed; |
22 | _velocity.Y = sin(_angle * M_PI) * _speed; |
23 | |
24 | _position.X += _velocity.X; |
25 | _position.Y += _velocity.Y; |
26 | } |
27 | |
28 | void Player::input() |
29 | { |
30 | if(key[KEY_Q]) |
31 | { |
32 | _angle-=0.05; // If this is too large, it rotates much too quickly |
33 | _direction.X = cos(_angle); |
34 | } |
35 | if(key[KEY_E]) |
36 | { |
37 | _angle+=0.05; // Same as rotation for KEY_Q |
38 | _direction.Y = sin(_angle); |
39 | } |
40 | if(key[KEY_W] && !_moveForward) |
41 | { |
42 | _speed = .5; |
43 | _moveForward = true; |
44 | } |
45 | else if(!key[KEY_W] && _moveForward) |
46 | { |
47 | _speed = 0; |
48 | _moveForward = false; |
49 | } |
50 | } |