Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » How to Move Bitmap By Input Keys...

Credits go to Johan Halmén, monkeyCode, and zer0 for helping out!
This thread is locked; no one can reply to it. rss feed Print
How to Move Bitmap By Input Keys...
tibgamer
Member #6,859
February 2006
avatar

Hi again...

I have been trying to move bitmap say "worm.bmp" over the screen through input keys..though I could able to move it to some extent but it is not moving in the desired way...In a sense..here in my code...when we run...it moves horizontally..and when I press down key..it moves down as long as I press the key..but when I release the key..it again moves horizontally...I want it to keep moving in the direction i press the key..Or simply put..it should be moving like a WORM...help please...

1 
2BITMAP *buffer;
3DATAFILE *data; /* i have my bitmap in my dat file */
4 
5/* I am skipping allegro graphic initialisation and other initialisation because I am facing problem in the below function only */
6 
7void move_worm()
8{
9 int x = SCREEN_W / 2;
10 int y = SCREEN_H / 2;
11 
12 while(!key[KEY_ESC])
13 {
14 blit((BITMAP *)data[0].dat, buffer, 0, 0, x++, y, SCREEN_W, SCREEN_H);
15 vsync();
16 blit(buffer, screen, 0, 0, 0, 0, SCREEN_W, SCREEN_H);
17 
18 if(key[KEY_RIGHT])
19 {
20 x++;
21 }
22 if(key[KEY_LEFT])
23 {
24 x--;
25 x--;
26 }
27 if(key[KEY_UP])
28 {
29 y--;
30 x--;
31 }
32 if(key[KEY_DOWN])
33 {
34 y++;
35 x--;
36 }
37 clear_keybuf();
38 }
39}

software is not written, it is rewritten

Johan Halmén
Member #1,550
September 2001

 blit((BITMAP *)data[0].dat, buffer, 0, 0, x++, y, SCREEN_W, SCREEN_H);

That line is performed each time, so it moves horizontally therefore.

Do something:

1if(key[KEY_RIGHT])
2 {
3 dx = 1;
4 dy = 0;
5 
6 }
7 if(key[KEY_LEFT])
8 {
9 dx = -1;
10 dy = 0;
11 }
12 if(key[KEY_UP])
13 {
14 dx = 0;
15 dy = -1;
16 }
17 if(key[KEY_DOWN])
18 {
19 dx = 0;
20 dy = 1;
21 }
22 x += dx;
23 y += dy;
24 blit((BITMAP *)data[0].dat, buffer, 0, 0, x, y, SCREEN_W, SCREEN_H);

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Years of thorough research have revealed that the red "x" that closes a window, really isn't red, but white on red background.

Years of thorough research have revealed that what people find beautiful about the Mandelbrot set is not the set itself, but all the rest.

monkeyCode
Member #7,140
April 2006

1// very quick psuedo-code, the 'worm' will run off screen tho.
2struct Worm {
3 int x, y;
4 int direction;
5 BITMAP* bmp;
6};
7 
8void move_worm(Worm* worm) {
9
10 if (direction == DIR_NORTH) {
11 worm->y--;
12 } else if (direction == DIR_SOUTH) {
13 worm->y++;
14 } else if (direction == DIR_WEST) {
15 worm->x--;
16 } else if (direction == DIR_EAST) {
17 worm->x++;
18 }
19}
20 
21 
22void update_worm(Worm* worm) {
23 if (key[KEY_UP]) {
24 worm->direction = DIR_NORTH;
25 } else if( key[KEY_DOWN]) {
26 worm->direction = DIR_SOUTH;
27 } else if( key[KEY_LEFT]) {
28 work->direction = DIR_WEST;
29 } else if( key[KEY_DOWN]) {
30 worm->direction = DIR_EAST;
31 }
32}
33 
34void draw_worm(Worm* worm, BITMAP* bmp) {
35 // as you know which direction the worm is moving in, you can easly add bitmaps for each direction.
36 blit(worm->bmp, bmp, 0, 0, bmp->x, bmp->y, SCREEN_W, SCREEN_H);
37}

