252 lines
6.1 KiB
C
252 lines
6.1 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 MAX_HSPD 2.5
|
|
#define ACCELERATION 1
|
|
#define DECELERATION 0.5
|
|
#define MIN_VSPD -12.0
|
|
#define MAX_VSPD 12
|
|
#define JUMP_SPD -3.99
|
|
#define GRAV 0.4
|
|
#define JUMP_SCALE 12
|
|
#define JUMP_REDUCTION -0.41
|
|
#define UG_CAN_JUMP upgrades[0]
|
|
char coins[1];
|
|
#define DRAW_LEVEL() draw_level(level, upgrades, coins[coin_id])
|
|
|
|
void dupdate(); //gint function
|
|
//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 = 5050;
|
|
//START UPGRADES
|
|
char upgrades[] = {
|
|
0 //jump
|
|
};
|
|
//END UPGRADES
|
|
unsigned int coin_id = 0;
|
|
unsigned int coin_count = 0;
|
|
char jump_pressed = 1; //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.0; //player vertical speed
|
|
double hspd = 0; //player horizontal speed
|
|
int move = 0;
|
|
int direction = 0;
|
|
int on_ground = 6; //remember if player is on solid
|
|
int player_x = 0;
|
|
int player_y = 0;
|
|
int start_x = 18*16 + 2;
|
|
int start_y = 9*16 + 4;
|
|
int old_x, old_y;
|
|
char spawn_buffer = 0;
|
|
unsigned int step = 0;
|
|
set_level(level_id, level, &coin_id);
|
|
DRAW_LEVEL();
|
|
draw_level_anims(level, upgrades, step);
|
|
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;
|
|
//START DRAW
|
|
step++;
|
|
draw_level_anims(level, upgrades, step);
|
|
draw_player(old_x, old_y, player_x, player_y);
|
|
draw_timer(step);
|
|
dupdate();
|
|
old_y = player_y;
|
|
old_x = player_x;
|
|
//END DRAW
|
|
clearevents();
|
|
//horizontal movement & collision
|
|
{
|
|
move = 0;
|
|
double friction = 1;
|
|
int trunc_hspd;
|
|
//ice
|
|
if (collide(player_x, player_y + 1, level, '~')) friction = 0.2;
|
|
move = keydown(KEY_RIGHT) + 0 - keydown(KEY_LEFT);
|
|
if (move) {
|
|
if (hspd < MAX_HSPD)
|
|
{
|
|
hspd += ACCELERATION * friction;
|
|
if (hspd > MAX_HSPD) hspd = MAX_HSPD;
|
|
}
|
|
direction = move;
|
|
}
|
|
else if (hspd > 0)
|
|
{
|
|
if (friction != 0.2) hspd -= DECELERATION * friction;
|
|
else hspd -= DECELERATION / 4 * friction;
|
|
if (hspd < 0) hspd = 0;
|
|
}
|
|
trunc_hspd = hspd * direction;
|
|
if (!collide(player_x, player_y + 1, level, '#'))
|
|
{
|
|
if (!collide_solid(player_x + trunc_hspd, player_y, level))
|
|
{
|
|
player_x += trunc_hspd;
|
|
}
|
|
else
|
|
{
|
|
int sign_hspd = sgn(trunc_hspd);
|
|
while (!collide_solid(player_x + sign_hspd, player_y, level))
|
|
{
|
|
player_x += sign_hspd;
|
|
}
|
|
hspd = 0;
|
|
}
|
|
}
|
|
}
|
|
//ground detection
|
|
if (vspd >= 0 && collide_solid(player_x, player_y + 1, level))
|
|
{
|
|
on_ground = 6;
|
|
vspd = 0;
|
|
if (spawn_buffer)
|
|
{
|
|
spawn_buffer = 0;
|
|
set_start_pos(&start_x, &start_y, player_x, player_y);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (on_ground != 6 && vspd < MAX_VSPD) vspd += GRAV;
|
|
if (on_ground) on_ground--;
|
|
}
|
|
//vertical movement
|
|
if (UG_CAN_JUMP) jump_test(&jump_pressed, &jump_buffer, &jump_hold);
|
|
//jump
|
|
if (jump_buffer && on_ground) {
|
|
vspd = JUMP_SPD;
|
|
on_ground = 0;
|
|
jump_hold = JUMP_SCALE;
|
|
}
|
|
else if (jump_hold && keydown(KEY_SHIFT))
|
|
{
|
|
jump_hold--;
|
|
vspd += JUMP_REDUCTION;
|
|
}
|
|
else jump_hold = 0;
|
|
//elevator collision and raise
|
|
if ((collide(player_x - 1, player_y, level, '^') ||
|
|
collide(player_x + 1, player_y, level, '^')) && vspd > MIN_VSPD)
|
|
{
|
|
if (vspd > -2)
|
|
{
|
|
vspd -= GRAV;
|
|
}
|
|
vspd -= GRAV;
|
|
}
|
|
//vertical collision
|
|
{
|
|
int trunc_vspd = vspd; //truncate vspd
|
|
if (trunc_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;
|
|
jump_hold = 0;
|
|
}
|
|
}
|
|
}
|
|
//spike collision and death
|
|
if (collide(player_x, player_y, level, 'v'))
|
|
{
|
|
player_x = start_x;
|
|
player_y = start_y;
|
|
vspd = 0;
|
|
}
|
|
//borders collision
|
|
if (player_x <= 22)
|
|
{
|
|
level_id -= 1;
|
|
player_x = 416 + (move * (int) hspd);
|
|
set_start_pos(&start_x, &start_y, player_x, player_y);
|
|
set_level(level_id, level, &coin_id);
|
|
DRAW_LEVEL();
|
|
reset_old_pos(&old_x, &old_y);
|
|
}
|
|
else if (player_x >= 416)
|
|
{
|
|
level_id += 1;
|
|
player_x = 22 + (move * (int) hspd);
|
|
set_start_pos(&start_x, &start_y, player_x, player_y);
|
|
set_level(level_id, level, &coin_id);
|
|
DRAW_LEVEL();
|
|
reset_old_pos(&old_x, &old_y);
|
|
}
|
|
else if (player_y <= 8)
|
|
{
|
|
level_id -= 100;
|
|
player_y = 246;
|
|
spawn_buffer = 1;
|
|
set_level(level_id, level, &coin_id);
|
|
DRAW_LEVEL();
|
|
reset_old_pos(&old_x, &old_y);
|
|
}
|
|
else if (player_y >= 248)
|
|
{
|
|
level_id += 100;
|
|
player_y = 10;
|
|
set_start_pos(&start_x, &start_y, player_x, player_y);
|
|
set_level(level_id, level, &coin_id);
|
|
DRAW_LEVEL();
|
|
reset_old_pos(&old_x, &old_y);
|
|
}
|
|
//item get
|
|
if (collide(player_x, player_y, level, 'j'))
|
|
{
|
|
UG_CAN_JUMP = 1;
|
|
erase_tile(player_x, player_y, level);
|
|
draw_upgrade_message('j');
|
|
}
|
|
//coin get
|
|
if (collide(player_x, player_y, level, 'c'))
|
|
{
|
|
coins[coin_id] = 1;
|
|
coin_count++;
|
|
erase_tile(player_x, player_y, level);
|
|
}
|
|
//exit
|
|
if (keydown(KEY_EXIT)) return 0;
|
|
}
|
|
}
|
|
|
|
int sgn(int number)
|
|
{
|
|
if (number < 0) return -1;
|
|
else return 1;
|
|
}
|