Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Can't get my buffer to work

Credits go to CGamesPlay and LennyLen for helping out!
This thread is locked; no one can reply to it. rss feed Print
Can't get my buffer to work
gamelord12
Member #8,586
May 2007

http://rafb.net/p/vYtDlk13.html

I'm trying to make a sword fighting game. Most of it is commented out because I don't have the sprites for it and I want to know that the most basic parts work first. For some reason, my sprites either aren't being grabbed off the sprite sheet or they're just not showing up on screen. I get a white background after the title screen like I'm supposed to but then the stick figure fighting stance that's supposed to display doesn't show up.

CGamesPlay
Member #2,559
July 2002
avatar

(Reposted here because rafb expires)

1// Andrew Banks
2// started on 5/15/07
3// Sword Play
4#include <allegro.h>
5
6#define BLACK makecol(0, 0, 0)
7#define GREEN makecol(0, 255, 0)
8#define WHITE makecol(255, 255, 255)
9
10int frame1 = 0, frame2 = 0, frameCount = 0, frameDelay = 50, p1 = 40, p2 = SCREEN_W - 40, player, stamina1 = 100, stamina2 = 100, ticks = 0, staticy = 460;
11
12BITMAP *temp;
13BITMAP *grabframe(BITMAP *source, int width, int height, int startx, int starty, int columns, int frame)
14{
15 temp = create_bitmap(width, height);
16
17 int x = startx + (frame % columns) * width;
18 int y = starty + (frame / columns) * height;
19
20 blit(source, temp, x, y, 0, 0, width, height);
21
22 return temp;
23}
24BITMAP *buffer;
25BITMAP *SwordPlayTitle;
26// sprite arrays end in s (for sprite) to differentiate from functions
27BITMAP *fightStances[3];
28/*BITMAP *attackHeads[10];
29BITMAP *attackHands[10];
30BITMAP *attackFoots[10];
31BITMAP *defendHeads[1];
32BITMAP *defendHands[1];
33BITMAP *defendFoots[1];
34BITMAP *runForwards[3];
35BITMAP *runBackwards[3];
36BITMAP *pushs[4];
37BITMAP *powerStruggles[1];*/
38
39void ticksFunction(void); // counts time between frames
40/*void attackHead(int player); // 10 frames
41void attackHand(int player); // 10 frames
42void attackFoot(int player); // 10 frames
43void defendHead(int player); // 2 frames, last one is repeated
44void defendHand(int player); // 2 frames, last one is repeated
45void defendFoot(int player); // 2 frames, last one is repeated
46void runForward(int player); // 2 frames played forward then backward, then next two frames (same thing)
47void runBackward(int player); // 2 frames played forward then backward, then next two frames (same thing)
48void push(int player); // 5 frames: one player stumbles backward, other stays in fightStance
49void powerStruggle(void); // both players go through same two frames, then loser is pushed
50*/
51void stamina(void); // displays players' stamina bars
52void increaseStamina(void); // slightly regenerates stamina every second
53//void decreaseStamina(void); // decreases player's stamina when an attack is blocked
54
55int main(void)
56{
57 allegro_init();
58 install_timer();
59 install_keyboard();
60 set_color_depth(32);
61 set_gfx_mode(GFX_AUTODETECT_WINDOWED, 640, 480, 0, 0);
62 //buffer = create_bitmap(SCREEN_W, SCREEN_H);
63 SwordPlayTitle = load_bitmap("SwordPlayTitle.bmp", NULL);
64
65 while(!key[KEY_SPACE])
66 {
67 blit(SwordPlayTitle, screen, 0, 0, 0, 0, SwordPlayTitle->w, SwordPlayTitle->h);
68 textprintf_centre_ex(SwordPlayTitle, font, SCREEN_W / 2, 460, makecol(255, 255, 255), -1, "Press Space Bar to Continue...");
69 }
70 destroy_bitmap(SwordPlayTitle);
71
72 rest(50);
73
74 // loads frames for the fighting stance animation
75 temp = load_bitmap("FightStanceSpriteSheet.bmp", NULL);
76 for(int x = 0; x <= 3; x++)
77 {
78 fightStances[x] = grabframe(temp, 240, 240, 0, 0, 1, x);
79 }
80
81 /*// loads frames for the attack head animation
82 temp = load_bitmap("attackHeadSheet.bmp", NULL);
83 for(int x = 0; x <= 2; x++)
84 {
85 fightStances[x] = grabframe(240, 240, 0, 0, 1, x);
86 }
87
88 // loads frames for the attack hand animation
89 temp = load_bitmap("attackHandSheet.bmp", NULL);
90 for(int x = 0; x <= 2; x++)
91 {
92 fightStances[x] = grabframe(240, 240, 0, 0, 1, x);
93 }
94
95 // loads frames for the attack foot animation
96 temp = load_bitmap("attackFootSheet.bmp", NULL);
97 for(int x = 0; x <= 2; x++)
98 {
99 fightStances[x] = grabframe(240, 240, 0, 0, 1, x);
100 }
101
102 // loads frames for the defend head animation
103 temp = load_bitmap("defendHeadSheet.bmp", NULL);
104 for(int x = 0; x <= 2; x++)
105 {
106 fightStances[x] = grabframe(240, 240, 0, 0, 1, x);
107 }
108
109 // loads frames for the defend hand animation
110 temp = load_bitmap("defendHandSheet.bmp", NULL);
111 for(int x = 0; x <= 2; x++)
112 {
113 fightStances[x] = grabframe(240, 240, 0, 0, 1, x);
114 }
115
116 // loads frames for the defend foot animation
117 temp = load_bitmap("defendFootSheet.bmp", NULL);
118 for(int x = 0; x <= 2; x++)
119 {
120 fightStances[x] = grabframe(240, 240, 0, 0, 1, x);
121 }
122
123 // loads frames for the run forward animation
124 temp = load_bitmap("runForwardSheet.bmp", NULL);
125 for(int x = 0; x <= 2; x++)
126 {
127 fightStances[x] = grabframe(240, 240, 0, 0, 1, x);
128 }
129
130 // loads frames for the run backward animation
131 temp = load_bitmap("runBackwardSheet.bmp", NULL);
132 for(int x = 0; x <= 2; x++)
133 {
134 fightStances[x] = grabframe(240, 240, 0, 0, 1, x);
135 }
136
137 // loads frames for the push animation
138 temp = load_bitmap("pushSheet.bmp", NULL);
139 for(int x = 0; x <= 2; x++)
140 {
141 fightStances[x] = grabframe(240, 240, 0, 0, 1, x);
142 }
143
144 // loads frames for the power struggle animation
145 temp = load_bitmap("powerStruggleSheet.bmp", NULL);
146 for(int x = 0; x <= 2; x++)
147 {
148 fightStances[x] = grabframe(240, 240, 0, 0, 1, x);
149 }*/
150
151 buffer = create_bitmap(SCREEN_W, SCREEN_H);
152 install_int(increaseStamina, 1000);
153 install_int(ticksFunction, frameDelay);
154
155 while(!key[KEY_ESC])
156 {
157 clear_to_color(buffer, WHITE);
158 /*// attack commands for player 1
159 if(key[KEY_W] && key[KEY_SPACE])
160 attackHead(1);
161 else if(key[KEY_SPACE])
162 attackHand(1);
163 else if(key[KEY_S] && key[KEY_SPACE])
164 attackFoot(1);
165
166 // defend commands for player 1
167 else if(key[KEY_W] && key[KEY_LSHIFT])
168 defendHead(1);
169 else if(key[KEY_LSHIFT])
170 defendHand(1);
171 else if(key[KEY_S] && key[KEY_LSHIFT])
172 defendFoot(1);
173 else*/
174 //{
175 blit(fightStances[frame1], buffer, p1, staticy, p1, staticy, fightStances[frame1]->w, fightStances[frame1]->h);
176 frame1++;
177 if(frame1 > 3)
178 frame1 = 0;
179 //}
180 }
181 remove_int(increaseStamina);
182
183 return 0;
184}END_OF_MAIN()
185
186void ticksFunction()
187{
188 ticks++;
189
190 if(ticks == frameDelay)
191 ticks = 0;
192}
193
194/*void fightStance(int player)
195{
196 int frame1 = 0, frame2 = 0;
197
198 if(player == 1 && ticks == 0)
199 {
200 blit(fightStances[frame1], screen, p1, staticy, p1, staticy, fightStances[frame1]->w, fightStances[frame1]->h);
201 frame1++;
202 if(frame1 > 4)
203 frame1 = 0;
204 }
205}*/
206
207void stamina()
208{
209 textprintf_ex(buffer, font, 5, 5, BLACK, -1, "Player 1");
210 textprintf_right_ex(buffer, font, SCREEN_W - 5, 5, BLACK, -1, "Player 2");
211 rectfill(buffer, 5, 5, 5 + stamina1, 10, GREEN);
212 rectfill(buffer, SCREEN_W - 105, 5, SCREEN_W - 105 + stamina2, 10, GREEN);
213}
214
215void increaseStamina()
216{
217 stamina1++;
218 if(stamina1 > 100)
219 stamina1 = 100;
220 stamina2++;
221 if(stamina2 > 100)
222 stamina2 = 100;
223}

This line is wrong:blit(fightStances[frame1], buffer, p1, staticy, p1, staticy, fightStances[frame1]->w, fightStances[frame1]->h);
It should be:blit(fightStances[frame1], buffer, 0, 0, p1, staticy, fightStances[frame1]->w, fightStances[frame1]->h);

Also, instead of doing this to display your title screen, which uses 100% CPU:

  while(!key[KEY_SPACE])
  {
    blit(SwordPlayTitle, screen, 0, 0, 0, 0, SwordPlayTitle->w, SwordPlayTitle->h);
    textprintf_centre_ex(SwordPlayTitle, font, SCREEN_W / 2, 460, makecol(255, 255, 255), -1, "Press Space Bar to Continue...");
  }
  destroy_bitmap(SwordPlayTitle);
 
  rest(50);

Do this instead:

blit(SwordPlayTitle, screen, 0, 0, 0, 0, SwordPlayTitle->w, SwordPlayTitle->h);
textprintf_centre_ex(SwordPlayTitle, font, SCREEN_W / 2, 460, makecol(255, 255, 255), -1, "Press A Key to Continue...");
destroy_bitmap(SwordPlayTitle);
readkey();

--
Tomasu: Every time you read this: hugging!

Ryan Patterson - <http://cgamesplay.com/>

gamelord12
Member #8,586
May 2007

Could you explain why there should be zeroes there?

Why is it that my original way uses 100% CPU, and what other tricks could you tell me to stop me from running into similar problems or poor practice down the road?

How do you post your code on this forum like that? Thanks.

CGamesPlay
Member #2,559
July 2002
avatar

Quote:

Could you explain why there should be zeroes there?

Those are the "source x" and "source y" points of the bitmap. If you have your sprite image and you set them to 32, 32, the first 32 pixels on the top and left will be skipped, because you said to start copying from the pixel at 32, 32.

Quote:

Why is it that my original way uses 100% CPU

Well, if you read it, he code sees if escape is pressed, draws the image to the screen, draws the text to the screen, sees if escape is pressed, draws the image to the screen... It's always doing something. My way draws the image to the screen, draws the text to the screen, then waits for a key to be pressed.

Quote:

what other tricks could you tell me to stop me from running into similar problems or poor practice down the road?

Just ask questions on the forums about what you aren't sure about.

Quote:

How do you post your code on this forum like that? Thanks.

This link is the "Help" button above the post reply box.

--
Tomasu: Every time you read this: hugging!

Ryan Patterson - <http://cgamesplay.com/>

gamelord12
Member #8,586
May 2007

1// Andrew Banks
2// started on 5/15/07
3// Sword Play
4#include <allegro.h>
5 
6#define BLACK makecol(0, 0, 0)
7#define GREEN makecol(0, 255, 0)
8#define WHITE makecol(255, 255, 255)
9 
10int frame1 = 0, frame2 = 0, frameCount = 0, frameDelay = 5, p1 = 40, p2 = SCREEN_W - 40, player, stamina1 = 100, stamina2 = 100, ticks = 0, staticy = 200;
11 
12BITMAP *temp;
13BITMAP *grabframe(BITMAP *source, int width, int height, int startx, int starty, int columns, int frame)
14{
15 temp = create_bitmap(width, height);
16 
17 int x = startx + (frame % columns) * width;
18 int y = starty + (frame / columns) * height;
19 
20 blit(source, temp, x, y, 0, 0, width, height);
21 
22 return temp;
23}
24BITMAP *buffer;
25BITMAP *SwordPlayTitle;
26// sprite arrays end in s (for sprite) to differentiate from functions
27BITMAP *fightStances[3];
28/*BITMAP *attackHeads[10];
29BITMAP *attackHands[10];
30BITMAP *attackFoots[10];
31BITMAP *defendHeads[1];
32BITMAP *defendHands[1];
33BITMAP *defendFoots[1];
34BITMAP *runForwards[3];
35BITMAP *runBackwards[3];
36BITMAP *pushs[4];
37BITMAP *powerStruggles[1];*/
38 
39void ticksFunction(void); // counts time between frames
40/*void attackHead(int player); // 10 frames
41void attackHand(int player); // 10 frames
42void attackFoot(int player); // 10 frames
43void defendHead(int player); // 2 frames, last one is repeated
44void defendHand(int player); // 2 frames, last one is repeated
45void defendFoot(int player); // 2 frames, last one is repeated
46void runForward(int player); // 2 frames played forward then backward, then next two frames (same thing)
47void runBackward(int player); // 2 frames played forward then backward, then next two frames (same thing)
48void push(int player); // 5 frames: one player stumbles backward, other stays in fightStance
49void powerStruggle(void); // both players go through same two frames, then loser is pushed
50*/
51void stamina(void); // displays players' stamina bars
52void increaseStamina(void); // slightly regenerates stamina every second
53//void decreaseStamina(void); // decreases player's stamina when an attack is blocked
54 
55int main(void)
56{
57 allegro_init();
58 install_timer();
59 install_keyboard();
60 set_color_depth(32);
61 set_gfx_mode(GFX_AUTODETECT_WINDOWED, 640, 480, 0, 0);
62 //buffer = create_bitmap(SCREEN_W, SCREEN_H);
63 SwordPlayTitle = load_bitmap("SwordPlayTitle.bmp", NULL);
64 
65 blit(SwordPlayTitle, screen, 0, 0, 0, 0, SwordPlayTitle->w, SwordPlayTitle->h);
66 textprintf_centre_ex(screen, font, SCREEN_W / 2, 460, makecol(255, 255, 255), -1, "Press Any Key to Continue...");
67 destroy_bitmap(SwordPlayTitle);
68 readkey();
69 
70 rest(50);
71 
72 // loads frames for the fighting stance animation
73 temp = load_bitmap("FightStanceSpriteSheet.bmp", NULL);
74 for(int x = 0; x <= 3; x++)
75 {
76 fightStances[x] = grabframe(temp, 240, 240, 0, 0, 1, x);
77 }
78 
79 /*// loads frames for the attack head animation
80 temp = load_bitmap("attackHeadSheet.bmp", NULL);
81 for(int x = 0; x <= 2; x++)
82 {
83 fightStances[x] = grabframe(240, 240, 0, 0, 1, x);
84 }
85
86 // loads frames for the attack hand animation
87 temp = load_bitmap("attackHandSheet.bmp", NULL);
88 for(int x = 0; x <= 2; x++)
89 {
90 fightStances[x] = grabframe(240, 240, 0, 0, 1, x);
91 }
92
93 // loads frames for the attack foot animation
94 temp = load_bitmap("attackFootSheet.bmp", NULL);
95 for(int x = 0; x <= 2; x++)
96 {
97 fightStances[x] = grabframe(240, 240, 0, 0, 1, x);
98 }
99
100 // loads frames for the defend head animation
101 temp = load_bitmap("defendHeadSheet.bmp", NULL);
102 for(int x = 0; x <= 2; x++)
103 {
104 fightStances[x] = grabframe(240, 240, 0, 0, 1, x);
105 }
106
107 // loads frames for the defend hand animation
108 temp = load_bitmap("defendHandSheet.bmp", NULL);
109 for(int x = 0; x <= 2; x++)
110 {
111 fightStances[x] = grabframe(240, 240, 0, 0, 1, x);
112 }
113
114 // loads frames for the defend foot animation
115 temp = load_bitmap("defendFootSheet.bmp", NULL);
116 for(int x = 0; x <= 2; x++)
117 {
118 fightStances[x] = grabframe(240, 240, 0, 0, 1, x);
119 }
120
121 // loads frames for the run forward animation
122 temp = load_bitmap("runForwardSheet.bmp", NULL);
123 for(int x = 0; x <= 2; x++)
124 {
125 fightStances[x] = grabframe(240, 240, 0, 0, 1, x);
126 }
127
128 // loads frames for the run backward animation
129 temp = load_bitmap("runBackwardSheet.bmp", NULL);
130 for(int x = 0; x <= 2; x++)
131 {
132 fightStances[x] = grabframe(240, 240, 0, 0, 1, x);
133 }
134
135 // loads frames for the push animation
136 temp = load_bitmap("pushSheet.bmp", NULL);
137 for(int x = 0; x <= 2; x++)
138 {
139 fightStances[x] = grabframe(240, 240, 0, 0, 1, x);
140 }
141
142 // loads frames for the power struggle animation
143 temp = load_bitmap("powerStruggleSheet.bmp", NULL);
144 for(int x = 0; x <= 2; x++)
145 {
146 fightStances[x] = grabframe(240, 240, 0, 0, 1, x);
147 }*/
148 
149 buffer = create_bitmap(SCREEN_W, SCREEN_H);
150 install_int(increaseStamina, 1000);
151 install_int(ticksFunction, frameDelay);
152 
153 while(!key[KEY_ESC])
154 {
155 clear_to_color(buffer, WHITE);
156 /*// attack commands for player 1
157 if(key[KEY_W] && key[KEY_SPACE])
158 attackHead(1);
159 else if(key[KEY_SPACE])
160 attackHand(1);
161 else if(key[KEY_S] && key[KEY_SPACE])
162 attackFoot(1);
163
164 // defend commands for player 1
165 else if(key[KEY_W] && key[KEY_LSHIFT])
166 defendHead(1);
167 else if(key[KEY_LSHIFT])
168 defendHand(1);
169 else if(key[KEY_S] && key[KEY_LSHIFT])
170 defendFoot(1);
171 else*/
172 //{
173 blit(fightStances[frame1], buffer, 0, 0, p1, staticy, fightStances[frame1]->w, fightStances[frame1]->h);
174 frame1++;
175 if(frame1 > 3)
176 frame1 = 0;
177 //}
178 blit(buffer, screen, 0, 0, 0, 0, buffer->w, buffer->h);
179 clear_bitmap(buffer);
180 }
181 remove_int(increaseStamina);
182 
183 return 0;
184}END_OF_MAIN()
185 
186void ticksFunction()
187{
188 ticks++;
189 
190 if(ticks == frameDelay)
191 ticks = 0;
192}
193 
194/*void fightStance(int player)
195{
196 int frame1 = 0, frame2 = 0;
197
198 if(player == 1 && ticks == 0)
199 {
200 blit(fightStances[frame1], screen, p1, staticy, p1, staticy, fightStances[frame1]->w, fightStances[frame1]->h);
201 frame1++;
202 if(frame1 > 4)
203 frame1 = 0;
204 }
205}*/
206 
207void stamina()
208{
209 textprintf_ex(buffer, font, 5, 5, BLACK, -1, "Player 1");
210 textprintf_right_ex(buffer, font, SCREEN_W - 5, 5, BLACK, -1, "Player 2");
211 rectfill(buffer, 5, 5, 5 + stamina1, 10, GREEN);
212 rectfill(buffer, SCREEN_W - 105, 5, SCREEN_W - 105 + stamina2, 10, GREEN);
213}
214 
215void increaseStamina()
216{
217 stamina1++;
218 if(stamina1 > 100)
219 stamina1 = 100;
220 stamina2++;
221 if(stamina2 > 100)
222 stamina2 = 100;
223}