Edit: aww beaten to it! :'(

tibgamer
Member #6,859
February 2006
avatar

hi johan...i could able to understand your code..and could able to run it..thankx..

hi casper..i really like urs code with structure...though..i am still confuse in the structure part...when i tried to merge it into my program..it shows lots of error...

struct Worm {
    int x, y;
    int direction;
    BITMAP* bmp;
};

basically..i didn't understand the BITMAP *bmp in the struct...Do i need to load bitmap in this *bmp...and i suppose..i need to define variable for the struct..like this..

struct Worm worm

and other thing is in the draw_worm function....

void draw_worm(Worm* worm, BITMAP* bmp) {
     // as you know which direction the worm is moving in, you can easly add bitmaps for each direction.
     blit(worm->bmp, bmp, 0, 0, bmp->x, bmp->y, SCREEN_W, SCREEN_H);
}

i didn't get the two paremeters...which one is for which one...as per me..it seems like the Worm *worm points to the content of structure..and BITMAP *bmp..points to the bitmap where i had loaded the bitmap image...rite...so..in the blit function...the worm point to the bmp and shows it on to the bmp...so i didn't get it..could you please..explain it in bit detail..possibly with comments..!

anyway..i really appreciate the help..and thanks a lot..

software is not written, it is rewritten

zer0
Member #6,501
October 2005
avatar

Casper's code assumes that BITMAP *bmp; points to the worms graphics, instead of having to go through the datafile.

I suppose it would be entirely possible to use this code:

BITMAP *bmp = (BITMAP *)data[0].dat
blit( bmp, buffer, etc...);

instead of just blitting it from the data file.

Either way you do it, BITMAP *bmp and (BITMAP *)data[0].dat point to the same data in memory. Do you not know how pointers work?

monkeyCode
Member #7,140
April 2006

Quote:

i didn't get the two paremeters...which one is for which one...as per me..it seems like the Worm *worm points to the content of structure..and BITMAP *bmp..points to the bitmap where i had loaded the bitmap image...rite...so..in the blit function...the worm point to the bmp and shows it on to the bmp...so i didn't get it..could you please..explain it in bit detail..possibly with comments..!

anyway..i really appreciate the help..and thanks a lot..

now which bmp are you reffering to? hehe should have named them more clearly ;).

void draw_worm(Worm* worm, BITMAP* buffer) {
    blit(worm->bmp, bufer, 0, 0, worm->x, worm->y, bmp->w, bmp->h);
}

Anyhow, Worm::bmp would point to whatever you want it, but move_worm and update_worm was what i wanted you to look at ;)

tibgamer
Member #6,859
February 2006
avatar

Quote:

Do you not know how pointers work?

well..i think in generic sense..pointer points to the address of the value stored in memory..rite...and here in the program...it points to the value inside the structure...

yes..you are right..i can blit it either from dat file or from bitmap..but the problem here is that when i try to integrate the code inside my program..it doesn't run....???

hi casper...

i am now clear with draw_worm function...the first paremeter will point to my bitmap image..and second will point to the buffer..i got it..

now..i hav one more question...in your structure..

struct Worm {
    int x, y;
    int direction;
    BITMAP* bmp;
};

i guess..you didn't define the pointer variable..like:

struct Worm *worm

so that the *worm can access the value inside the struct Worm...am i right or is it other wise...!

anywa..i appreciate..it buddy....;)

software is not written, it is rewritten

monkeyCode
Member #7,140
April 2006

Ah forgot about that, mostly use C++ so you'll have to exuse my C ;)

tibgamer
Member #6,859
February 2006
avatar

hello monkey_code

here is my whole of the program...i integrate urs code in here..but its not working..could you please go through the code and point out the error..thanks a lot..

