151 lines
3.6 KiB
C
151 lines
3.6 KiB
C
#include <gint/keyboard.h>
|
|
#include <gint/timer.h>
|
|
#include <gint/clock.h>
|
|
#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[] = {
|
|
1 //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_solid(player_x + hspd, player_y, level))
|
|
{
|
|
player_x += hspd;
|
|
}
|
|
//ground detection
|
|
if (collide_solid(player_x, player_y + 1, level)) 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_solid(player_x, player_y + trunc_vspd, level))
|
|
{
|
|
player_y += trunc_vspd;
|
|
}
|
|
else
|
|
{
|
|
int sign_vspd = sgn(trunc_vspd);
|
|
while (!collide_solid(player_x, player_y + sign_vspd, level))
|
|
{
|
|
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;
|
|
}
|
|
//elevator collision and raise
|
|
if (collide(player_x - 1, player_y, level, '^') ||
|
|
collide(player_x + 1, player_y, level, '^'))
|
|
{
|
|
if (vspd < 8) vspd -= GRAV;
|
|
}
|
|
//borders collision
|
|
if (player_x <= 11)
|
|
{
|
|
level_id -= 1;
|
|
player_x = 207;
|
|
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 = 12;
|
|
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;
|
|
}
|