Mail Archives: djgpp/1996/10/23/08:37:00
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 <stdlib.h>
> #include <conio.h>
> #include <stdio.h>
> #include <string.h>
> #include <dir.h>
> #include <pc.h>
> #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 <stdlib.h>
#include <conio.h>
#include <stdio.h>
#include <string.h>
#include <dir.h>
#include <pc.h>
#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
___________________________________________
- Raw text -