Checkpoints.
authorWintermute <wintermute@hannover.ccc.de>
Sat, 19 Oct 2013 13:03:32 +0000 (15:03 +0200)
committerWintermute <wintermute@hannover.ccc.de>
Sat, 19 Oct 2013 13:03:32 +0000 (15:03 +0200)
badge/jumpnrun/enemies.c
badge/jumpnrun/items.c
badge/jumpnrun/items.h
badge/jumpnrun/jumpnrun.c
badge/jumpnrun/jumpnrun.h
badge/jumpnrun/level_load.c
badge/jumpnrun/smb.lv
mock/tools/level-converter.cc

index 914d342..7e2e6f6 100644 (file)
@@ -552,7 +552,7 @@ jumpnrun_enemy_type const jumpnrun_enemy_type_data[JUMPNRUN_ENEMY_TYPE_COUNT] =
     .extent                    = { FIXED_INT_I(7), FIXED_INT_I(7) },
     .hitbox                    = { { FIXED_INT_I(1), FIXED_INT_I(1) },
                                    { FIXED_INT_I(5), FIXED_INT_I(4) } },
-    .spawn_inertia             = { FIXED_POINT_I(0, -50), FIXED_INT_I(0) },
+    .spawn_inertia             = { FIXED_POINT_I(0, -80), FIXED_INT_I(0) },
     .collision_tiles           = enemy_collision_tiles_bounce_horiz,
     .collision_player          = enemy_collision_player_jumpable,
     .collision_shots           = enemy_collision_shots_die,
index e0d67b6..cc296c3 100644 (file)
@@ -1,10 +1,25 @@
 #include "items.h"
 #include "jumpnrun.h"
 
