if(self->base.flags & JUMPNRUN_ENEMY_SPAWNED) {
if(!enemy_in_spawn_area(self, state) || fixed_point_gt(rectangle_top (enemy_hitbox(self)), FIXED_INT(BADGE_DISPLAY_HEIGHT))) {
jumpnrun_enemy_despawn(self);
- } else if(self->base.flags & JUMPNRUN_MOVEABLE_DYING) {
- if(self->base.tick_minor == JUMPNRUN_SPLOSION_FRAMES * JUMPNRUN_SPLOSION_TICKS_PER_FRAME) {
+ } else if(jumpnrun_moveable_dying(&self->base)) {
+ if(jumpnrun_moveable_finished_dying(&self->base)) {
jumpnrun_enemy_despawn(self);
} else {
if(fb) {
(void) player_inertia_mod;
if(rectangle_intersect(enemy_hitbox(self), &state->player.base.hitbox)) {
- state->player.base.flags |= JUMPNRUN_PLAYER_DEAD;
+ jumpnrun_player_kill(&state->player);
}
}
{
if(rectangle_intersect(enemy_hitbox(self), &state->player.base.hitbox)) {
if(fixed_point_lt(rectangle_top(&state->player.base.hitbox), rectangle_top(enemy_hitbox(self))) &&
- fixed_point_gt(state->player.base.inertia.y, FIXED_INT(0)))
+ fixed_point_gt(state->player.base.inertia.y, FIXED_INT(0)) &&
+ jumpnrun_player_alive(&state->player))
{
jumpnrun_enemy_kill(self);
player_inertia_mod->y = FIXED_POINT(0, -250);
state->player.base.jumpable_frames = 12;
} else {
- state->player.base.flags |= JUMPNRUN_PLAYER_DEAD;
+ jumpnrun_player_kill(&state->player);
}
}
}
jumpnrun_player_respawn(&state->player, lv->start_pos);
state->flags = 0;
state->screen_left = 0;
+ state->tick = 0;
memset(state->shots, 0, sizeof(state->shots));
for(size_t i = 0; i < lv->header.enemy_count; ++i) {
#include "../ui/display.h"
enum {
- JUMPNRUN_MAX_SHOTS = 2,
+ JUMPNRUN_MAX_SHOTS = 2,
- JUMPNRUN_STATE_WON = 1
+ JUMPNRUN_STATE_WON = 1,
+ JUMPNRUN_STATE_TICKS_PER_FRAME = 3
};
typedef struct jumpnrun_game_state {
jumpnrun_player player;
int screen_left;
uint8_t flags;
+ uint8_t tick;
jumpnrun_shot shots[JUMPNRUN_MAX_SHOTS];
} jumpnrun_game_state;
#include "jumpnrun.h"
#include "collision.h"
#include "levels.h"
+#include "player.h"
#include "render.h"
#include "stats.h"
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(state->player.base.hitbox.pos.y, FIXED_INT(BADGE_DISPLAY_HEIGHT))) {
+ jumpnrun_player_despawn(&state->player);
+ } else if(killed) {
+ jumpnrun_player_kill (&state->player);
}
}
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) {
jumpnrun_render_tile(&fb, state, &lv->tiles[tile]);
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 {
+ jumpnrun_render_splosion(&fb, state, &state->player.base);
+ state->player.base.tick_minor += JUMPNRUN_STATE_TICKS_PER_FRAME;
+ }
badge_framebuffer_flush(&fb);
}
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;
}
}
JUMPNRUN_MOVEABLE_DYING = 4
};
+enum {
+ JUMPNRUN_SPLOSION_FRAMES = 4,
+ JUMPNRUN_SPLOSION_TICKS_PER_FRAME = 15
+};
+
typedef struct jumpnrun_moveable {
rectangle hitbox;
vec2d inertia;
static inline bool jumpnrun_moveable_touching_ground(jumpnrun_moveable const *self) { return self->flags & JUMPNRUN_MOVEABLE_TOUCHING_GROUND; }
static inline bool jumpnrun_moveable_mirrored (jumpnrun_moveable const *self) { return self->flags & JUMPNRUN_MOVEABLE_MIRRORED ; }
+static inline bool jumpnrun_moveable_dying (jumpnrun_moveable const *self) { return self->flags & JUMPNRUN_MOVEABLE_DYING ; }
+
+static inline bool jumpnrun_moveable_finished_dying (jumpnrun_moveable const *self) { return jumpnrun_moveable_dying(self) && self->tick_minor >= JUMPNRUN_SPLOSION_FRAMES * JUMPNRUN_SPLOSION_TICKS_PER_FRAME; }
#endif
jumpnrun_player_respawn(self, spawn_pos);
self->lives = lives;
}
+
+void jumpnrun_player_kill (jumpnrun_player *self) {
+ if((self->base.flags & JUMPNRUN_MOVEABLE_DYING) == 0) {
+ self->base.flags |= JUMPNRUN_MOVEABLE_DYING;
+ self->base.tick_minor = 0;
+ }
+}
+
+void jumpnrun_player_despawn(jumpnrun_player *self) {
+ self->base.flags |= JUMPNRUN_PLAYER_DEAD;
+ self->base.flags &= ~JUMPNRUN_MOVEABLE_DYING;
+ self->base.inertia = (vec2d) { FIXED_INT(0), FIXED_INT(0) };
+}
+
+void jumpnrun_player_advance_animation(jumpnrun_player *self) {
+ ++self->base.tick_minor;
+}
};
enum {
+ JUMPNRUN_PLAYER_TICKS_PER_FRAME = 6,
JUMPNRUN_PLAYER_FRAMES = 4
};
uint8_t keys;
} jumpnrun_player;
-void jumpnrun_player_spawn (jumpnrun_player *self, vec2d spawn_pos, uint8_t lives);
-void jumpnrun_player_respawn (jumpnrun_player *self, vec2d spawn_pos);
+void jumpnrun_player_spawn (jumpnrun_player *self, vec2d spawn_pos, uint8_t lives);
+void jumpnrun_player_respawn(jumpnrun_player *self, vec2d spawn_pos);
+void jumpnrun_player_kill (jumpnrun_player *self);
+void jumpnrun_player_despawn(jumpnrun_player *self);
+
+void jumpnrun_player_advance_animation(jumpnrun_player *self);
+
+static inline bool jumpnrun_player_alive(jumpnrun_player const *self) {
+ return (self->base.flags & (JUMPNRUN_PLAYER_DEAD | JUMPNRUN_MOVEABLE_DYING)) == 0;
+}
#endif
void jumpnrun_render_player_symbol(badge_framebuffer *fb, int8_t x, int8_t y);
void jumpnrun_render_key_symbol (badge_framebuffer *fb, int8_t x, int8_t y);
-enum {
- JUMPNRUN_SPLOSION_FRAMES = 4,
- JUMPNRUN_SPLOSION_TICKS_PER_FRAME = 15
-};
-
#endif