From 5df5b3536a7e824c1340a07f3c26a7c61e78b68b Mon Sep 17 00:00:00 2001 From: Wintermute Date: Tue, 15 Oct 2013 20:20:41 +0200 Subject: [PATCH] Hunde. --- badge/jumpnrun/enemies.c | 150 +++++++++++++++++++++++++--------- badge/jumpnrun/enemies.h | 38 +++++---- badge/jumpnrun/moveable.h | 2 +- badge/jumpnrun/smb.lv | 3 +- mock/tools/level-converter.cc | 11 +-- 5 files changed, 141 insertions(+), 63 deletions(-) diff --git a/badge/jumpnrun/enemies.c b/badge/jumpnrun/enemies.c index 4ebd31c..1b35739 100644 --- a/badge/jumpnrun/enemies.c +++ b/badge/jumpnrun/enemies.c @@ -45,22 +45,17 @@ static badge_sprite const anim_spiral[] = { }; static badge_sprite const anim_rotor[] = { - /* - { 9, 9, (uint8_t const *) "\x00\x00\x00\x04\x0e\x1f\x02\x0c\x18\x70\x00" }, - { 9, 9, (uint8_t const *) "\x1c\x30\x60\x84\x0e\x1f\x00\x00\x00\x00\x00" }, - { 9, 9, (uint8_t const *) "\x1c\x30\x60\x80\xf0\xe1\x40\x00\x00\x00\x00" }, - { 9, 9, (uint8_t const *) "\x00\x00\x00\x00\xf0\xe1\x42\x0c\x18\x70\x00" }, - */ { 9, 9, (uint8_t const *) "\x00\x00\x00\x00\xf0\xe1\x42\x0c\x18\x70\x00" }, { 9, 9, (uint8_t const *) "\x1c\x30\x60\x80\xf0\xe1\x40\x00\x00\x00\x00" }, { 9, 9, (uint8_t const *) "\x1c\x30\x60\x84\x0e\x1f\x00\x00\x00\x00\x00" }, { 9, 9, (uint8_t const *) "\x00\x00\x00\x04\x0e\x1f\x02\x0c\x18\x70\x00" } - /* - { 9, 9, (uint8_t const *) "\x00\x00\x00\x00\xf0\xe1\x40\x00\x00\x00\x00" }, - { 9, 9, (uint8_t const *) "\x1c\x30\x60\x80\x00\x01\x00\x00\x00\x00\x00" }, - { 9, 9, (uint8_t const *) "\x00\x00\x00\x04\x0e\x1f\x00\x00\x00\x00\x00" }, - { 9, 9, (uint8_t const *) "\x00\x00\x00\x00\x00\x01\x02\x0c\x18\x70\x00" } - */ +}; + +static badge_sprite const anim_dog[] = { + { 8, 5, (uint8_t const *) "\xc1\xf8\xc6\xb8\x08" }, + { 8, 5, (uint8_t const *) "\xc1\xba\xce\x99\x0c" }, + { 8, 5, (uint8_t const *) "\xc1\xf8\xc6\xb8\x10" }, + { 8, 5, (uint8_t const *) "\xc1\xf8\xc6\xb8\x20" } }; static void enemy_animation_advance(jumpnrun_enemy *enemy) { @@ -99,7 +94,7 @@ void jumpnrun_process_enemy(jumpnrun_enemy *self, enemy_render_flags(self)); } } - } else if(self->flags & JUMPNRUN_ENEMY_UNAVAILABLE) { + } else if(self->flags & JUMPNRUN_ENEMY_UNAVAILABLE) { if(state->left > fixed_point_cast_int(self->spawn_pos.x) + spawn_margin || state->left + BADGE_DISPLAY_WIDTH + spawn_margin < fixed_point_cast_int(self->spawn_pos.x)) { self->flags &= ~JUMPNRUN_ENEMY_UNAVAILABLE; @@ -137,8 +132,8 @@ void enemy_collision_tiles_bounce_horiz(jumpnrun_enemy *self, } void enemy_collision_player_deadly(struct jumpnrun_enemy *self, - struct jumpnrun_game_state *state, - vec2d *player_inertia_mod) { + struct jumpnrun_game_state *state, + vec2d *player_inertia_mod) { (void) player_inertia_mod; rectangle rect_self = enemy_hitbox(self); @@ -166,9 +161,9 @@ void enemy_collision_player_jumpable(jumpnrun_enemy *self, } void enemy_collision_tiles_pass_through(struct jumpnrun_enemy *self, - vec2d *desired_position, - struct jumpnrun_level *lv, - struct jumpnrun_tile_range const *visible_tiles) { + vec2d *desired_position, + struct jumpnrun_level *lv, + struct jumpnrun_tile_range const *visible_tiles) { (void) self; (void) desired_position; (void) lv; @@ -199,10 +194,10 @@ void enemy_tick_straight_ahead(jumpnrun_enemy *self, } void enemy_tick_swing_up_and_down(struct jumpnrun_enemy *self, - struct jumpnrun_game_state *state, - struct jumpnrun_level *lv, - struct jumpnrun_tile_range const *visible_tiles, - vec2d *player_inertia_mod) { + struct jumpnrun_game_state *state, + struct jumpnrun_level *lv, + struct jumpnrun_tile_range const *visible_tiles, + vec2d *player_inertia_mod) { int screenpos = fixed_point_cast_int(rectangle_left(&self->base.current_box)); if(screenpos + JUMPNRUN_MAX_SPAWN_MARGIN < state->left || @@ -216,20 +211,20 @@ void enemy_tick_swing_up_and_down(struct jumpnrun_enemy *self, rectangle_move_to(&self->base.current_box, new_pos); self->base.inertia.y = - fixed_point_add(fixed_point_add(self->base.inertia.y, - fixed_point_div(self->type->spawn_inertia.y, FIXED_INT(3))), - fixed_point_mul(FIXED_POINT(0, 5), - fixed_point_sub(self->spawn_pos.y, - enemy_position(self).y))); + fixed_point_add(fixed_point_add(self->base.inertia.y, + fixed_point_div(self->type->spawn_inertia.y, FIXED_INT(3))), + fixed_point_mul(FIXED_POINT(0, 5), + fixed_point_sub(self->spawn_pos.y, + enemy_position(self).y))); enemy_animation_advance(self); } void enemy_tick_stationary(struct jumpnrun_enemy *self, - struct jumpnrun_game_state *state, - struct jumpnrun_level *lv, - struct jumpnrun_tile_range const *visible_tiles, - vec2d *player_inertia_mod) { + struct jumpnrun_game_state *state, + struct jumpnrun_level *lv, + struct jumpnrun_tile_range const *visible_tiles, + vec2d *player_inertia_mod) { int screenpos = fixed_point_cast_int(rectangle_left(&self->base.current_box)); if(screenpos + JUMPNRUN_MAX_SPAWN_MARGIN < state->left || @@ -244,10 +239,10 @@ void enemy_tick_stationary(struct jumpnrun_enemy *self, } void enemy_tick_jumper(jumpnrun_enemy *self, - jumpnrun_game_state *state, - jumpnrun_level *lv, - jumpnrun_tile_range const *visible_tiles, - vec2d *player_inertia_mod) { + jumpnrun_game_state *state, + jumpnrun_level *lv, + jumpnrun_tile_range const *visible_tiles, + vec2d *player_inertia_mod) { int screenpos = fixed_point_cast_int(rectangle_left(&self->base.current_box)); if(screenpos + JUMPNRUN_MAX_SPAWN_MARGIN < state->left || @@ -269,6 +264,72 @@ void enemy_tick_jumper(jumpnrun_enemy *self, enemy_animation_advance(self); } +void enemy_tick_dog(jumpnrun_enemy *self, + jumpnrun_game_state *state, + jumpnrun_level *lv, + jumpnrun_tile_range const *visible_tiles, + vec2d *player_inertia_mod) { + int screenpos = fixed_point_cast_int(rectangle_left(&self->base.current_box)); + + if(screenpos + JUMPNRUN_MAX_SPAWN_MARGIN < state->left || + screenpos >= state->left + BADGE_DISPLAY_WIDTH + JUMPNRUN_MAX_SPAWN_MARGIN) { + return; + } + + jumpnrun_passive_movement(&self->base.inertia); + + vec2d new_pos = vec2d_add(enemy_position(self), self->base.inertia); + self->type->collision_tiles(self, &new_pos, lv, visible_tiles); + self->type->collision_player(self, state, player_inertia_mod); + rectangle_move_to(&self->base.current_box, new_pos); + + if(self->base.tick_minor % self->type->animation_ticks_per_frame == 0) { + switch(self->base.tick_minor / self->type->animation_ticks_per_frame) { + case 12: + self->base.tick_minor = 0; + case 0: + case 2: + case 4: + case 6: + self->base.anim_frame = 0; + if(self->flags & JUMPNRUN_ENEMY_FACING_RIGHT) { + self->base.inertia.x = fixed_point_neg(self->type->spawn_inertia.x); + } else { + self->base.inertia.x = self->type->spawn_inertia.x; + } + + break; + + case 1: + case 3: + case 5: + case 7: + self->base.anim_frame = 1; + if(self->flags & JUMPNRUN_ENEMY_FACING_RIGHT) { + self->base.inertia.x = fixed_point_neg(self->type->spawn_inertia.x); + } else { + self->base.inertia.x = self->type->spawn_inertia.x; + } + break; + + case 8: + case 10: + self->base.anim_frame = 2; + self->base.inertia.x = FIXED_INT(0); + break; + + case 9: + case 11: + self->base.anim_frame = 3; + self->base.inertia.x = FIXED_INT(0); + break; + } + } + + ++self->base.tick_minor; + if (fixed_point_lt(self->base.inertia.x, FIXED_INT(0))) { self->flags &= ~JUMPNRUN_ENEMY_FACING_RIGHT; } + else if(fixed_point_ne(self->base.inertia.x, FIXED_INT(0))) { self->flags |= JUMPNRUN_ENEMY_FACING_RIGHT; } +} jumpnrun_enemy_type const jumpnrun_enemy_type_data[JUMPNRUN_ENEMY_TYPE_COUNT] = { { @@ -278,7 +339,7 @@ jumpnrun_enemy_type const jumpnrun_enemy_type_data[JUMPNRUN_ENEMY_TYPE_COUNT] = .extent = { FIXED_INT_I(8), FIXED_INT_I(5) }, .hitbox = { { FIXED_INT_I(1), FIXED_INT_I(2) }, { FIXED_INT_I(6), FIXED_INT_I(3) } }, - .spawn_inertia = { FIXED_POINT_I(0, -100), FIXED_INT_I(0) }, + .spawn_inertia = { FIXED_POINT_I(0, -200), FIXED_INT_I(0) }, .collision_tiles = enemy_collision_tiles_bounce_horiz, .collision_player = enemy_collision_player_jumpable, .game_tick = enemy_tick_straight_ahead @@ -310,7 +371,7 @@ jumpnrun_enemy_type const jumpnrun_enemy_type_data[JUMPNRUN_ENEMY_TYPE_COUNT] = .animation_frames = anim_snake, .extent = { FIXED_INT_I(10), FIXED_INT_I(6) }, .hitbox = { { FIXED_INT_I(1), FIXED_INT_I(4) }, - { FIXED_INT_I(8), FIXED_INT_I(2) } }, + { FIXED_INT_I(8), FIXED_INT_I(2) } }, .spawn_inertia = { FIXED_POINT_I(0, -150), FIXED_INT_I(0) }, .collision_tiles = enemy_collision_tiles_bounce_horiz, .collision_player = enemy_collision_player_jumpable, @@ -321,7 +382,7 @@ jumpnrun_enemy_type const jumpnrun_enemy_type_data[JUMPNRUN_ENEMY_TYPE_COUNT] = .animation_frames = anim_spiral, .extent = { FIXED_INT_I(10), FIXED_INT_I(10) }, .hitbox = { { FIXED_INT_I(1), FIXED_INT_I(1) }, - { FIXED_INT_I(8), FIXED_INT_I(8) } }, + { FIXED_INT_I(8), FIXED_INT_I(8) } }, .spawn_inertia = { FIXED_INT_I(0), FIXED_POINT_I(0, -200) }, .collision_tiles = enemy_collision_tiles_pass_through, .collision_player = enemy_collision_player_deadly, @@ -332,10 +393,21 @@ jumpnrun_enemy_type const jumpnrun_enemy_type_data[JUMPNRUN_ENEMY_TYPE_COUNT] = .animation_frames = anim_rotor, .extent = { FIXED_INT_I(9), FIXED_INT_I(9) }, .hitbox = { { FIXED_INT_I(1), FIXED_INT_I(1) }, - { FIXED_INT_I(7), FIXED_INT_I(7) } }, + { FIXED_INT_I(7), FIXED_INT_I(7) } }, .spawn_inertia = { FIXED_INT_I(0), FIXED_POINT_I(0, 0) }, .collision_tiles = enemy_collision_tiles_pass_through, .collision_player = enemy_collision_player_deadly, .game_tick = enemy_tick_stationary + }, { + .animation_ticks_per_frame = 16, + .animation_length = ARRAY_SIZE(anim_dog), + .animation_frames = anim_dog, + .extent = { FIXED_INT_I(8), FIXED_INT_I(5) }, + .hitbox = { { FIXED_INT_I(1), FIXED_INT_I(1) }, + { FIXED_INT_I(6), FIXED_INT_I(4) } }, + .spawn_inertia = { FIXED_POINT_I(0, -200), FIXED_POINT_I(0, 0) }, + .collision_tiles = enemy_collision_tiles_bounce_horiz, + .collision_player = enemy_collision_player_jumpable, + .game_tick = enemy_tick_dog } }; diff --git a/badge/jumpnrun/enemies.h b/badge/jumpnrun/enemies.h index ac8e560..add16c0 100644 --- a/badge/jumpnrun/enemies.h +++ b/badge/jumpnrun/enemies.h @@ -23,17 +23,17 @@ typedef struct jumpnrun_enemy_type { vec2d spawn_inertia; void (*collision_tiles)(struct jumpnrun_enemy *self, - vec2d *desired_position, - struct jumpnrun_level *lv, - struct jumpnrun_tile_range const *visible_tiles); + vec2d *desired_position, + struct jumpnrun_level *lv, + struct jumpnrun_tile_range const *visible_tiles); void (*collision_player)(struct jumpnrun_enemy *self, - struct jumpnrun_game_state *state, - vec2d *player_inertia_mod); + struct jumpnrun_game_state *state, + vec2d *player_inertia_mod); void (*game_tick)(struct jumpnrun_enemy *self, - struct jumpnrun_game_state *state, + struct jumpnrun_game_state *state, struct jumpnrun_level *lv, struct jumpnrun_tile_range const *visible_tiles, - vec2d *player_inertia_mod); + vec2d *player_inertia_mod); } jumpnrun_enemy_type; typedef struct jumpnrun_enemy { @@ -44,16 +44,19 @@ typedef struct jumpnrun_enemy { jumpnrun_enemy_type const *type; } jumpnrun_enemy; +enum { + JUMPNRUN_ENEMY_SPAWNED = 1, + JUMPNRUN_ENEMY_UNAVAILABLE = 2, + JUMPNRUN_ENEMY_FACING_RIGHT = 4 +}; + static inline rectangle const *enemy_box (jumpnrun_enemy const *enemy) { return &enemy->base.current_box ; } static inline vec2d enemy_position (jumpnrun_enemy const *enemy) { return enemy->base.current_box.pos; } static inline rectangle enemy_hitbox (jumpnrun_enemy const *enemy) { rectangle r = enemy->type->hitbox; rectangle_move_rel(&r, enemy_position(enemy)); return r; } static inline badge_sprite const *enemy_sprite (jumpnrun_enemy const *enemy) { return &enemy->type->animation_frames[enemy->base.anim_frame]; } -static inline uint8_t enemy_render_flags(jumpnrun_enemy const *enemy) { return fixed_point_lt(enemy->base.inertia.x, FIXED_POINT(0, 0)) ? 0 : BADGE_BLT_MIRRORED; } -enum { - JUMPNRUN_ENEMY_SPAWNED = 1, - JUMPNRUN_ENEMY_UNAVAILABLE = 2 -}; +static inline bool enemy_facing_right(jumpnrun_enemy const *enemy) { return (enemy->flags & JUMPNRUN_ENEMY_FACING_RIGHT) || fixed_point_gt(enemy->base.inertia.x, FIXED_INT(0)); } +static inline uint8_t enemy_render_flags(jumpnrun_enemy const *enemy) { return enemy_facing_right(enemy) ? BADGE_BLT_MIRRORED : 0; } enum { JUMPNRUN_ENEMY_TYPE_CAT, @@ -62,6 +65,7 @@ enum { JUMPNRUN_ENEMY_TYPE_SNAKE, JUMPNRUN_ENEMY_TYPE_SPIRAL, JUMPNRUN_ENEMY_TYPE_ROTOR, + JUMPNRUN_ENEMY_TYPE_DOG, JUMPNRUN_ENEMY_TYPE_COUNT }; @@ -69,9 +73,9 @@ enum { extern jumpnrun_enemy_type const jumpnrun_enemy_type_data[JUMPNRUN_ENEMY_TYPE_COUNT]; void jumpnrun_process_enemy(jumpnrun_enemy *self, - badge_framebuffer *fb, - struct jumpnrun_game_state *state, - struct jumpnrun_level *lv, - struct jumpnrun_tile_range const *visible_tiles, - vec2d *player_inertia_mod); + badge_framebuffer *fb, + struct jumpnrun_game_state *state, + struct jumpnrun_level *lv, + struct jumpnrun_tile_range const *visible_tiles, + vec2d *player_inertia_mod); #endif diff --git a/badge/jumpnrun/moveable.h b/badge/jumpnrun/moveable.h index 5e7514b..284d2bb 100644 --- a/badge/jumpnrun/moveable.h +++ b/badge/jumpnrun/moveable.h @@ -7,7 +7,7 @@ typedef struct jumpnrun_moveable { rectangle current_box; vec2d inertia; - uint8_t tick_minor; + uint8_t tick_minor; uint8_t anim_frame; uint8_t anim_direction; diff --git a/badge/jumpnrun/smb.lv b/badge/jumpnrun/smb.lv index 4549573..8571c67 100644 --- a/badge/jumpnrun/smb.lv +++ b/badge/jumpnrun/smb.lv @@ -9,7 +9,7 @@ ? #?#?# 01 01 #?# # ## ? ? ? # ## # # ## # ##?# ###### # ### 01 23 23 @ R R ## ## ### ## ####### # ##### P 01 23 23 23 M ### ### #### ### 01 01 ######## D # ##### - S 23 23B 23 B B 23 C C C C C C C C #### #### ##### #### 23 C C 23######### # ##### + S 23 23B 23 H H 23 C C C C C C H H #### #### ##### #### 23 C C 23######### # ##### #################################################################### ############### ################################################################ ##################################################### ######### [tiles] @@ -30,3 +30,4 @@ B bunny S snake @ spiral R rotor +H dog diff --git a/mock/tools/level-converter.cc b/mock/tools/level-converter.cc index 2b3ae35..e4ab5ed 100644 --- a/mock/tools/level-converter.cc +++ b/mock/tools/level-converter.cc @@ -42,11 +42,12 @@ namespace jnrcpp { enemies.add ("cat" , JUMPNRUN_ENEMY_TYPE_CAT ) ("mushroom" , JUMPNRUN_ENEMY_TYPE_MUSHROOM ) - ("bunny" , JUMPNRUN_ENEMY_TYPE_BUNNY ) - ("kaninchen", JUMPNRUN_ENEMY_TYPE_BUNNY ) // legacy - ("snake" , JUMPNRUN_ENEMY_TYPE_SNAKE ) - ("spiral" , JUMPNRUN_ENEMY_TYPE_SPIRAL ) - ("rotor" , JUMPNRUN_ENEMY_TYPE_ROTOR ) + ("bunny" , JUMPNRUN_ENEMY_TYPE_BUNNY ) + ("kaninchen", JUMPNRUN_ENEMY_TYPE_BUNNY ) // legacy + ("snake" , JUMPNRUN_ENEMY_TYPE_SNAKE ) + ("spiral" , JUMPNRUN_ENEMY_TYPE_SPIRAL ) + ("rotor" , JUMPNRUN_ENEMY_TYPE_ROTOR ) + ("dog" , JUMPNRUN_ENEMY_TYPE_DOG ) ; } -- 2.20.1