-static void on_collect_win(jumpnrun_game_state *state) {
+static void on_collect_win(jumpnrun_item       *self,
+                           jumpnrun_game_state *state,
+                           jumpnrun_level      *lv) {
+  (void) lv;
+  self->flags |= JUMPNRUN_ITEM_COLLECTED;
   state->status = JUMPNRUN_WON;
 }
 
+static void on_collect_checkpoint(jumpnrun_item       *self,
+                                  jumpnrun_game_state *state,
+                                  jumpnrun_level      *lv) {
+  (void) state;
+  self->flags |= JUMPNRUN_ITEM_COLLECTED;
+  lv->start_pos = (vec2d) { self->pos.x,
+                            fixed_point_sub(fixed_point_add(self->pos.y, FIXED_INT(self->type->sprite.height)), hacker_extents().y)
+  };
+}
+
 jumpnrun_item_type const jumpnrun_item_type_data[JUMPNRUN_ITEM_TYPE_COUNT] = {
-  { { 6, 7, (uint8_t const *) "\x7c\x61\xb5\x1a\xfc\x03" }, on_collect_win }
+  { { 6,  7, (uint8_t const *) "\x7c\x61\xb5\x1a\xfc\x03"                             }, on_collect_win },
+  { { 9, 12, (uint8_t const *) "\xff\x1f\x04\x49\x10\x05\x49\x50\x04\x51\x10\x04\x7f" }, on_collect_checkpoint }
 };
index 3ea9668..2ee7a94 100644 (file)
@@ -5,14 +5,23 @@
 #include "../util/rectangle.h"
 
 struct jumpnrun_game_state;
+struct jumpnrun_level;
+struct jumpnrun_item;
+
+enum {
+  JUMPNRUN_ITEM_COLLECTED = 1
+};
 
 typedef struct jumpnrun_item_type {
   badge_sprite sprite;
-  void (*on_collect)(struct jumpnrun_game_state *state);
+  void (*on_collect)(struct jumpnrun_item       *item,
+                     struct jumpnrun_game_state *state,
+                     struct jumpnrun_level      *lv);
 } jumpnrun_item_type;
 
 typedef struct jumpnrun_item {
-  vec2d pos;
+  vec2d   pos;
+  uint8_t flags;
   jumpnrun_item_type const *type;
 } jumpnrun_item;
 
@@ -25,6 +34,7 @@ static inline rectangle rect_from_item(jumpnrun_item const *item) {
 
 enum {
   JUMPNRUN_ITEM_TYPE_DOCUMENT,
+  JUMPNRUN_ITEM_TYPE_CHECKPOINT,
 
   JUMPNRUN_ITEM_TYPE_COUNT
 };
index 5fc5eb7..3c7f04b 100644 (file)
@@ -19,7 +19,7 @@ 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 const hacker_extent = { FIXED_INT_I(5), FIXED_INT_I(8) };
+vec2d hacker_extents(void) { return (vec2d) { FIXED_INT_I(5), FIXED_INT_I(8) }; }
 static vec2d const shot_spawn_inertia = { FIXED_POINT_I(0, 800), FIXED_POINT_I(0, -800) };
 
 static badge_sprite const anim_hacker[] = {
@@ -86,8 +86,8 @@ static inline int imax(int x, int y) {
 
 static inline fixed_point hacker_left  (vec2d const *pos, jumpnrun_game_state const *state) { (void) state; return pos->x; }
 static inline fixed_point hacker_top   (vec2d const *pos, jumpnrun_game_state const *state) { (void) state; return pos->y; }
-static inline fixed_point hacker_right (vec2d const *pos, jumpnrun_game_state const *state) { return fixed_point_add(hacker_left(pos, state), hacker_extent.x); }
-static inline fixed_point hacker_bottom(vec2d const *pos, jumpnrun_game_state const *state) { return fixed_point_add(hacker_top (pos, state), hacker_extent.y); }
+static inline fixed_point hacker_right (vec2d const *pos, jumpnrun_game_state const *state) { return fixed_point_add(hacker_left(pos, state), hacker_extents().x); }
+static inline fixed_point hacker_bottom(vec2d const *pos, jumpnrun_game_state const *state) { return fixed_point_add(hacker_top (pos, state), hacker_extents().y); }
 
 int jumpnrun_level_assert_left_side(jumpnrun_game_state const *state) {
   static int const lmargin = 20;
@@ -221,19 +221,25 @@ void jumpnrun_level_tick(jumpnrun_level      *lv,
     }
 
     for(size_t item = 0; item < lv->header.item_count; ++item) {
-      int screenpos = fixed_point_cast_int(lv->items[item].pos.x) - state->left;
-      if(screenpos > -lv->items[item].type->sprite.width &&
+      jumpnrun_item *item_obj = &lv->items[item];
+
+      if(item_obj->flags & JUMPNRUN_ITEM_COLLECTED) {
+        continue;
+      }
+
+      int screenpos = fixed_point_cast_int(item_obj->pos.x) - state->left;
+      if(screenpos > -item_obj->type->sprite.width &&
          screenpos < BADGE_DISPLAY_WIDTH) {
-        rectangle item_rect = rect_from_item(&lv->items[item]);
+        rectangle item_rect = rect_from_item(item_obj);
 
         if(rectangle_intersect(&state->player.current_box, &item_rect)) {
-          lv->items[item].type->on_collect(state);
+          item_obj->type->on_collect(item_obj, state, lv);
         }
 
         badge_framebuffer_blt(&fb,
                               screenpos,
-                              fixed_point_cast_int(lv->items[item].pos.y),
-                              &lv->items[item].type->sprite,
+                              fixed_point_cast_int(item_obj->pos.y),
+                              &item_obj->type->sprite,
                               0);
       }
     }
@@ -332,13 +338,16 @@ uint8_t jumpnrun_play(char const *lvname) {
   jumpnrun_game_state gs;
   memset(&gs, 0, sizeof(gs));
 
-  gs.player.current_box = rectangle_new(lv.start_pos, hacker_extent);
+  for(gs.lives = 3; gs.lives != 0; --gs.lives) {
+    gs.status = JUMPNRUN_PLAYING;
+    gs.player.current_box = rectangle_new(lv.start_pos,
+                                          hacker_extents());
 
-  while(gs.status == JUMPNRUN_PLAYING) {
-    badge_event_t ev = badge_event_wait();
+    while(gs.status == JUMPNRUN_PLAYING) {
+      badge_event_t ev = badge_event_wait();
 
-    switch(badge_event_type(ev)) {
-    case BADGE_EVENT_USER_INPUT:
+      switch(badge_event_type(ev)) {
+      case BADGE_EVENT_USER_INPUT:
       {
         uint8_t old_state = badge_event_old_input_state(ev);
         uint8_t new_state = badge_event_new_input_state(ev);
@@ -360,11 +369,12 @@ uint8_t jumpnrun_play(char const *lvname) {
 
         break;
       }
-    case BADGE_EVENT_GAME_TICK:
+      case BADGE_EVENT_GAME_TICK:
       {
         jumpnrun_level_tick(&lv, &gs);
         break;
       }
+      }
     }
   }
 
index cdbcf95..c6613f5 100644 (file)
@@ -43,12 +43,12 @@ typedef struct jumpnrun_game_state {
 
   uint8_t status;
   int     left;
+  uint8_t lives;
 
   jumpnrun_shot shots[JUMPNRUN_MAX_SHOTS];
 } jumpnrun_game_state;
 
-rectangle hacker_rect_current(jumpnrun_game_state const *state);
-
+vec2d hacker_extents(void);
 void jumpnrun_passive_movement(vec2d *inertia);
 
 uint8_t jumpnrun_play(char const *lvname);
index a945fc9..dc009b9 100644 (file)
@@ -2,6 +2,7 @@
 #include "tiles.h"
 #include "items.h"
 #include "enemies.h"
+#include "jumpnrun.h"
 
 #ifndef __linux__
 #include <drivers/fatfs/ff.h>
@@ -26,30 +27,30 @@ static level_thing jumpnrun_level_parse_blob(unsigned char blob[3]) {
 }
 
 static void jumpnrun_level_make_tile(jumpnrun_tile *dest, level_thing thing) {
+  memset(dest, 0, sizeof(*dest));
+
   dest->type  = thing.type;
   dest->pos.x = thing.x;
   dest->pos.y = thing.y;
 }
 
 static void jumpnrun_level_make_item(jumpnrun_item *dest, level_thing thing) {
+  memset(dest, 0, sizeof(*dest));
+
   dest->type = &jumpnrun_item_type_data[thing.type];
-  dest->pos.x = FIXED_POINT(thing.x * JUMPNRUN_TILE_PIXEL_WIDTH , 0);
-  dest->pos.y = FIXED_POINT(thing.y * JUMPNRUN_TILE_PIXEL_WIDTH , 0);
+  dest->pos.x = FIXED_POINT( thing.x      * JUMPNRUN_TILE_PIXEL_WIDTH                            , 0);
+  dest->pos.y = FIXED_POINT((thing.y + 1) * JUMPNRUN_TILE_PIXEL_WIDTH - dest->type->sprite.height, 0);
 }
 
 static void jumpnrun_level_make_enemy(jumpnrun_enemy *dest, level_thing thing) {
+  memset(dest, 0, sizeof(*dest));
+
   dest->type = &jumpnrun_enemy_type_data[thing.type];
 
-  dest->spawn_pos.x          = FIXED_POINT(thing.x * JUMPNRUN_TILE_PIXEL_WIDTH , 0);
-  dest->spawn_pos.y          = FIXED_POINT(thing.y * JUMPNRUN_TILE_PIXEL_HEIGHT, 0);
+  dest->spawn_pos.x          = FIXED_POINT( thing.x      * JUMPNRUN_TILE_PIXEL_WIDTH                                          , 0);
+  dest->spawn_pos.y          = FIXED_POINT((thing.y + 1) * JUMPNRUN_TILE_PIXEL_HEIGHT - dest->type->animation_frames[0].height, 0);
   dest->base.current_box     = rectangle_new(dest->spawn_pos, dest->type->extent);
   dest->base.inertia         = dest->type->spawn_inertia;
-  dest->flags                = 0;
-  dest->base.tick_minor      = 0;
-  dest->base.anim_frame      = 0;
-  dest->base.anim_direction  = 0;
-  dest->base.touching_ground = 0;
-  dest->base.jumpable_frames = 0;
 }
 
 #ifdef __linux__
@@ -92,8 +93,8 @@ int jumpnrun_load_level_from_file(jumpnrun_level *dest, FIL *fd) {
 #endif
     return JUMPNRUN_LEVEL_LOAD_ERROR;
   } else {
-    dest->start_pos.x = FIXED_POINT(spos[0] * JUMPNRUN_TILE_PIXEL_WIDTH , 0);
-    dest->start_pos.y = FIXED_POINT(spos[1] * JUMPNRUN_TILE_PIXEL_HEIGHT, 0);
+    dest->start_pos.x = fixed_point_sub(FIXED_INT((spos[0] + 1) * JUMPNRUN_TILE_PIXEL_WIDTH ), hacker_extents().x);
+    dest->start_pos.y =                 FIXED_INT( spos[1]      * JUMPNRUN_TILE_PIXEL_HEIGHT);
   }
 
   for(i = 0; i < dest->header.tile_count; ++i) {
index 6f30070..59c765b 100644 (file)
@@ -5,11 +5,11 @@
                      ?                                                         vv######   ###?        W     ?           ###    #??#                                                        ##        #
                                                                                                                                                                                           ###        #
                                                          V                                                                                                                               ####        #     #
-                                                                                                                                                                                        #####     V  #    ###
-               ?   #?#?#                     01         01                  #?#              #     ##    ?  ?  ?     #          ##      #  #          ##  #            ##?#            ######        #    ###
+                                                                                                   c                                                                                    #####        #    ###
+               ?   #?#?#                     01         01                  #?#              #     ##    ?  ?  ?     #          ##      #  #          ##  #            ##?#            ######     V  #    ###
                                      01      23         23          @                R R                                               ##  ##        ###  ##                          #######        #   #####
-   P                       01        23      23         23                       G                        M                           ###  ###      ####  ###     01              01 ########   D    #   #####
-                     S     23        23B     23   H H   23                                      C C              S S      C C  H H   ####  ####    #####  ####    23         H H  23#########        #   #####
+                           01        23      23         23                       G                        M                           ###  ###      ####  ###     01              01 ########   d    #   #####
+   P                 S     23        23B     23   H H   23                                      C C              S S      C C  H H   ####  ####    #####  ####    23         H H  23#########        #   #####
 ####################################################################  ###############   ################################################################  ############################################^^^######
 
 [tiles]
@@ -25,7 +25,8 @@ v spike_down
 < spike_left
 
 [items]
-D doc
+d doc
+c checkpoint
 
 [enemies]
 C cat
index e5bfa98..cdd4662 100644 (file)
@@ -40,7 +40,8 @@ namespace jnrcpp {
         ;
 
       items.add
-        ("doc", JUMPNRUN_ITEM_TYPE_DOCUMENT)
+        ("doc"       , JUMPNRUN_ITEM_TYPE_DOCUMENT  )
+        ("checkpoint", JUMPNRUN_ITEM_TYPE_CHECKPOINT)
         ;
 
       enemies.add
This page took 0.038513 seconds and 4 git commands to generate.