Allegro Animation <help me>

/* When this program runs for a certain period of time, it calls abort() and ends with a user abort prompt */

/* built using visual c++ */

#define USE_CONSOLE
#include <allegro.h>

int main() {

allegro_init();
install_keyboard();
set_gfx_mode( GFX_AUTODETECT, 1600, 900, 0, 0 );
acquire_screen();
release_screen();

int x = 30;
int y = 30;

while( !key[KEY_ESC] ) {

BITMAP *buffer = create_bitmap( 1600, 900 );

if ( key[KEY_UP] || key[KEY_DOWN] || key[KEY_LEFT] || key[KEY_RIGHT] ) {

if ( key[KEY_UP] ) {

if ( y<=20 ) {

}

else {

y--;

}

}

if ( key[KEY_DOWN] ) {

if ( y>=880 ) {

}

else {

y++;

}

}

if ( key[KEY_LEFT] ) {

if ( x <= 20 ) {

}

else {

x--;

}

}

if ( key[KEY_RIGHT] ) {

if ( x >=1580 ) {

}

else {

x++;

}

}

}

circlefill( buffer, x, y, 50, makecol( 220, 10, 10 ) );
draw_sprite( screen, buffer, 0, 0 );
clear_keybuf();

}

return 0;

}
END_OF_MAIN()
You are creating the buffer inside your main loop (the big one in main). You should create it only once, preferably right after set_gfx_mode(). Because you were creating it every loop without destroying it, you had a HUGE memory leak. When the system can't give you any more memory, it closes your program (i.e. the crash). I'm sure that if you opened *task manager and found your program (under the processes tab), the mem usage would be MASSIVE (due to the memory leak). Just move BITMAP* buffer = create_bitmap(SCREEN_W, SCREEN_H); to a spot outside of your while (!key[KEY_ESC]){...} loop.

*Windows specific...
Last edited on
Ok, I'll try that when I get home but wouldn't that not clear the screen if I did that? Cuz wouldn't that only buffer once, if I don't keep redrawing the bitmap over one another?

EDIT: Idk if there is an easier way or not, but I think this should fix my problem. destroy_bitmap(buffer);

That way, I can still clear my screen each time the circle moves
Last edited on
No, that will make it crash too. destroy_bitmap() does exactly what it says, it destroy the bitmap. i.e. deletes it. If you call that, buffer will point to an invalid memory location, so if you use it, the program will crash.

To clear the screen, just call clear_bitmap(); You could also draw a rectangle over the whole buffer, one that is the same color as your background.

1
2
3
4
5
6
while (!key[KEY_ESC]){
    objects.move();

    rectfill(buffer, 0, 0, SCREEN_W, SCREEN_H, makecol(r,g,b));
    objects.draw();
    draw_sprite(screen, buffer, 0, 0);}
/* None of those things seam to be working. Here's my code. */
/* EDIT: NO ERRORS. JUST NEED TO CLEAR THE SCREEN */

#define USE_CONSOLE
#include <allegro.h>

void moveCircle( int x, int y, int color, BITMAP *thebuffer ) {

acquire_screen();

rectfill( thebuffer, 0, 0, SCREEN_W, SCREEN_H, 0 );
draw_sprite( screen, thebuffer, 0, 0 );

if ( color == 0 ) {
circlefill( thebuffer, x, y, 50, makecol( 240, 0, 0 ) );
}
if ( color == 1 ) {
circlefill( thebuffer, x, y, 50, makecol( 240, 100, 100 ) );
}

draw_sprite(screen, thebuffer, 0, 0);

}

int main() {

int color = 0;
allegro_init();
install_keyboard();
install_mouse();
set_gfx_mode( GFX_AUTODETECT, 1600, 900, 0, 0 );
BITMAP *buffer = create_bitmap( 1600, 900 );

while( !key[KEY_ESC] ) {

int x = mouse_x;
int y = mouse_y;

if ( mouse_b & 1 ) {

moveCircle( x, y, 1, buffer );

}

else {

moveCircle( x, y, 0, buffer );

}

}

return 0;

}
END_OF_MAIN()
Last edited on
Try clear_bitmap(thebuffer);
I know. I already tried that. Its not working

EDIT: This works. Apparently giving the color a value of 0 doesn't work. I figured it out. Here's my code.

