X-Git-Url: https://git.rohieb.name/hackover2013-badge-firmware.git/blobdiff_plain/01d395b92b5ba972a6e1c3d8f2bf4803f155a3cb..05db94c84b6f7e4ee91fd67d6e1a8d97a2b97f2e:/badge/jumpnrun/jumpnrun.c?ds=sidebyside diff --git a/badge/jumpnrun/jumpnrun.c b/badge/jumpnrun/jumpnrun.c index 7dc2c22..c91aac1 100644 --- a/badge/jumpnrun/jumpnrun.c +++ b/badge/jumpnrun/jumpnrun.c @@ -2,6 +2,7 @@ #include "jumpnrun.h" #include "collision.h" #include "levels.h" +#include "player.h" #include "render.h" #include "stats.h" @@ -15,12 +16,11 @@ #include #include -static vec2d const gravity = { FIXED_POINT_I(0, 0), FIXED_POINT_I(0, 56) }; -static vec2d const move_max = { FIXED_POINT_I(0, 600), FIXED_POINT_I(1, 300) }; -static fixed_point const accel_horiz = FIXED_POINT_I(0, 50); -static fixed_point const accel_vert = FIXED_POINT_I(0, 167); -static fixed_point const drag_factor = FIXED_POINT_I(0, 854); -static fixed_point const speed_jump_x = FIXED_POINT_I(0, 600); +static vec2d gravity () { return (vec2d) { FIXED_POINT(0, 0), FIXED_POINT(0, 56) }; } +static vec2d move_max () { return (vec2d) { FIXED_POINT(0, 600), FIXED_POINT(1, 300) }; } +static fixed_point accel_horiz () { return FIXED_POINT(0, 50); } +static fixed_point accel_vert () { return FIXED_POINT(0, 167); } +static fixed_point drag_factor () { return FIXED_POINT(0, 854); } static inline int imax(int x, int y) { return x < y ? y : x; @@ -80,15 +80,15 @@ jumpnrun_tile_range jumpnrun_visible_tiles(jumpnrun_level const *lv, } void jumpnrun_apply_gravity(vec2d *inertia) { - *inertia = vec2d_add(*inertia, gravity); + *inertia = vec2d_add(*inertia, gravity()); } void jumpnrun_passive_movement(vec2d *inertia) { jumpnrun_apply_gravity(inertia); - inertia->x = fixed_point_min(fixed_point_max(fixed_point_neg(move_max.x), inertia->x), move_max.x); - inertia->y = fixed_point_min(fixed_point_max(fixed_point_neg(move_max.y), inertia->y), move_max.y); + inertia->x = fixed_point_min(fixed_point_max(fixed_point_neg(move_max().x), inertia->x), move_max().x); + inertia->y = fixed_point_min(fixed_point_max(fixed_point_neg(move_max().y), inertia->y), move_max().y); } static void jumpnrun_apply_movement(jumpnrun_level const *lv, @@ -99,18 +99,18 @@ static void jumpnrun_apply_movement(jumpnrun_level const *lv, (BADGE_EVENT_KEY_LEFT | BADGE_EVENT_KEY_RIGHT)) { case BADGE_EVENT_KEY_LEFT: - // state->player.base.inertia.x = state->player.touching_ground ? fixed_point_sub(state->player.base.inertia.x, accel_horiz) : fixed_point_neg(speed_jump_x); - state->player.base.inertia.x = fixed_point_sub(state->player.base.inertia.x, accel_horiz); + // state->player.base.inertia.x = state->player.touching_ground ? fixed_point_sub(state->player.base.inertia.x, accel_horiz()) : fixed_point_neg(speed_jump_x()); + state->player.base.inertia.x = fixed_point_sub(state->player.base.inertia.x, accel_horiz()); state->player.base.flags |= JUMPNRUN_MOVEABLE_MIRRORED; break; case BADGE_EVENT_KEY_RIGHT: - // state->player.base.inertia.x = state->player.touching_ground ? fixed_point_add(state->player.base.inertia.x, accel_horiz) : speed_jump_x; - state->player.base.inertia.x = fixed_point_add(state->player.base.inertia.x, accel_horiz); + // state->player.base.inertia.x = state->player.touching_ground ? fixed_point_add(state->player.base.inertia.x, accel_horiz()) : speed_jump_x(); + state->player.base.inertia.x = fixed_point_add(state->player.base.inertia.x, accel_horiz()); state->player.base.flags &= ~JUMPNRUN_MOVEABLE_MIRRORED; break; default: if(jumpnrun_moveable_touching_ground(&state->player.base)) { - state->player.base.inertia.x = fixed_point_mul(state->player.base.inertia.x, drag_factor); + state->player.base.inertia.x = fixed_point_mul(state->player.base.inertia.x, drag_factor()); } //else { //state->player.base.inertia.x = FIXED_INT(0); //} @@ -121,7 +121,7 @@ static void jumpnrun_apply_movement(jumpnrun_level const *lv, if(state->player.base.jumpable_frames == 0) { // intentionally left blank. } else if(badge_event_current_input_state() & BADGE_EVENT_KEY_BTN_A) { - state->player.base.inertia.y = fixed_point_sub(state->player.base.inertia.y, accel_vert); + state->player.base.inertia.y = fixed_point_sub(state->player.base.inertia.y, accel_vert()); --state->player.base.jumpable_frames; } else { state->player.base.jumpable_frames = 0; @@ -140,8 +140,10 @@ static void jumpnrun_apply_movement(jumpnrun_level const *lv, bool killed = collisions_tiles_displace(&new_pos, &state->player.base, lv, tilerange, inertia_mod); state->player.base.inertia = *inertia_mod; - if(killed || fixed_point_gt(state->player.base.hitbox.pos.y, FIXED_INT(BADGE_DISPLAY_HEIGHT))) { - state->player.base.flags |= JUMPNRUN_PLAYER_DEAD; + if(fixed_point_gt(rectangle_top(&state->player.base.hitbox), FIXED_INT(BADGE_DISPLAY_HEIGHT))) { + jumpnrun_player_despawn(&state->player); + } else if(killed) { + jumpnrun_player_kill (&state->player); } } @@ -151,18 +153,20 @@ void jumpnrun_level_tick(jumpnrun_level *lv, jumpnrun_tile_range tilerange = jumpnrun_visible_tiles(lv, state); vec2d inertia_mod = state->player.base.inertia; - jumpnrun_apply_movement(lv, &tilerange, state, &inertia_mod); + if(jumpnrun_player_alive(&state->player)) { + jumpnrun_apply_movement(lv, &tilerange, state, &inertia_mod); + } + state->screen_left = jumpnrun_level_assert_left_side(state); - if(state->player.base.tick_minor == 0) { - badge_framebuffer fb; - badge_framebuffer_clear(&fb); + if(state->tick == 0) { + badge_framebuffer fb = { { { 0 } } }; - for(size_t tile = tilerange.first; tile < tilerange.last; ++tile) { + for(uint16_t tile = tilerange.first; tile < tilerange.last; ++tile) { jumpnrun_render_tile(&fb, state, &lv->tiles[tile]); } - for(size_t item = 0; item < lv->header.item_count; ++item) { + for(uint16_t item = 0; item < lv->header.item_count; ++item) { jumpnrun_item *item_obj = &lv->items[item]; if(item_obj->flags & JUMPNRUN_ITEM_COLLECTED) { @@ -182,7 +186,7 @@ void jumpnrun_level_tick(jumpnrun_level *lv, } } - for(size_t shot_ix = 0; shot_ix < JUMPNRUN_MAX_SHOTS; ++shot_ix) { + for(uint16_t shot_ix = 0; shot_ix < JUMPNRUN_MAX_SHOTS; ++shot_ix) { jumpnrun_shot *shot = &state->shots[shot_ix]; jumpnrun_shot_process(shot); if(jumpnrun_shot_spawned(shot)) { @@ -190,12 +194,20 @@ void jumpnrun_level_tick(jumpnrun_level *lv, } } - for(size_t enemy_ix = 0; enemy_ix < lv->header.enemy_count; ++enemy_ix) { + for(uint16_t enemy_ix = 0; enemy_ix < lv->header.enemy_count; ++enemy_ix) { jumpnrun_enemy *enemy = &lv->enemies[enemy_ix]; jumpnrun_process_enemy(enemy, &fb, state, lv, &tilerange, &inertia_mod); } - jumpnrun_render_player(&fb, state); + if(jumpnrun_player_alive(&state->player)) { + jumpnrun_render_player(&fb, state); + jumpnrun_player_advance_animation(&state->player); + } else if(jumpnrun_moveable_finished_dying(&state->player.base)) { + jumpnrun_player_despawn(&state->player); + } else if(jumpnrun_moveable_dying(&state->player.base)) { + jumpnrun_render_splosion(&fb, state, &state->player.base); + state->player.base.tick_minor += JUMPNRUN_STATE_TICKS_PER_FRAME; + } badge_framebuffer_flush(&fb); @@ -207,31 +219,33 @@ void jumpnrun_level_tick(jumpnrun_level *lv, state->player.base.anim_frame = 0; } } else { - for(size_t shot_ix = 0; shot_ix < JUMPNRUN_MAX_SHOTS; ++shot_ix) { + for(uint16_t shot_ix = 0; shot_ix < JUMPNRUN_MAX_SHOTS; ++shot_ix) { jumpnrun_shot_process(&state->shots[shot_ix]); } - for(size_t enemy_ix = 0; enemy_ix < lv->header.enemy_count; ++enemy_ix) { + for(uint16_t enemy_ix = 0; enemy_ix < lv->header.enemy_count; ++enemy_ix) { jumpnrun_enemy *enemy = &lv->enemies[enemy_ix]; jumpnrun_process_enemy(enemy, NULL, state, lv, &tilerange, &inertia_mod); } } state->player.base.inertia = inertia_mod; - ++state->player.base.tick_minor; - if(state->player.base.tick_minor == 3) { - state->player.base.tick_minor = 0; + ++state->tick; + if(state->tick == JUMPNRUN_STATE_TICKS_PER_FRAME) { + state->tick = 0; } } -uint8_t jumpnrun_play(char const *lvname) { +uint8_t jumpnrun_play_level(char const *lvname) { jumpnrun_level lv; JUMPNRUN_LEVEL_LOAD(lv, lvname); jumpnrun_game_state gs; - for(jumpnrun_game_state_init(&gs, &lv); (gs.flags & JUMPNRUN_STATE_WON) == 0 && gs.player.lives != 0; --gs.player.lives) { + jumpnrun_game_state_init(&gs, &lv); + + do { jumpnrun_show_lives_screen(&gs); jumpnrun_game_state_respawn(&gs, &lv); @@ -269,9 +283,17 @@ uint8_t jumpnrun_play(char const *lvname) { } } } + } while((gs.flags & JUMPNRUN_STATE_WON) == 0 && gs.player.lives-- != 0); + + if(gs.flags & JUMPNRUN_STATE_WON) { + jumpnrun_show_you_rock(); + return JUMPNRUN_WON; + } + + if(++gs.player.lives == 0) { + jumpnrun_show_game_over(); + return JUMPNRUN_LOST; } - if(gs.flags & JUMPNRUN_STATE_WON) { return JUMPNRUN_WON; } - if(gs.player.lives == 0) return JUMPNRUN_LOST; return JUMPNRUN_ERROR; }