Rotate a bitmap
Karamell Kungen

How to rotate a bitmap?
I just started with allegro and planning to build some kind of 2d racing where you see everything from above. My car is a bitmap and my track is a bitmap(haven't done it yet). When I press left and right i will not move the bitmap(with x++) I want to rotate the car bitmap! How to do that, a function?

Chris Katko
void rotate_sprite(BITMAP *bmp, BITMAP *sprite, int x, int y, fixed angle);

Does just that. It's just like a normal sprite drawing function, but the angle argument will rotate it in "allegro degrees" (which are 0.0 to 255.0). (IIRC) Where 0 is up, 64 is right, 128 is down, and 192 is left.

If you want to make it turn, all you need to do is increase/decrease a fixed (or "fix") variable.

1 
2int main()
3{
4fix angle;
5 
6do{
7if(key[KEY_LEFT]){angle--; if(angle < 0)angle=255;}
8if(key[KEY_RIGHT]){angle++; if(angle > 255)angle = 0;}
9if(key[KEY_ESC)break;
10 
11rotate_sprite(screen, mysprite, 320, 240, angle);
12}while(true);
13 
14return 0;
15}

A "fix" won't work if your using C (as opposed to C++). The difference is that fix does nessicary conversions between other variable types. I'd recommend reading the "Fixed point math routines" section of the Allegro Manual for more on that.

If I forgot anything, feel free to ask.

Steve Terry

it's

fixed angle;
if(key[KEY_LEFT]){angle = angle - itofix(1);}

rotate_sprite(screen, mysprite, 320, 240, angle);

alternately

int angle;
if(key[KEY_LEFT]){angle--;}

rotate_sprite(screen, mysprite, 320, 240, itofix(angle));

Karamell Kungen

thanks :)

hmm this is a problem i should solve by myself but I can't :/ When I press left/right the angle var changes but if I want the car to move forward I press KEY_UP and then it should move in the angle direction.

Chris Katko

Steve:

fix is a C++ version of fixed with the operators overloaded, so conversion is done automatically.

Karamell:

For that you want sine ( sin(); ) and cosine ( cos(); ).

Where it would be (IIRC):

1int myfunction()
2{
3fix velocity, angle;
4 
5do{
6if(key[KEY_UP)velocity++; //or += .5 or whatever you want.
7if(key[KEY_DOWN)velocity--;
8if(key[KEY_LEFT]){angle--; if(angle < 0)angle=255;}
9if(key[KEY_RIGHT]){angle++; if(angle > 255)angle = 0;}
10 
11//This converts the polar coordinents to cartesian.
12x += cos(angle) * velocity;
13y += sin(angle) * velocity;
14 
15//Draw/etc
16 
17}while(whatever);
18 
19return 0;
20}

brain21

I'm lost. Is today "build a game for a newbie" day? I think it should be today.

Chris Katko

I'm lost. Is what Steve and I wrote out suppost to be hard...? I took me about a minute tops to write my second post out.

akOOma

This code isn't right at all..
first 'angle' is in Allegro (or whatever) degrees and later you use cos and sin with 'angle', so it should be in radians, but it isn't
I think that you should convert 'angle' from Allegro Degrees to Radians, but that's not that hard

// angle to normal degrees (0 to 360)
angle *= 1.40625;
// angle to radians (0 to 2Pi)
angle *= Pi / 180;
// now you can use sin and cos

Chris Katko

Actually, I was (and still am) correct. ;D

Calling fsin and fcos on a fix, will give incorrect results, because fix (not fixed) automatically does type-conversions.

Allegro 4.1.12 Manual said:

You should not mix the fix class with the fixed typedef though, because the compiler will mistake the fixed values for regular integers and insert unnecessary conversions. For example, if x is an object of class fix, calling fixsqrt(x) will return the wrong result. You should use the overloaded sqrt(x) or x.sqrt() instead.

Thread #323382. Printed from Allegro.cc