| 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 | } |