1#include <allegro.h>
2struct Worm {
3 int x, y;
4 int direction;
5 BITMAP* bmp;
6};
7 
8struct Worm *worm;
9BITMAP *buffer;
10 
11void load_worm();
12void move_worm(struct Worm* worm);
13void update_worm(struct Worm* worm);
14void draw_worm(struct Worm* worm, BITMAP* buffer);
15void unload_worm();
16 
17int DIR_NORTH = 0;
18int DIR_SOUTH = 1;
19int DIR_EAST = 2;
20int DIR_WEST = 3;
21 
22int main()
23{
24 allegro_init();
25 install_keyboard();
26
27 load_worm();
28
29 while(!key[KEY_ESC])
30 {
31 move_worm(worm);
32
33 update_worm(worm);
34
35 draw_worm(worm, buffer);
36 }
37
38 unload_worm();
39
40 return 0;
41}
42END_OF_MAIN()
43 
44void load_worm()
45{
46
47 set_color_depth(32);
48 set_gfx_mode(GFX_AUTODETECT_WINDOWED, 640, 480,0,0);
49 set_color_conversion(COLORCONV_TOTAL);
50
51 worm->bmp = create_bitmap(SCREEN_W, SCREEN_H);
52 if(!worm->bmp) {
53 allegro_message("Sorry, not enough memory");
54 exit(1);
55 }
56 clear(worm->bmp);
57
58 worm->bmp = load_bitmap("worm.bmp", NULL);
59 if(!worm->bmp) {
60 allegro_message("Sorry, not able to read bitmap!");
61 exit(2);
62 }
63
64}
65 
66void move_worm(struct Worm *worm) {
67
68 if (worm->direction == DIR_NORTH) {
69 worm->y--;
70 } else if (worm->direction == DIR_SOUTH) {
71 worm->y++;
72 } else if (worm->direction == DIR_WEST) {
73 worm->x--;
74 } else if (worm->direction == DIR_EAST) {
75 worm->x++;
76 }
77}
78 
79void update_worm(struct Worm* worm) {
80
81 if (key[KEY_UP]) {
82 worm->direction = DIR_NORTH;
83 } else if( key[KEY_DOWN]) {
84 worm->direction = DIR_SOUTH;
85 } else if( key[KEY_LEFT]) {
86 worm->direction = DIR_WEST;
87 } else if( key[KEY_DOWN]) {
88 worm->direction = DIR_EAST;
89 }
90}
91 
92void draw_worm(struct Worm* worm, struct BITMAP* buffer) {
93 // as you know which direction the worm is moving in, you can easly add bitmaps for each direction.
94 blit(worm->bmp, buffer, 0, 0, worm->x, worm->y, SCREEN_W, SCREEN_H);
95 blit(buffer, screen, 0, 0, 0, 0, SCREEN_W, SCREEN_H);
96}
97 
98void unload_worm()
99{
100
101 destroy_bitmap(buffer);
102
103}

;)

software is not written, it is rewritten

Inphernic
Member #1,111
March 2001

struct Worm *worm;

Hint: Where do you initialize the pointer?

umperio
Member #3,474
April 2003
avatar

worm->bmp = create_bitmap(SCREEN_W, SCREEN_H);
  if(!worm->bmp) {
  allegro_message("Sorry, not enough memory");
  exit(1);
  }
  clear(worm->bmp);

I guess you mean:

buffer = create_bitmap(SCREEN_W, SCREEN_H);
  if(!buffer) {
  allegro_message("Sorry, not enough memory");
  exit(1);
  }
  clear(buffer);

monkeyCode
Member #7,140
April 2006

You have a dangling pointer there, either allocate it or put it on the stack.

