Weird Sprite Handler
horizon981

I wanted to make a program to load sprites from a sprite strip and a simple sprite engine.
The proble is that I get a black screen only. The application doesn't crash, just that you get to see nothing.
If anything from the code is not clear to you, please don't hesitate to ask, it's really important.
The code:

1/*Advanced Sprite Animation with RLE Sprites*/
2#include <allegro.h>
3 
4struct Sprites
5{
6 int x, y;
7 int xSpeed, ySpeed;
8 int xDir, yDir;
9 bool isAlive;
10 int delay;
11 int curFrame, maxFrame;
12}monster;
13 
14 
15void setup_sprites(Sprites *Sprite)
16{
17 Sprite->x = rand()%100;
18 Sprite->y = rand()%100;
19 Sprite->xSpeed = 2; //--Move 2 pixels per keystroke
20 Sprite->ySpeed = 0; //--Vertical movement
21 Sprite->xDir = 1; //Default = +ve
22 Sprite->yDir = 0; //No movement in Y direction
23 Sprite->isAlive = true;
24 Sprite->delay = 20;
25 Sprite->curFrame = 0;
26 Sprite->maxFrame = 3;
27}
28
29void update_sprite(Sprites *Sprite)
30{
31 if(Sprite->xDir == 1)
32 Sprite->x += Sprite->xSpeed;
33 else if(Sprite->xDir == -1)
34 Sprite->x -= Sprite->xSpeed;
35 else
36 Sprite->x += 0;
37
38 if(Sprite->yDir == 1)
39 Sprite->y += Sprite->ySpeed;
40 else if(Sprite->yDir == -1)
41 Sprite->y -= Sprite->ySpeed;
42 else
43 Sprite->y += 0;
44
45 Sprite->curFrame++;
46
47 if(Sprite->curFrame>3)
48 Sprite->curFrame = 0;
49}
50 
51
52int main()
53{
54 allegro_init();
55 set_color_depth(desktop_color_depth());
56 set_gfx_mode(GFX_AUTODETECT_WINDOWED, 640, 480, 0, 0);
57
58 install_keyboard();
59
60 BITMAP *buffer = create_bitmap(640, 480);
61 BITMAP *image = load_bitmap("monster.bmp", NULL);
62
63 if(!buffer)
64 {
65 allegro_message("Double Buffering Failed, outta here...");
66 allegro_exit();
67 return -1;
68 }
69 if(!image)
70 {
71 allegro_message("Sprite loading failed... outta here");
72 allegro_exit();
73 return -1;
74 }
75
76 Sprites *Sprite = &monster;
77 //--Lock Screen
78 acquire_screen();
79
80 //--Set up initial behaviour of sprites
81 setup_sprites(Sprite);
82
83 while(!key[KEY_ESC])
84 {
85 int x = image->w/(Sprite->maxFrame+1)*Sprite->curFrame;
86 int y = 0;
87
88 update_sprite(Sprite);
89 rest(Sprite->delay);
90 blit(image, buffer, x, y, Sprite->x, Sprite->y,
91 (image->w/(Sprite->maxFrame+1)), image->h);
92
93 blit(buffer, screen, 0, 0, 0, 0, 640, 480);
94 }
95 release_screen();
96
97 destroy_bitmap(image);
98 destroy_bitmap(buffer);
99 allegro_exit();
100 return 0;
101}
102END_OF_MAIN();

Thanks in advance!

Kauhiz
Quote:

struct Sprites
{
int x, y;
int xSpeed, ySpeed;
int xDir, yDir;
bool isAlive;
int delay;
int curFrame, maxFrame;
}monster;

void setup_sprites(Sprites *Sprite)

That's wrong. Do

struct Sprites
{
 int x, y;
 int xSpeed, ySpeed;
 int xDir, yDir;
 bool isAlive;
 int delay;
 int curFrame, maxFrame;
}Sprites;

Edit: For clarification, right now you have a struct called monster, but use a struct called Sprites. Also, again, drop the ; at END_OF_MAIN() :P

horizon981

In case you didn't notice, Sprite is a pointer to struct monster.

Kauhiz

Sprite is declared as Sprites *Sprite. So, what is Sprites?

Kitty Cat

You're doing more than drawing to the screen between the acquire/release_screen pairs. You don't need to call them at all when you only draw to the screen once per loop.

horizon981

Sprites is a structure that holds all the data about a sprite. monster is an instance of this structure. Sprite is a pointer to monster. Does that help?

Kauhiz

Wait, I think you're right, what was I looking at... Well, Kitty Cat is right anyway, the acquire/release bitmap calls are placed horribly, either get rid of them all together or just put them around the blitting (right now they're both outside the main loop :o)

horizon981

Thanks a lot!!
What was wrong with the screen acquire cammands?

Jonny Cook

If I remember correctly, you can only do drawing operations between acquire/release_screen() calls. And they are only beneficial when you draw to the screen multiple times in a row, which you aren't doing.

miran

You should throw the book you're reading out the window. It's no good.

Kauhiz

The screen needs to be acquired before it's drawn to. After that, it needs to be released. Blit does this automatically, unless you do it manually. The reason you may want to do it manually, is that if you draw a lot of stuff to the screen, it's better to acquire the screen then draw everything and release the screen than acquire before and release after every blit. The way you had it would release the screen after the user presses ESC, which just terrible.

horizon981

So, is double buffering as good as manually acquiring the screen?

BAF

You should be double buffering anyway. And its like comparing apples to oranges, double buffering has nothing to do with acquiring the screen.

Kikaru

From my limited experience, double buffering eliminates flickering, really helps when using a custom mouse pointer. :)

Also, I've never used acquire_screen() - release_screen() functions, and all my games have run pretty well.

Thread #587014. Printed from Allegro.cc