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 | } |