1/* Use a macro, enum or const int instead, the previous would work but it's just bad practice ;) */
2#define DIR_NORTH 1
3#define DIR_SOUTH 2
4#define DIR_EAST 3
5#define DIR_WEST 4
6 
7struct Worm {
8 int x, y;
9 int direction;
10 BITMAP* bmp;
11};
12 
13void construct_worm(Worm* worm) {
14 /* screen buffer creation doesn't really have any relationship to the worm, so why put it here? ;) */
15 worm->bmp = load_bitmap("worm.bmp", NULL);
16 worm->x = 0;
17 worm->y = 0;
18
19 worm->direction = DIR_EAST;
20
21 if(!worm->bmp) {
22 allegro_message("Error, file not found");
23 exit(1);
24 }
25}
26 
27int main(argc, char** argv) {
28 Worm worm;
29 BITMAP* buffer;
30
31 /* setup allegro and the buffers somewhere before construct */
32 construct_worm(&worm);
33
34 while(!key[KEY_ESC]) {
35 update_worm(&worm);
36 draw_worm(&worm, buffer); /* buffer isn't defined or constructed here */
37
38 /* swap buffers */
39 }
40
41 return 0;
42}

tibgamer
Member #6,859
February 2006
avatar

hi guys...

I have been banging my head against the computer screen for quite some time to make this code work..but I couldn't...!! Here..is the improved version of the worm program by integrating the code suggested by you...when I compile the program..it shows lots of error..I am using DevC++...could you guy care to compile this program for me..and solve the error...I really appreciate it...

1#include <allegro.h>
2 
3#define DIR_NORTH 1
4#define DIR_SOUTH 2
5#define DIR_EAST 3
6#define DIR_WEST 4
7 
8struct Worm {
9 int x, y;
10 int direction;
11 BITMAP* bmp;
12};
13 
14void construct_worm(struct Worm* worm);
15void move_worm(struct Worm* worm);
16void update_worm(struct Worm* worm);
17void draw_worm(struct Worm* worm, BITMAP* buffer);
18void unload_worm();
19 
20 
21int main()
22{
23 Worm *worm;
24 BITMAP *buffer;
25
26 allegro_init();
27 install_keyboard();
28
29 set_color_depth(32);
30 set_gfx_mode(GFX_AUTODETECT_WINDOWED, 640, 480,0,0);
31 set_color_conversion(COLORCONV_TOTAL);
32
33 construct_worm(Worm* worm);
34
35 while(!key[KEY_ESC]) {
36 move_worm(&worm);
37 update_worm(&worm);
38 draw_worm(&worm, buffer);
39 }
40
41 unload_worm();
42
43 return 0;
44}
45END_OF_MAIN()
46 
47void construct_worm(struct Worm* worm) {
48 /* screen buffer creation doesn't really have any relationship to the worm, so why put it here? ;) */
49 worm->bmp = load_bitmap("worm.bmp", NULL);
50 worm->x = 0;
51 worm->y = 0;
52
53 worm->direction = DIR_EAST;
54
55 if(!worm->bmp) {
56 allegro_message("Error, file not found");
57 exit(1);
58 }
59}
60 
61void move_worm(struct Worm *worm) {
62
63 if (worm->direction == DIR_NORTH) {
64 worm->y--;
65 } else if (worm->direction == DIR_SOUTH) {
66 worm->y++;
67 } else if (worm->direction == DIR_WEST) {
68 worm->x--;
69 } else if (worm->direction == DIR_EAST) {
70 worm->x++;
71 }
72}
73 
74void update_worm(struct Worm* worm) {
75
76 if (key[KEY_UP]) {
77 worm->direction = DIR_NORTH;
78 } else if( key[KEY_DOWN]) {
79 worm->direction = DIR_SOUTH;
80 } else if( key[KEY_LEFT]) {
81 worm->direction = DIR_WEST;
82 } else if( key[KEY_DOWN]) {
83 worm->direction = DIR_EAST;
84 }
85}
86 
87void draw_worm(struct Worm* worm, struct BITMAP* buffer) {
88 // as you know which direction the worm is moving in, you can easly add bitmaps for each direction.
89 blit(worm->bmp, buffer, 0, 0, worm->x, worm->y, SCREEN_W, SCREEN_H);
90 blit(buffer, screen, 0, 0, 0, 0, SCREEN_W, SCREEN_H);
91}
92 
93void unload_worm()
94{
95
96 destroy_bitmap(buffer);
97
98}

