diff --git a/assets-cg/img/ice.png b/assets-cg/img/ice.png new file mode 100644 index 0000000..cfaf2e1 Binary files /dev/null and b/assets-cg/img/ice.png differ diff --git a/levels.lua b/levels.lua index a23f15e..42389c6 100644 --- a/levels.lua +++ b/levels.lua @@ -3,6 +3,7 @@ -- - placeholder tile -- v spike -- ^ elevator +-- ~ ice -- j jump upgrade -- -- level id format : YYXX with YY and XX being the Y and X position on the map @@ -60,7 +61,7 @@ levels = {[5049] = [[ -00.....0.0.0..0..0......00- -00......0.0..000.0....vv00- -00....................vv00- --00000000000000000000000000- +-00~~~~~~~~~~~~~~~~~~~~~~00- -00000000000000000000000000- ---------------------------- ]], diff --git a/platform.g3a b/platform.g3a index 3666960..8beb18a 100644 Binary files a/platform.g3a and b/platform.g3a differ diff --git a/src/collide.c b/src/collide.c index c3c503b..99ccb95 100644 --- a/src/collide.c +++ b/src/collide.c @@ -4,17 +4,19 @@ char collide(int x, int y, char level[], char tile) { if ((level[(int)(x/16) + (int)(y/16) * LEVEL_WIDTH] == tile) || - (level[(int)(x/16) + (int)((y+PLAYER_SIDES)/16) * LEVEL_WIDTH] == tile) || - (level[(int)((x+PLAYER_SIDES)/16) + (int)((y+PLAYER_SIDES)/16) * LEVEL_WIDTH] == tile) || - (level[(int)((x+PLAYER_SIDES)/16) + (int)(y/16) * LEVEL_WIDTH] == tile) /*|| - (level[(int)(x/16) + (int)((y+PLAYER_SIDES/2)/16) * LEVEL_WIDTH] == tile) || - (level[(int)((x+PLAYER_SIDES/2)/16) + (int)(y/16) * LEVEL_WIDTH] == tile) || - (level[(int)((x+PLAYER_SIDES/2)/16) + (int)((y+PLAYER_SIDES)/16) * LEVEL_WIDTH] == tile) || - (level[(int)((x+PLAYER_SIDES)/16) + (int)((y+PLAYER_SIDES/2)/16) * LEVEL_WIDTH] == tile)*/) return 1; + (level[(int)(x/16) + (int)((y+PLAYER_SIDES)/16) * LEVEL_WIDTH] == tile) || + (level[(int)((x+PLAYER_SIDES)/16) + (int)((y+PLAYER_SIDES)/16) * LEVEL_WIDTH] == tile) || + (level[(int)((x+PLAYER_SIDES)/16) + (int)(y/16) * LEVEL_WIDTH] == tile) /*|| + (level[(int)(x/16) + (int)((y+PLAYER_SIDES/2)/16) * LEVEL_WIDTH] == tile) || + (level[(int)((x+PLAYER_SIDES/2)/16) + (int)(y/16) * LEVEL_WIDTH] == tile) || + (level[(int)((x+PLAYER_SIDES/2)/16) + (int)((y+PLAYER_SIDES)/16) * LEVEL_WIDTH] == tile) || + (level[(int)((x+PLAYER_SIDES)/16) + (int)((y+PLAYER_SIDES/2)/16) * LEVEL_WIDTH] == tile)*/) return 1; return 0; } char collide_solid(int x, int y, char level[]) { - return (collide(x, y, level, '0') || collide(x, y, level, '^')); + return (collide(x, y, level, '0') || + collide(x, y, level, '^') || + collide(x, y, level, '~')); } diff --git a/src/draw.c b/src/draw.c index 190a06d..1423103 100644 --- a/src/draw.c +++ b/src/draw.c @@ -25,6 +25,7 @@ void draw_level(char level[], char upgrades[]) extern image_t img_ground; //ground texture, 16x16 extern image_t img_spike; //spike texture, 16x16 extern image_t img_elevator; //elevator texture, 16x16 + extern image_t img_ice; //ice texture, 16x4 extern image_t img_jitem; //jump item texture, 16x16 unsigned int i = 0; unsigned int x = 0; @@ -42,10 +43,15 @@ void draw_level(char level[], char upgrades[]) case '^': dimage(x + DRAW_OFFSET_X, y + DRAW_OFFSET_Y, &img_elevator); break; + case '~': + dimage(x + DRAW_OFFSET_X, y + DRAW_OFFSET_Y, &img_ground); + dimage(x + DRAW_OFFSET_X, y + DRAW_OFFSET_Y, &img_ice); + break; case 'j': if (!upgrades[0]) dimage(x + DRAW_OFFSET_X, y + DRAW_OFFSET_Y, &img_jitem); else level[i] = '.'; + break; } x += 16; if (x == 16*LEVEL_WIDTH) diff --git a/src/main.c b/src/main.c index b415270..bd8d2e1 100644 --- a/src/main.c +++ b/src/main.c @@ -6,7 +6,9 @@ #include "levels.h" #include "player.h" -#define WALK_SPD 2 +#define MAX_HSPD 2.0 +#define ACCELERATION 1 +#define DECELERATION 0.5 #define MIN_VSPD -12.0 #define MAX_VSPD 12 #define JUMP_SPD -4.2 @@ -22,59 +24,90 @@ 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; + 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; + volatile int has_ticked = 1; //fps cap + char level[477]; + int level_id = 5050; //start upgrades (mostly bools) char upgrades[] = { 0 //can jump }; //end upgrades - 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; //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; + 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; + int old_x, old_y; char spawn_buffer = 0; - set_level(level_id, level); - draw_level(level, upgrades); + set_level(level_id, level); + draw_level(level, upgrades); 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); + 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 + 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 & 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_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; @@ -85,19 +118,19 @@ int main(void) 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; + 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--; @@ -114,27 +147,27 @@ int main(void) } vspd -= GRAV; } - //vertical collision - { - int trunc_vspd = vspd; //truncate vspd + //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; - } + { + 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; + 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')) { @@ -146,7 +179,7 @@ int main(void) if (player_x <= 22) { level_id -= 1; - player_x = 416 + hspd; + player_x = 416 + (move * (int) hspd); set_start_pos(&start_x, &start_y, player_x, player_y); set_level(level_id, level); draw_level(level, upgrades); @@ -155,7 +188,7 @@ int main(void) else if (player_x >= 416) { level_id += 1; - player_x = 22 + hspd; + player_x = 22 + (move * (int) hspd); set_start_pos(&start_x, &start_y, player_x, player_y); set_level(level_id, level); draw_level(level, upgrades); @@ -186,13 +219,13 @@ int main(void) erase_tile(player_x, player_y, level); draw_upgrade_message('j'); } - //exit - if (keydown(KEY_EXIT)) return 0; - } + //exit + if (keydown(KEY_EXIT)) return 0; + } } int sgn(int number) { - if (number < 0) return -1; - else return 1; + if (number < 0) return -1; + else return 1; }