Thanks for the help so far, but I'm still having issues.

My current problems are:

1. Stamina bars do not display at all
2. Only one frame of the stick figure displays, and it constantly has a black box written over top of it because it isn't reading in the other three frames of the animation.
3. Is there a way to specify what color is read as transparent? In class, we did a sample program with a cat going across the screen and pink was the transparent color...I'm not sure if that's the default or the only transparent color.

On another note, could someone take a look at my timer when used for my framerate? I'm trying to get it so that I can easily adjust and increase the flow of the animation. Is there an easier/more efficient way or any tweaks that could be done to the code?

Here's my sprite sheet. Keep in mind that in actuality, the sheet will be 240x960.
{"name":"FightStanceSpriteSheet.jpg","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/d\/8\/d834c597adf78e61db10b90a8d64b0e5.jpg","w":800,"h":200,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/d\/8\/d834c597adf78e61db10b90a8d64b0e5"}FightStanceSpriteSheet.jpg

CGamesPlay
Member #2,559
July 2002
avatar

Quote:

1. Stamina bars do not display at all

Why would they? You never call the function that draws them.

Quote:

2. Only one frame of the stick figure displays, and it constantly has a black box written over top of it because it isn't reading in the other three frames of the animation.

Sure. You call grabframe and pass 1 as the number of columns, but that image has 4.

Quote:

3. Is there a way to specify what color is read as transparent? In class, we did a sample program with a cat going across the screen and pink was the transparent color...I'm not sure if that's the default or the only transparent color.

Nope, sorry.

Also, this part is wrong:

  for(int x = 0; x <= 3; x++)
  {
    fightStances[x] = grabframe(temp, 240, 240, 0, 0, 1, x);
  }

fightStances is BITMAP* fightStances[3]. That means that you have 3 indexes to work with: 0, 1, and 2. But your loop writes to 0, 1, 2, and 3. That's one too many. Change the "x <= 3" to "x < 3", so you will only write to 0, 1, and 2.

--
Tomasu: Every time you read this: hugging!

Ryan Patterson - <http://cgamesplay.com/>

gamelord12
Member #8,586
May 2007

Those were such obvious answers. Thank you, I can't believe I missed them. However, as far as the columns are concerned, I copied the code for the grabframe() function right out of a tutorial program, and they actually read columns from the other direction. I'm pretty sure I copied that right when I applied it to this program, though it may have been after I pasted it up on this board. I'll post a newer version when my next inevitable problem turns up. As for my timers, are they okay? Or is there a better way to do it?

LennyLen
Member #5,313
December 2004
avatar

Quote:

However, as far as the columns are concerned, I copied the code for the grabframe() function right out of a tutorial program, and they actually read columns from the other direction.

The number of columns is the same, no matter what direction you look at them from.

CGamesPlay
Member #2,559
July 2002
avatar

Unless you took them from top to bottom, in which case they are called "rows". But the code shows that they run form left to right.

--
Tomasu: Every time you read this: hugging!

Ryan Patterson - <http://cgamesplay.com/>

gamelord12
Member #8,586
May 2007

Okay, so my updated code:

1// Sword Play
2#include <allegro.h>
3 
4#define BLACK makecol(0, 0, 0)
5#define GREEN makecol(0, 255, 0)
6#define WHITE makecol(255, 255, 255)
7 
8int frame1 = 0, frame2 = 0, frameCount = 0, frameDelay = 500, p1 = 40, p2 = SCREEN_W - 40, player, stamina1 = 100, stamina2 = 100, ticks = 0, staticy = 200;
9 
10BITMAP *grabframe(BITMAP *source, int width, int height, int startx, int starty, int columns, int frame)
11{
12 BITMAP *temp = create_bitmap(width, height);
13 
14 int x = startx + (frame % columns) * width;
15 int y = starty + (frame / columns) * height;
16 
17 blit(source, temp, x, y, 0, 0, width, height);
18 
19 return temp;
20}
21BITMAP *buffer;
22BITMAP *pic;
23BITMAP *SwordPlayTitle;
24// sprite arrays end in s (for sprite) to differentiate from functions
25BITMAP *fightStances[4];
26/*BITMAP *attackHeads[10];
27BITMAP *attackHands[10];
28BITMAP *attackFoots[10];
29BITMAP *defendHeads[1];
30BITMAP *defendHands[1];
31BITMAP *defendFoots[1];
32BITMAP *runForwards[3];
33BITMAP *runBackwards[3];
34BITMAP *pushs[4];
35BITMAP *powerStruggles[1];*/
36 
37void ticksFunction(void); // counts time between frames
38/*void attackHead(int player); // 10 frames
39void attackHand(int player); // 10 frames
40void attackFoot(int player); // 10 frames
41void defendHead(int player); // 2 frames, last one is repeated
42void defendHand(int player); // 2 frames, last one is repeated
43void defendFoot(int player); // 2 frames, last one is repeated
44void runForward(int player); // 2 frames played forward then backward, then next two frames (same thing)
45void runBackward(int player); // 2 frames played forward then backward, then next two frames (same thing)
46void push(int player); // 5 frames: one player stumbles backward, other stays in fightStance
47void powerStruggle(void); // both players go through same two frames, then loser is pushed
48*/
49void stamina(void); // displays players' stamina bars
50void increaseStamina(void); // slightly regenerates stamina every second
51//void decreaseStamina(void); // decreases player's stamina when an attack is blocked
52 
53int main(void)
54{
55 allegro_init();
56 install_timer();
57 install_keyboard();
58 set_color_depth(32);
59 set_gfx_mode(GFX_AUTODETECT_WINDOWED, 640, 480, 0, 0);
60 SwordPlayTitle = load_bitmap("SwordPlayTitle.bmp", NULL);
61 
62 blit(SwordPlayTitle, screen, 0, 0, 0, 0, SwordPlayTitle->w, SwordPlayTitle->h);
63 textprintf_centre_ex(screen, font, SCREEN_W / 2, 460, makecol(255, 255, 255), -1, "Press Any Key to Continue...");
64 destroy_bitmap(SwordPlayTitle);
65 readkey();
66 
67 rest(50);
68 
69 // loads frames for the fighting stance animation
70 pic = load_bitmap("FightStanceSpriteSheet.bmp", NULL);
71 for(int x = 0; x <= 3; x++)
72 {
73 fightStances[x] = grabframe(pic, 240, 240, 0, 0, 4, x);
74 }
75 
76 /*// loads frames for the attack head animation
77 temp = load_bitmap("attackHeadSheet.bmp", NULL);
78 for(int x = 0; x <= 2; x++)
79 {
80 fightStances[x] = grabframe(240, 240, 0, 0, 1, x);
81 }
82
83 // loads frames for the attack hand animation
84 temp = load_bitmap("attackHandSheet.bmp", NULL);
85 for(int x = 0; x <= 2; x++)
86 {
87 fightStances[x] = grabframe(240, 240, 0, 0, 1, x);
88 }
89
90 // loads frames for the attack foot animation
91 temp = load_bitmap("attackFootSheet.bmp", NULL);
92 for(int x = 0; x <= 2; x++)
93 {
94 fightStances[x] = grabframe(240, 240, 0, 0, 1, x);
95 }
96
97 // loads frames for the defend head animation
98 temp = load_bitmap("defendHeadSheet.bmp", NULL);
99 for(int x = 0; x <= 2; x++)
100 {
101 fightStances[x] = grabframe(240, 240, 0, 0, 1, x);
102 }
103
104 // loads frames for the defend hand animation
105 temp = load_bitmap("defendHandSheet.bmp", NULL);
106 for(int x = 0; x <= 2; x++)
107 {
108 fightStances[x] = grabframe(240, 240, 0, 0, 1, x);
109 }
110
111 // loads frames for the defend foot animation
112 temp = load_bitmap("defendFootSheet.bmp", NULL);
113 for(int x = 0; x <= 2; x++)
114 {
115 fightStances[x] = grabframe(240, 240, 0, 0, 1, x);
116 }
117
118 // loads frames for the run forward animation
119 temp = load_bitmap("runForwardSheet.bmp", NULL);
120 for(int x = 0; x <= 2; x++)
121 {
122 fightStances[x] = grabframe(240, 240, 0, 0, 1, x);
123 }
124
125 // loads frames for the run backward animation
126 temp = load_bitmap("runBackwardSheet.bmp", NULL);
127 for(int x = 0; x <= 2; x++)
128 {
129 fightStances[x] = grabframe(240, 240, 0, 0, 1, x);
130 }
131
132 // loads frames for the push animation
133 temp = load_bitmap("pushSheet.bmp", NULL);
134 for(int x = 0; x <= 2; x++)
135 {
136 fightStances[x] = grabframe(240, 240, 0, 0, 1, x);
137 }
138
139 // loads frames for the power struggle animation
140 temp = load_bitmap("powerStruggleSheet.bmp", NULL);
141 for(int x = 0; x <= 2; x++)
142 {
143 fightStances[x] = grabframe(240, 240, 0, 0, 1, x);
144 }*/
145
146 destroy_bitmap(pic);
147 buffer = create_bitmap(SCREEN_W, SCREEN_H);
148 install_int(increaseStamina, 1000);
149 install_int(ticksFunction, frameDelay);
150 
151 while(!key[KEY_ESC])
152 {
153 clear_to_color(buffer, WHITE);
154 /*// attack commands for player 1
155 if(key[KEY_W] && key[KEY_SPACE])
156 attackHead(1);
157 else if(key[KEY_SPACE])
158 attackHand(1);
159 else if(key[KEY_S] && key[KEY_SPACE])
160 attackFoot(1);
161
162 // defend commands for player 1
163 else if(key[KEY_W] && key[KEY_LSHIFT])
164 defendHead(1);
165 else if(key[KEY_LSHIFT])
166 defendHand(1);
167 else if(key[KEY_S] && key[KEY_LSHIFT])
168 defendFoot(1);
169 else*/
170 //{
171 blit(fightStances[frame1], buffer, 0, 0, p1, staticy, fightStances[frame1]->w, fightStances[frame1]->h);
172 if(ticks == 0)
173 frame1++;
174 if(frame1 > 3)
175 frame1 = 0;
176 //}
177 stamina();
178 blit(buffer, screen, 0, 0, 0, 0, buffer->w, buffer->h);
179 clear_bitmap(buffer);
180 }
181 remove_int(increaseStamina);
182 
183 return 0;
184}END_OF_MAIN()
185 
186void ticksFunction()
187{
188 ticks++;
189 
190 if(ticks == frameDelay)
191 ticks = 0;
192}
193 
194void stamina()
195{
196 textprintf_ex(buffer, font, 5, 15, BLACK, -1, "Player 1");
197 textprintf_right_ex(buffer, font, SCREEN_W - 5, 15, BLACK, -1, "Player 2");
198 rectfill(buffer, 5, 5, 5 + stamina1, 10, GREEN);
199 rectfill(buffer, SCREEN_W - 105, 5, SCREEN_W - 105 + stamina2, 10, GREEN);
200}
201 
202void increaseStamina()
203{
204 stamina1++;
205 if(stamina1 > 100)
206 stamina1 = 100;
207 stamina2++;
208 if(stamina2 > 100)
209 stamina2 = 100;
210}

My sprite animates, but depending on the speed, it will only run through for a few cycles. Like I said before, I feel like I'm going through that loop REALLY ineffieciently. How can I make it easy to adjust the animation speed?

CGamesPlay
Member #2,559
July 2002
avatar

Well, you should have your game loop looking something like this:

1int currentFrame = 0, frameCounter = 0;
2BITMAP* frames[3];
3 
4// Logic function. Called 30 times per second. Returns true to continue
5// playing the game, and false to quit it.
6bool logic()
7{
8 // This function is called 30 times each second, so this variable goes
9 // up 30 times each second
10 ++frameCounter;
11 // If it's been around 10 / 30 of a second, go to the next animation
12 // frame a reset it
13 if(frameCounter >= 10)
14 {
15 frameCounter = 0;
16 currentFrame++;
17 if(currentFrame >= 3)
18 currentFrame = 0;
19 }
20 
21 // If the user is not pressing escape then return true to continue playing
22 if(!key[KEY_ESC])
23 return true;
24 // Otherwise return false to quit
25 return false;
26}
27 
28// This function is called to draw the game to the screen
29void draw(BITMAP* to)
30{
31 BITMAP* sprite = frames[currentFrame];
32 blit(sprite, to, 0, 0, 200, 200, sprite->w, sprite->h);
33}
34 
35volatile int ticks = 0;
36void timer()
37{
38 ticks++;
39}
40 
41int main(int argc, char* argv[])
42{
43 allegro_init();
44 set_color_depth(16);
45 set_gfx_mode(GFX_AUTODETECT_WINDOWED, 640, 480, 0, 0);
46 install_keyboard();
47 install_timer();
48 
49 BITMAP* buffer = create_bitmap(SCREEN_W, SCREEN_H);
50 
51 // This will call the timer function 30 times per second
52 install_int_ex(timer, BPS_TO_TIMER(30));
53 
54 bool quit = false;
55 while(!quit)
56 {
57 while(ticks > 0)
58 {
59 --ticks;
60 // This will ensure the logic function is called 30 times per second
61 if(!logic())
62 { // If the logic function decided it was time to quit, then do so.
63 quit = true;
64 break;
65 }
66 }
67 draw(buffer);
68 blit(buffer, screen, 0, 0, 0, 0, buffer->w, buffer->h);
69 // This will cause the CPU to go idle if logic + drawing takes less than
70 // 1 / 30 of a second
71 if(ticks == 0)
72 rest(1);
73 }
74 
75 destroy_bitmap(buffer);
76 return 0;
77}

--
Tomasu: Every time you read this: hugging!

Ryan Patterson - <http://cgamesplay.com/>

LennyLen
Member #5,313
December 2004
avatar

Quote:

        currentFrame = 0;
        if(currentFrame >= 3)
            currentFrame = 0;

Why are you checking if currentFrame is greater than or equal to 3 when you've just set it to 0?

CGamesPlay
Member #2,559
July 2002
avatar

Whoops, fixed, thanks.

--
Tomasu: Every time you read this: hugging!

Ryan Patterson - <http://cgamesplay.com/>

gamelord12
Member #8,586
May 2007

CGames, I did like some of what I saw in your program, but there was a lot that seemed either unnecessary or I just didn't understand it. Here's my updated program (issues listed in first comment lines):

1// Sword Play
2 
3// Known issues:
4 
5// game still isn't anywhere near playable
6// stick dude no longer moves
7// pressing keys apparently bogs down the computer enough to slow the game down
8 
9#include <allegro.h>
10 
11#define BLACK makecol(0, 0, 0)
12#define GREEN makecol(0, 255, 0)
13#define WHITE makecol(255, 255, 255)
14 
15volatile int frame1 = 0, frame2 = 0, p1 = 40, p2 = SCREEN_W - 40, player, stamina1 = 100, stamina2 = 100, ticks = 0;
16const int frameRate = 15, staticy = 200;
17 
18BITMAP *grabframe(BITMAP *source, int width, int height, int startx, int starty, int columns, int frame)
19{
20 BITMAP *temp = create_bitmap(width, height);
21 
22 int x = startx + (frame % columns) * width;
23 int y = starty + (frame / columns) * height;
24 
25 blit(source, temp, x, y, 0, 0, width, height);
26 
27 return temp;
28}
29BITMAP *buffer;
30BITMAP *pic;
31BITMAP *SwordPlayTitle;
32// sprite arrays end in s (for sprite) to differentiate from functions
33BITMAP *fightStances[4];
34/*BITMAP *attackHeads[10];
35BITMAP *attackHands[10];
36BITMAP *attackFoots[10];
37BITMAP *defendHeads[1];
38BITMAP *defendHands[1];
39BITMAP *defendFoots[1];
40BITMAP *runForwards[3];
41BITMAP *runBackwards[3];
42BITMAP *pushs[4];
43BITMAP *powerStruggles[1];*/
44 
45void time(void); // used to count hundredths of a second
46void frame1Function(int maxframes); // controls animation of current action for player 1
47 
48/*void attackHead(int player); // 10 frames
49void attackHand(int player); // 10 frames
50void attackFoot(int player); // 10 frames
51void defendHead(int player); // 2 frames, last one is repeated
52void defendHand(int player); // 2 frames, last one is repeated
53void defendFoot(int player); // 2 frames, last one is repeated
54void runForward(int player); // 2 frames played forward then backward, then next two frames (same thing)
55void runBackward(int player); // 2 frames played forward then backward, then next two frames (same thing)
56void push(int player); // 5 frames: one player stumbles backward, other stays in fightStance
57void powerStruggle(void); // both players go through same two frames, then loser is pushed
58*/
59void stamina(void); // displays players' stamina bars
60void increaseStamina(void); // slightly regenerates stamina every second
61//void decreaseStamina(void); // decreases player's stamina when an attack is blocked
62 
63int main(void)
64{
65 allegro_init();
66 install_timer();
67 install_keyboard();
68 set_color_depth(32);
69 set_gfx_mode(GFX_AUTODETECT_WINDOWED, 640, 480, 0, 0);
70 SwordPlayTitle = load_bitmap("SwordPlayTitle.bmp", NULL);
71 
72 blit(SwordPlayTitle, screen, 0, 0, 0, 0, SwordPlayTitle->w, SwordPlayTitle->h);
73 textprintf_centre_ex(screen, font, SCREEN_W / 2, 460, makecol(255, 255, 255), -1, "Press Any Key to Continue...");
74 destroy_bitmap(SwordPlayTitle);
75 readkey();
76 
77 rest(50);
78 
79 // loads frames for the fighting stance animation
80 pic = load_bitmap("FightStanceSpriteSheet.bmp", NULL);
81 for(int x = 0; x <= 3; x++)
82 {
83 fightStances[x] = grabframe(pic, 240, 240, 0, 0, 4, x);
84 }
85 
86 /*// loads frames for the attack head animation
87 temp = load_bitmap("attackHeadSheet.bmp", NULL);
88 for(int x = 0; x <= 2; x++)
89 {
90 fightStances[x] = grabframe(240, 240, 0, 0, 1, x);
91 }
92
93 // loads frames for the attack hand animation
94 temp = load_bitmap("attackHandSheet.bmp", NULL);
95 for(int x = 0; x <= 2; x++)
96 {
97 fightStances[x] = grabframe(240, 240, 0, 0, 1, x);
98 }
99
100 // loads frames for the attack foot animation
101 temp = load_bitmap("attackFootSheet.bmp", NULL);
102 for(int x = 0; x <= 2; x++)
103 {
104 fightStances[x] = grabframe(240, 240, 0, 0, 1, x);
105 }
106
107 // loads frames for the defend head animation
108 temp = load_bitmap("defendHeadSheet.bmp", NULL);
109 for(int x = 0; x <= 2; x++)
110 {
111 fightStances[x] = grabframe(240, 240, 0, 0, 1, x);
112 }
113
114 // loads frames for the defend hand animation
115 temp = load_bitmap("defendHandSheet.bmp", NULL);
116 for(int x = 0; x <= 2; x++)
117 {
118 fightStances[x] = grabframe(240, 240, 0, 0, 1, x);
119 }
120
121 // loads frames for the defend foot animation
122 temp = load_bitmap("defendFootSheet.bmp", NULL);
123 for(int x = 0; x <= 2; x++)
124 {
125 fightStances[x] = grabframe(240, 240, 0, 0, 1, x);
126 }
127
128 // loads frames for the run forward animation
129 temp = load_bitmap("runForwardSheet.bmp", NULL);
130 for(int x = 0; x <= 2; x++)
131 {
132 fightStances[x] = grabframe(240, 240, 0, 0, 1, x);
133 }
134
135 // loads frames for the run backward animation
136 temp = load_bitmap("runBackwardSheet.bmp", NULL);
137 for(int x = 0; x <= 2; x++)
138 {
139 fightStances[x] = grabframe(240, 240, 0, 0, 1, x);
140 }
141
142 // loads frames for the push animation
143 temp = load_bitmap("pushSheet.bmp", NULL);
144 for(int x = 0; x <= 2; x++)
145 {
146 fightStances[x] = grabframe(240, 240, 0, 0, 1, x);
147 }
148
149 // loads frames for the power struggle animation
150 temp = load_bitmap("powerStruggleSheet.bmp", NULL);
151 for(int x = 0; x <= 2; x++)
152 {
153 fightStances[x] = grabframe(240, 240, 0, 0, 1, x);
154 }*/
155
156 destroy_bitmap(pic);
157 buffer = create_bitmap(SCREEN_W, SCREEN_H);
158 install_int_ex(time, BPS_TO_TIMER(100)); // calls the timer function 100 times every second
159 install_int_ex(increaseStamina, BPS_TO_TIMER(1)); // increases the stamina bars for both players by 1 every second
160 
161 while(!key[KEY_ESC])
162 {
163 clear_to_color(buffer, WHITE);
164 /*// attack commands for player 1
165 if(key[KEY_W] && key[KEY_SPACE])
166 attackHead(1);
167 else if(key[KEY_SPACE])
168 attackHand(1);
169 else if(key[KEY_S] && key[KEY_SPACE])
170 attackFoot(1);
171
172 // defend commands for player 1
173 else if(key[KEY_W] && key[KEY_LSHIFT])
174 defendHead(1);
175 else if(key[KEY_LSHIFT])
176 defendHand(1);
177 else if(key[KEY_S] && key[KEY_LSHIFT])
178 defendFoot(1);
179 else*/
180 //{
181 frame1Function(3);
182
183 blit(fightStances[frame1], buffer, 0, 0, p1, staticy, fightStances[frame1]->w, fightStances[frame1]->h);
184 //}
185 stamina();
186 blit(buffer, screen, 0, 0, 0, 0, buffer->w, buffer->h);
187 clear_bitmap(buffer);
188 }
189 remove_int(increaseStamina);
190 
191 return 0;
192}END_OF_MAIN()
193 
194void time()
195{
196 ticks++;
197
198 if(ticks >= 100)
199 ticks = 0;
200}
201 
202void frame1Function(int maxframes)
203{
204 if(ticks == (100 % frameRate))
205 {
206 if(frame1 >= maxframes)
207 frame1 = 0;
208 else
209 frame1++;
210 }
211}
212 
213void stamina()
214{
215 textprintf_ex(buffer, font, 5, 15, BLACK, -1, "Player 1");
216 textprintf_right_ex(buffer, font, SCREEN_W - 5, 15, BLACK, -1, "Player 2");
217 rectfill(buffer, 5, 5, 5 + stamina1, 10, GREEN);
218 rectfill(buffer, SCREEN_W - 105, 5, SCREEN_W - 105 + stamina2, 10, GREEN);
219}
220 
221void increaseStamina()
222{
223 stamina1++;
224 if(stamina1 > 100)
225 stamina1 = 100;
226 stamina2++;
227 if(stamina2 > 100)
228 stamina2 = 100;
229}

zavirax
Member #8,634
May 2007

forgive me if im wrong i only had a quick skim over it... i cant see that you have declared width and height but i think you must have becaus eyou would be having erors...hmmm...well check it and im probably wrong.::)