;)

software is not written, it is rewritten

umperio
Member #3,474
April 2003
avatar

I guess you're not learning, just asking us to code for you.

construct_worm(Worm* worm);

The compiler should tell you there something wrong with it. Do you know how to call a function? If not read a C book or look at the other functions you call.

move_worm(&worm);
update_worm(&worm);
draw_worm(&worm, buffer);

Your worm is a pointer to a Worm struct, so you should use it as a parameter, not a pointer to it.

monkeyCode
Member #7,140
April 2006

void draw_worm(struct Worm* worm, struct BITMAP* buffer) {
     blit(worm->bmp, buffer, 0, 0, worm->x, worm->y, SCREEN_W, SCREEN_H);

     /* What relationship does this have to the 'worm'? */
     blit(buffer, screen, 0, 0, 0, 0, SCREEN_W, SCREEN_H);
}

void unload_worm() {
    /* Again, what relationship does the framebuffer have with the worm object? 
     * Also, buffer is declared locally (Which is fine) but this function basicly wont know what to do, which probaly is one of the errors mingw is tossing at you.
     */
    destroy_bitmap(buffer); 
}

1int main() {
2 Worm worm;
3 BITMAP *buffer;
4
5 allegro_init();
6 install_keyboard();
7
8 set_color_depth(32);
9 set_gfx_mode(GFX_AUTODETECT_WINDOWED, 640, 480,0,0);
10 set_color_conversion(COLORCONV_TOTAL);
11
12 buffer = create_bitmap(SCREEN_W, SCREEN_H);
13 
14 /* construct_worm(Worm* worm); */
15 construct_worm(&worm);
16
17 while(!key[KEY_ESC]) {
18 update_worm(&worm);
19 move_worm(&worm);
20 draw_worm(&worm, buffer);
21
22 blit(buffer, screen, 0, 0, 0, 0, SCREEN_W, SCREEN_H);
23 }
24
25 destroy_bitmap(buffer);
26
27 return 0;
28}
29END_OF_MAIN()

tibgamer
Member #6,859
February 2006
avatar

Quote:

I guess you're not learning, just asking us to code for you

i am sorry if it sounds like that...however,,i have been coming here to learn from you guys..and if my intention is to just get hold of the code then..i can get it easily off the net...but then I won't able to learn anything from it...in contrast..i have been discussing the code here...so that you learned guys can teach me....right now i am bit rusty..and if it offends you guys..my bad..

regards

int main()
{
Worm worm;
BITMAP *buffer;
....

my compiler is throwing error message..saying "worm is undeclared"..shouldn't it be declared before the main() to make it global...with its pointer type...

struct Worm* worm;
BITMAP* buffer;

regards

software is not written, it is rewritten

monkeyCode
Member #7,140
April 2006

Quote:

i am sorry if it sounds like that...however,,i have been coming here to learn from you guys..and if my intention is to just get hold of the code then..i can get it easily off the net...but then I won't able to learn anything from it...in contrast..i have been discussing the code here...so that you learned guys can teach me....right now i am bit rusty..and if it offends you guys..my bad..

I don't mind that, altough it seems like you should pick up a book on C or C++ depending on which you are interested in.

Also, please try to punctuate properly ;D

Quote:

my compiler is throwing error message..saying "worm is undeclared"..shouldn't it be declared before the main() to make it global...with its pointer type...

Again, the code wasn't meant to compile.

...

But a quick check comfirms that it does compile, so what's the problem?

Edit:

// C is a bit more strict in how you declare structs, so either 
struct Worm worm;
// or
typedef struct Worm worm_t;
worm_t worm;

Go to: