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 | |
4 | struct 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 | |
15 | void 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 | |
29 | void 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 | |
52 | int 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 | } |
102 | END_OF_MAIN(); |
Thanks in advance!
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()
In case you didn't notice, Sprite is a pointer to struct monster.
Sprite is declared as Sprites *Sprite. So, what is Sprites?
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.
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?
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 )
Thanks a lot!!
What was wrong with the screen acquire cammands?
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.
You should throw the book you're reading out the window. It's no good.
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.
So, is double buffering as good as manually acquiring the screen?
You should be double buffering anyway. And its like comparing apples to oranges, double buffering has nothing to do with acquiring the screen.
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.