gamelord12
Member #8,586
May 2007

Yes, everything that needs to be declared is declared, however, my stick figure guy now moves very much like a robot. The frame that it displays appears to be random, and it only plays like 1 every second. What's wrong?

Onewing
Member #6,152
August 2005
avatar

Quote:

if(ticks == (100 % frameRate))

This seems...odd to me. Maybe I don't understand your logic, but what I get is ticks is being changed by a hardware interrupt, meaning it could go right past (100 % frameRate) before the if statement is called.

------------
Solo-Games.org | My Tech Blog: The Digital Helm

gamelord12
Member #8,586
May 2007

yeah, I changed it to this soon after posting:

1void time()
2{
3 ticks++;
4 
5 if(ticks >= 100)
6 ticks = 0;
7}
8 
9void frame1Function(int maxframes)
10{
11 float comparisonVariable = frameRate / 100;
12
13 if(ticks >= comparisonVariable)
14 {
15 ticks = 0;
16 
17 if(frame1 >= maxframes)
18 frame1 = 0;
19 else
20 frame1++;
21 }
22}

Then after I did that, I noticed I had to switch the 100 and frameRate, and it works. Thanks guys! Now the next possible problem that could come up would be during my animations that run when buttons are pressed. I'll let you know how that works out, but maybe in another topic.

Go to: