#include <stddef.h>
#include <stdio.h>
-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;
}
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,
(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);
//}
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;
bool killed = collisions_tiles_displace(&new_pos, &state->player.base, lv, tilerange, inertia_mod);
state->player.base.inertia = *inertia_mod;
- if(fixed_point_gt(state->player.base.hitbox.pos.y, FIXED_INT(BADGE_DISPLAY_HEIGHT))) {
+ 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);
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) {
}
}
- 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)) {
}
}
- 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_player_advance_animation(&state->player);
} else if(jumpnrun_moveable_finished_dying(&state->player.base)) {
jumpnrun_player_despawn(&state->player);
- } else {
+ } 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;
}
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);
}
}
}
-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);
}
}
}
+ } 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;
}