From: Nuno Jesus Newsgroups: comp.os.msdos.djgpp Subject: Re: Allegro: How do you move sprites around with the arrow keys? Date: Wed, 23 Oct 1996 10:07:25 +0200 Organization: CET/PT Lines: 245 Message-ID: <326DD23D.745F@cet.pt> References: <199610212154 DOT RAA06637 AT shore DOT intercom DOT net> NNTP-Posting-Host: briol.cet.pt Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit To: Jeremy Ford To: djgpp AT delorie DOT com DJ-Gateway: from newsgroup comp.os.msdos.djgpp Jeremy Ford wrote: > > Hello, > > I was wondering how you moved a sprite around using the arrow keys in > allegro? > > I wanted to draw the background and then move another sprite on top > of it using the arrow keys. I also don't want the background to get > erased while the sprite is being moved. > > Below I have included my code..,so everybody can see that I actually > tried and that I don't just want someone to do it for me :-) > > If anybody can give me some sample code or show me what I'm doing wrong > please help me :-) > thanks > Jeremy Ford > p.s. I know the code below probaly isn't very good but I'm just > learning..everybody has to start somewhere :-) > > /* this code will not compile without my header and data file > * if your interested in compiling this just -mail me and I will send > *you the files*/ > #include > #include > #include > #include > #include > #include > #include "rifle.h" > #include "allegro.h" > > char *datafile_name = "rifle.dat"; > DATAFILE *rifle_data; > BITMAP *sprite_buffer; > int *file_attr; > int next; > void animate(void); > void scope_move(); > > void main() > { > if((file_exists(datafile_name, 32, file_attr))==0) > { > printf("Datafile %s not found..Exiting program",datafile_name); > exit(0); > } > allegro_init(); > install_keyboard(); > install_mouse(); > clear_keybuf(); > set_gfx_mode(GFX_VGA,320,200,0,0); > rifle_data = load_datafile(datafile_name); > set_pallete(rifle_data[PALLETE_001].dat); > sprite_buffer = create_bitmap(320,200); > clear(sprite_buffer); > do > { > draw_sprite(sprite_buffer,rifle_data[INTRO].dat,0,0); > animate(); > } > while(next == 1); > readkey(); > fade_out(1); > set_pallete(rifle_data[PALLETE_001].dat); > clear_keybuf(); rectfill(screen,0,0,320,200,0); > do > { > draw_sprite(sprite_buffer,rifle_data[MAIN].dat,0,0); > animate(); > } > while(next == 1); > clear_keybuf(); > scope_move(); > unload_datafile(rifle_data); > allegro_exit(); > exit(0); > } > void animate() > { > vsync(); vsync(); > blit(sprite_buffer,screen,0,0,0,0,320,200); > clear(sprite_buffer); > next = 1; > if(keypressed) > next = 0; > } > > void scope_move() > { > int pos_x; > int pos_y; > int c; > pos_x = pos_y = 30; > c = getch(); > switch(c) > { > case KEY_UP: > pos_y++; > vsync(); > draw_rle_sprite(screen,rifle_data[SCOPE].dat,pos_x,pos_y); > break; > case KEY_DOWN: > pos_y--; > vsync(); > draw_rle_sprite(screen,rifle_data[SCOPE].dat,pos_x,pos_y); > break; > case KEY_LEFT: > pos_x--; > vsync(); > draw_rle_sprite(screen,rifle_data[SCOPE].dat,pos_x,pos_y); > break; > case KEY_RIGHT: > pos_x++; > vsync(); > draw_rle_sprite(screen,rifle_data[SCOPE].dat,pos_x,pos_y); > break; > case 'Q'|| 'q': > fade_out(1); > allegro_exit(); > exit(0); > break; > default: > scope_move(); > break; > } > } -- The problem is that you setup the pos_x and pos_y variables inside scope_move, but you define then everytime you get into it, making it always start up in (30,30). You need to define pos_x and pos_y outside scope_move (put them as global), and initialize them in that same global definition. Then, inside scope_move, you may do whatever you like, and you should check the limits (the bottom, the top, the left and the right). There's one other problem in your code, in the default section of the switch inside scope_move. Everytime you press a key other than the ones you defined, you call scope_move again. One first problem that could arise is the stack problem: If you press a not defined key for about some thousands of time, you will surely come up a stack fault. But the bigger problem is that while you are inside scope_move, you never update the screen, witch is not very good when you start to program a real game. Another minor 'bug' is the double vsync inside animate. You just don't need to put the vsync before the blit function, because it will be automatically called by her, so you're just wasting time. Ho, and I've just noticed that there's another 'bug'. You need to put the call to clear_keybuf and scope_move inside the second while of the main function, or you will never get the sprite's x and y updated!!! Ok, the full code could be: /* this code will not compile without my header and data file * if your interested in compiling this just -mail me and I will send *you the files*/ #include #include #include #include #include #include #include "rifle.h" #include "allegro.h" char *datafile_name = "rifle.dat"; DATAFILE *rifle_data; BITMAP *sprite_buffer; int *file_attr; int next; void animate(void); void scope_move(); int pos_x=30, pos_y=30; void main() { if((file_exists(datafile_name, 32, file_attr))==0) { printf("Datafile %s not found..Exiting program",datafile_name); exit(0); } allegro_init(); install_keyboard(); install_mouse(); clear_keybuf(); set_gfx_mode(GFX_VGA,320,200,0,0); rifle_data = load_datafile(datafile_name); set_pallete(rifle_data[PALLETE_001].dat); sprite_buffer = create_bitmap(320,200); clear(sprite_buffer); draw_sprite(sprite_buffer,rifle_data[INTRO].dat,0,0); blit(sprite_buffer,screen,0,0,0,0,320,200); readkey(); fade_out(1); set_pallete(rifle_data[PALLETE_001].dat); clear_keybuf(); rectfill(screen,0,0,320,200,0); while(1) { scope_move(); draw_sprite(sprite_buffer,rifle_data[MAIN].dat,0,0); blit(sprite_buffer,screen,0,0,0,0,320,200); vsync(); draw_rle_sprite(screen,rifle_data[SCOPE].dat,pos_x,pos_y); } } void scope_move() { if (keypressed) { switch(getch()) { case KEY_UP: if (pos_y) pos_y--; break; case KEY_DOWN: if (pos_y<200) pos_y++; break; case KEY_LEFT: if (pos_x) pos_x--; break; case KEY_RIGHT: if (pos_x<320) pos_x++; break; case 'Q'|| 'q': fade_out(1); clear_keybuf(); unload_datafile(rifle_data); allegro_exit(); exit(0); break; } } } And I think that's all, folk... ___________________________________________ Nuno Jesus - DCID/CET/PT - Portugal Tel. +351(034)381089, Fax +351(034)8913551 EMail : njesus AT cet DOT pt ___________________________________________