#include #include #include #include "draw.h" #include "collide.h" #include "levels.h" #include "player.h" #define WALK_SPD 1 #define MIN_VSPD -8.0 #define JUMP_SPD -3.4 #define GRAV 0.2 #define UG_CAN_JUMP upgrades[0] void jump_test(char *jump_pressed, char *jump_buffer, unsigned int *jump_hold); //test if jump pressed int sgn(int number); //return the sign of input double int callback(volatile void *arg) { volatile int *has_ticked = arg; *has_ticked = 1; return 0; } int main(void) { volatile int has_ticked = 1; //fps cap char level[477]; int level_id = 1; //start upgrades (mostly bools) char upgrades[] = { 0 //can jump }; //end upgrades char jump_pressed = 0; //avoid holding jump char jump_buffer = 0; //jump buffer, last 3 frames unsigned int jump_hold = 0; //number of consecutive frames jump has been held double vspd = 0; //player vertical speed char hspd = 0; //player horizontal speed int on_ground = 6; //remember if player is on solid int player_x = 0; int player_y = 0; int start_x = 18*8 + 1; int start_y = 9*8 + 2; int old_x, old_y; set_level(level_id, level); draw_level(level); player_x = start_x; player_y = start_y; old_x = player_x + 1; //offset to draw it on first cycle old_y = player_y; //fps cap timer timer_setup(0, timer_delay(0, 16667), 0, callback, &has_ticked); timer_start(0); while (1) { while(!has_ticked) sleep(); has_ticked = 0; draw_player(old_x, old_y, player_x, player_y); dupdate(); old_x = player_x; old_y = player_y; clearevents(); //horizontal movement hspd = 0; if (keydown(KEY_LEFT)) hspd -= WALK_SPD; if (keydown(KEY_RIGHT)) hspd += WALK_SPD; if (!collide(player_x + hspd, player_y, level, '0')) { player_x += hspd; } //ground detection if (collide(player_x, player_y + 1, level, '0')) on_ground = 6; else { if (vspd > MIN_VSPD) vspd += GRAV; if (jump_hold) if (on_ground) on_ground--; } //vertical movement if (UG_CAN_JUMP) jump_test(&jump_pressed, &jump_buffer, &jump_hold); //if jump is pressed and on ground if (jump_buffer && on_ground) { vspd = JUMP_SPD; on_ground = 0; jump_hold = 10; } else if (jump_hold && keydown(KEY_SHIFT)) { jump_hold--; vspd -= GRAV / 2; } else jump_hold = 0; //vertical collision { int trunc_vspd = vspd; //truncate vspd if (!collide(player_x, player_y + trunc_vspd, level, '0')) { player_y += trunc_vspd; } else { int sign_vspd = sgn(trunc_vspd); while (!collide(player_x, player_y + sign_vspd, level, '0')) { player_y += sign_vspd; } vspd = 0; } } //spike collision and death if (collide(player_x, player_y, level, 'v')) { player_x = start_x; player_y = start_y; } //borders collision if (player_x <= 8) { level_id -= 1; player_x = 201; set_start_pos(&start_x, &start_y, player_x, player_y); set_level(level_id, level); draw_level(level); reset_old_pos(&old_x, &old_y); } else if (player_x >= 208) { level_id += 1; player_x = 9; set_start_pos(&start_x, &start_y, player_x, player_y); set_level(level_id, level); draw_level(level); reset_old_pos(&old_x, &old_y); } //exit if (keydown(KEY_EXIT)) return 0; } } int sgn(int number) { if (number < 0) return -1; else return 1; }