void makeCircle( int x, int y, BITMAP *buffer ) {

acquire_screen();
clear( buffer );
rectfill( buffer, 0, 0, 1600, 900, makecol( 0, 0, 0 ) );
circlefill( buffer, x, y, 50, makecol( 220, 50, 0 ) );
draw_sprite( screen, buffer, 0, 0 );
release_screen();

}
Last edited on
How come whenever I use colors in my program, they always come out what I do not expect. Like makecol( 0, 0, 0 ) is tented orange instead or black and just plain - 0 - doesn't show up and I'm pretty sure - 0 - should be black. I've tried using set_color_depth( 32 ) but this is not working and causes an abort() to be called and I think that's because I already have set_gfx_mode declared. Any help is appreciated! :)
You must set the color depth BEFORE you call "set_gfx_mode()"
/* I know. I've already done that correctly. The thing that's wrong now, is that if I use it, the program doesn't work. It doesn't animate the circle like it should.. Here's my code */

#define USE_CONSOLE
#include <allegro.h>

void makeCircle( int x, int y, BITMAP *buffer, int color ) {

acquire_screen();
clear( buffer );
rectfill( buffer, 0, 0, 1600, 900, makecol( 0, 0, 0 ) );
if ( color == 0 ) {

circlefill( buffer, x, y, 50, makecol( 200, 0, 0 ) );

}

if ( color == 1 ) {

circlefill( buffer, x, y, 50, makecol( 0, 250, 0 ) );

}

draw_sprite( screen, buffer, 0, makecol( 0, 0, 0 ) );
release_screen();

}

int main() {

allegro_init();
install_keyboard();
install_mouse();
set_color_depth( 32 );
set_gfx_mode( GFX_AUTODETECT, 1600, 900, 0, 0 );
int x = 0;
int y = 0;
int color = 0;

BITMAP *buffer = create_bitmap( 1600, 900 );

while( !key[KEY_ESC] ) {

x = mouse_x;
y = mouse_y;

if ( mouse_b ) {

color=1;

}

makeCircle( x, y, buffer, color );

color=0;

}

return 0;

}
END_OF_MAIN()
Last edited on
When you call "draw_sprite(screen, buffer, ...)", you pass x/y values after buffer. In this case, both would be zero, because you want to draw the buffer at (0,0). The way you have it now, you pass 0 for the x-value, but makecol(...) for the y-value. This will return some unknown number and it will draw the buffer at that number, which will probably cause the buffer, and thus the circle, to go below the bottom of the screen. Do this instead:

 
draw_sprite(screen, buffer, 0, 0);
whoops. I'll fix that when I get home.
still doesn't work. I woulda edited my post but idk if anyone would see this or not. I fixed that error but it still is messed up. Please help... Pretty much the same code. Here it is..

#define USE_CONSOLE
#include <allegro.h>

void makeCircle( int x, int y, BITMAP *buffer, int color ) {

acquire_screen();

if ( color == 0 ) {

circlefill( buffer, x, y, 50, makecol( 200, 0, 0 ) );

}

if ( color == 1 ) {

circlefill( buffer, x, y, 50, makecol( 0, 250, 0 ) );

}

draw_sprite( screen, buffer, 0, 0 );

release_screen();

}

int main() {

allegro_init();
install_keyboard();
install_mouse();
set_color_depth( 32 );
set_gfx_mode( GFX_AUTODETECT, 1600, 900, 0, 0 );
int x = 0;
int y = 0;
int color = 0;

BITMAP *buffer = create_bitmap( 1600, 900 );

while( !key[KEY_ESC] ) {

x = mouse_x;
y = mouse_y;

if ( mouse_b ) {

color=1;

}

makeCircle( x, y, buffer, color );

rectfill( buffer, 0, 0, 1600, 900, makecol( 0, 0, 0 ) );

color=0;

}

return 0;

}
END_OF_MAIN()
Last edited on
I'm assuming by "not working", you mean that the circle doesn't change color when clicked. Correct? I don't see anything else horribly wrong with your code.

The syntax for checking if the right mouse button is pressed is:
 
if (mouse_b & 1){...}
No i mean that the circle doesn't move according to my x and y coordinates of my mouse. The whole program is just a circle at my original x and y position of my mouse. However, if I do not put set_color_depth( int ), the program works just fine. Maybe its because the function set_color_depth(int) and set_gfx_mode are somehow connected... When I don't put set_color_depth( int ), my colors are not what they should be. makecol( 0, 0, 0 ) gives me a tented orange color for my background.
It works fine for me, color change and position both. Your code is fine, perhaps its your mouse... jk jk Try using (640,480) for your screens width and height. (in set_gfx_mode() and when you create the buffer in main).
K. I'll try soon. Really doesnt madder, but i just wonder why its screwing up cuz of that hehe
Topic archived. No new replies allowed.