1 | // Sword Play |
2 | |
3 | // Known issues: |
4 | |
5 | // flawlessly, player can move forward...and that's it |
6 | // moving backward has animation issues |
7 | // many more sprite sheets still needed |
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 | |
15 | volatile int frame1 = 0, frame2 = 0, p1 = 40, p2 = SCREEN_W - 40, player, stamina1 = 100, stamina2 = 100, ticks = 0; |
16 | const int frameRate = 8, staticy = 200; |
17 | |
18 | // obtains sprites from a sprite sheet |
19 | BITMAP *grabframe(BITMAP *source, int width, int height, int startx, int starty, int columns, int frame) |
20 | { |
21 | BITMAP *temp = create_bitmap(width, height); |
22 | |
23 | int x = startx + (frame % columns) * width; |
24 | int y = starty + (frame / columns) * height; |
25 | |
26 | blit(source, temp, x, y, 0, 0, width, height); |
27 | |
28 | return temp; |
29 | } |
30 | BITMAP *buffer; // used to smooth out the animation |
31 | BITMAP *buffer2; // used to smooth out animation even more |
32 | BITMAP *pic; // temporary variable for putting sprites into an array |
33 | BITMAP *SwordPlayTitle; // title screen picture |
34 | |
35 | // sprite arrays end in s (for sprite) to differentiate from functions |
36 | BITMAP *fightStances[4]; |
37 | BITMAP *runForwards[9]; |
38 | BITMAP *runBackwards[4]; |
39 | |
40 | /*BITMAP *attackHeads[10]; |
41 | BITMAP *attackHands[10]; |
42 | BITMAP *attackFoots[10]; |
43 | BITMAP *defendHeads[1]; |
44 | BITMAP *defendHands[1]; |
45 | BITMAP *defendFoots[1]; |
46 | |
47 | BITMAP *powerStruggles[1]; |
48 | BITMAP *pushs[4];*/ |
49 | |
50 | void time(void); // used to count hundredths of a second |
51 | void frame1Function(int maxframes); // controls animation of current action for player 1 |
52 | |
53 | void runForward(int player); // 9 frames |
54 | void runBackward(int player); // 4 frames |
55 | |
56 | /*void attackHead(int player); |
57 | void attackHand(int player); |
58 | void attackFoot(int player); |
59 | void defendHead(int player); |
60 | void defendHand(int player); |
61 | void defendFoot(int player); |
62 | |
63 | void push(int player); // 5 frames: one player stumbles backward, other stays in fightStance |
64 | void powerStruggle(void); // both players go through same two frames, then loser is pushed*/ |
65 | |
66 | void stamina(void); // displays players' stamina bars |
67 | void increaseStamina(void); // slightly regenerates stamina every second |
68 | /*void decreaseStamina(void); // decreases player's stamina when an attack is blocked*/ |
69 | |
70 | int main(void) |
71 | { |
72 | allegro_init(); // uses Allegro |
73 | install_timer(); // initializes timing functionality |
74 | install_keyboard(); // allows use of keyboard |
75 | set_color_depth(32); // sets color depth for pallette of sprites |
76 | set_gfx_mode(GFX_AUTODETECT_WINDOWED, 640, 480, 0, 0); // makes the screen a 640x480 window |
77 | SwordPlayTitle = load_bitmap("SwordPlayTitle.bmp", NULL); // loads title screen image |
78 | |
79 | blit(SwordPlayTitle, screen, 0, 0, 0, 0, SwordPlayTitle->w, SwordPlayTitle->h); // puts the title screen picture on the screen |
80 | textprintf_centre_ex(screen, font, SCREEN_W / 2, 460, makecol(255, 255, 255), -1, "Press Any Key to Continue..."); |
81 | destroy_bitmap(SwordPlayTitle); // frees up memory by destroying a now unneeded title screen |
82 | readkey(); // waits for input to proceed |
83 | |
84 | rest(50); // brief pause between input and loading the actual game |
85 | |
86 | // loads frames for the fighting stance animation |
87 | pic = load_bitmap("FightStanceSpriteSheet.bmp", NULL); |
88 | for(int x = 0; x <= 3; x++) |
89 | { |
90 | fightStances[x] = grabframe(pic, 240, 240, 0, 0, 4, x); |
91 | } |
92 | |
93 | // loads frames for the running forward animation |
94 | pic = load_bitmap("RunForwardSheet.bmp", NULL); |
95 | for(int x = 0; x <= 8; x++) |
96 | { |
97 | runForwards[x] = grabframe(pic, 240, 240, 0, 0, 4, x); |
98 | } |
99 | |
100 | // loads frames for the running backward animation |
101 | pic = load_bitmap("RunBackwardSheet.bmp", NULL); |
102 | for(int x = 0; x <= 3; x++) |
103 | { |
104 | runBackwards[x] = grabframe(pic, 240, 240, 0, 0, 4, x); |
105 | } |
106 | |
107 | destroy_bitmap(pic); // frees up memory by destroying a now unneeded temporary variable |
108 | buffer = create_bitmap(SCREEN_W, SCREEN_H); // makes the buffer |
109 | buffer2 = create_bitmap(SCREEN_W, SCREEN_H); // makes the buffer's buffer |
110 | install_int_ex(time, BPS_TO_TIMER(100)); // calls the timer function 100 times every second |
111 | install_int_ex(increaseStamina, BPS_TO_TIMER(1)); // increases the stamina bars for both players by 1 every second |
112 | |
113 | // main game loop |
114 | while(!key[KEY_ESC]) |
115 | { |
116 | clear_to_color(buffer, WHITE); |
117 | /*// attack commands for player 1 |
118 | if(key[KEY_W] && key[KEY_SPACE]) |
119 | attackHead(1); |
120 | else if(key[KEY_SPACE]) |
121 | attackHand(1); |
122 | else if(key[KEY_S] && key[KEY_SPACE]) |
123 | attackFoot(1); |
124 | |
125 | // defend commands for player 1 |
126 | else if(key[KEY_W] && key[KEY_LSHIFT]) |
127 | defendHead(1); |
128 | else if(key[KEY_LSHIFT]) |
129 | defendHand(1); |
130 | else if(key[KEY_S] && key[KEY_LSHIFT]) |
131 | defendFoot(1);*/ |
132 | |
133 | // movement commands for player 1 |
134 | if(key[KEY_D]) |
135 | { |
136 | runForward(1); |
137 | masked_blit(runForwards[frame1], buffer, 0, 0, p1, staticy, runForwards[frame1]->w, runForwards[frame1]->h); |
138 | } |
139 | else if(key[KEY_A]) |
140 | { |
141 | runBackward(1); |
142 | masked_blit(runBackwards[frame1], buffer, 0, 0, p1, staticy, runBackwards[frame1]->w, runBackwards[frame1]->h); |
143 | } |
144 | else |
145 | { |
146 | frame1Function(3); |
147 | masked_blit(fightStances[frame1], buffer, 0, 0, p1, staticy, fightStances[frame1]->w, fightStances[frame1]->h); |
148 | } |
149 | stamina(); // displays the stamina bars on the screen |
150 | masked_blit(buffer, buffer2, 0, 0, 0, 0, buffer->w, buffer->h); // puts everything that just happened in the last split-second on the second buffer |
151 | masked_blit(buffer2, screen, 0, 0, 0, 0, buffer2->w, buffer2->h); // puts that buffer on the screen |
152 | clear_bitmap(buffer); // erases the buffer so that it can be changed again |
153 | } |
154 | remove_int(increaseStamina); // frees up the memory used to call this function over and over again |
155 | |
156 | return 0; // makes this code compatible with non-MS compilers |
157 | }END_OF_MAIN() |
158 | |
159 | void time() |
160 | { |
161 | ticks++; |
162 | |
163 | if(ticks >= 100) |
164 | ticks = 0; |
165 | } |
166 | |
167 | void frame1Function(int maxframes) |
168 | { |
169 | if(frame1 >= maxframes) |
170 | frame1 = 0; |
171 | |
172 | float comparisonVariable = 100 / frameRate; |
173 | |
174 | if(ticks >= comparisonVariable) |
175 | { |
176 | ticks = 0; |
177 | |
178 | if(frame1 >= maxframes) |
179 | frame1 = 0; |
180 | else |
181 | frame1++; |
182 | } |
183 | } |
184 | |
185 | void runForward(int player) |
186 | { |
187 | if(player == 1) |
188 | { |
189 | frame1Function(8); |
190 | |
191 | if(p1 <= (SCREEN_W - 240)) |
192 | p1++; |
193 | } |
194 | } |
195 | |
196 | void runBackward(int player) |
197 | { |
198 | if(player == 1) |
199 | { |
200 | frame1Function(4); |
201 | |
202 | if(p1 > 0) |
203 | p1--; |
204 | } |
205 | } |
206 | |
207 | void stamina() |
208 | { |
209 | textprintf_ex(buffer, font, 5, 15, BLACK, -1, "Player 1"); |
210 | textprintf_right_ex(buffer, font, SCREEN_W - 5, 15, 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 | |
215 | void increaseStamina() |
216 | { |
217 | stamina1++; |
218 | if(stamina1 > 100) |
219 | stamina1 = 100; |
220 | stamina2++; |
221 | if(stamina2 > 100) |
222 | stamina2 = 100; |
223 | } |