Init nochmal verkürzt.
[hackover2013-badge-firmware.git] / badge / jumpnrun / enemies.c
1 #include "enemies.h"
2
3 #include "collision.h"
4 #include "tiles.h"
5 #include "jumpnrun.h"
6
7 #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof*(arr))
8
9 static badge_sprite const anim_cat[] = {
10 { 8, 5, (uint8_t const *) "\xc7\x3f\xce\x38\x11" },
11 { 8, 5, (uint8_t const *) "\xd7\x7d\xc6\x19\x25" }
12 };
13
14 void jumpnrun_process_enemy(jumpnrun_enemy *self,
15 badge_framebuffer *fb,
16 struct jumpnrun_game_state *state,
17 struct jumpnrun_level *lv,
18 struct jumpnrun_tile_range const *visible_tiles) {
19 int const spawn_margin = 1 + self->type->animation_frames[self->current_frame].width;
20
21 if(self->flags & JUMPNRUN_ENEMY_SPAWNED) {
22 if(fixed_point_lt(self->current_pos.x, FIXED_POINT(state->left - spawn_margin, 0)) ||
23 fixed_point_gt(self->current_pos.x, FIXED_POINT(state->left + BADGE_DISPLAY_WIDTH + spawn_margin, 0)) ||
24 fixed_point_cast_int(self->current_pos.y) > BADGE_DISPLAY_HEIGHT) {
25 self->flags &= ~JUMPNRUN_ENEMY_SPAWNED;
26 } else {
27 self->type->game_tick(self, state, lv, visible_tiles);
28 badge_framebuffer_blt(fb,
29 fixed_point_cast_int(self->current_pos.x) - state->left,
30 fixed_point_cast_int(self->current_pos.y),
31 &self->type->animation_frames[self->current_frame],
32 fixed_point_lt(self->inertia.x, FIXED_POINT(0, 0)) ? 0 : BADGE_BLT_MIRRORED);
33 }
34 } else if(self->flags & JUMPNRUN_ENEMY_UNAVAILABLE) {
35 if(state->left > fixed_point_cast_int(self->spawn_pos.x) + spawn_margin ||
36 state->left + BADGE_DISPLAY_WIDTH + spawn_margin < fixed_point_cast_int(self->spawn_pos.x)) {
37 self->flags &= ~JUMPNRUN_ENEMY_UNAVAILABLE;
38 }
39 } else if((fixed_point_gt(self->spawn_pos.x, FIXED_POINT(state->left - spawn_margin, 0)) &&
40 fixed_point_lt(self->spawn_pos.x, FIXED_POINT(state->left - spawn_margin / 2, 0))) ||
41 (fixed_point_lt(self->spawn_pos.x, FIXED_POINT(state->left + BADGE_DISPLAY_WIDTH + spawn_margin, 0)) &&
42 fixed_point_gt(self->spawn_pos.x, FIXED_POINT(state->left + BADGE_DISPLAY_WIDTH, 0)))) {
43 // enemy unspawned, available and in spawn zone.
44 self->flags |= JUMPNRUN_ENEMY_SPAWNED | JUMPNRUN_ENEMY_UNAVAILABLE;
45 self->current_pos = self->spawn_pos;
46 self->inertia = self->type->spawn_inertia;
47 self->current_frame = 0;
48 self->tick_counter = 0;
49 }
50 }
51
52 void enemy_collision_tiles_bounce_horiz(jumpnrun_enemy *self,
53 vec2d *desired_position,
54 jumpnrun_level *lv,
55 jumpnrun_tile_range const *visible_tiles) {
56 rectangle rect_self = rect_from_enemy(self);
57 vec2d inertia_copy = self->inertia;
58 bool touching_ground = false;
59
60 collisions_tiles_displace(desired_position,
61 &rect_self,
62 lv,
63 visible_tiles,
64 &inertia_copy,
65 &touching_ground);
66
67 if(fixed_point_ne(inertia_copy.x, self->inertia.x)) {
68 self->inertia.x = fixed_point_neg(self->inertia.x);
69 }
70 }
71
72 void enemy_collision_player_kill(jumpnrun_enemy *self,
73 jumpnrun_game_state *state)
74 {
75 rectangle rect_self = rect_from_enemy(self);
76 rectangle rect_hacker = hacker_rect_current(state);
77
78 if(rectangle_intersect(&rect_self, &rect_hacker)) {
79 state->status = JUMPNRUN_DEAD;
80 }
81 }
82
83 void enemy_tick_cat(jumpnrun_enemy *self,
84 jumpnrun_game_state *state,
85 jumpnrun_level *lv,
86 jumpnrun_tile_range const *visible_tiles) {
87 int screenpos = fixed_point_cast_int(self->current_pos.x);
88
89 if(screenpos + JUMPNRUN_MAX_SPAWN_MARGIN < state->left ||
90 screenpos >= state->left + BADGE_DISPLAY_WIDTH + JUMPNRUN_MAX_SPAWN_MARGIN) {
91 return;
92 }
93
94 jumpnrun_passive_movement(&self->inertia);
95
96 vec2d new_pos = vec2d_add(self->current_pos, self->inertia);
97 self->type->collision_tiles(self, &new_pos, lv, visible_tiles);
98 self->type->collision_player(self, state);
99 self->current_pos = new_pos;
100
101 self->tick_counter = (self->tick_counter + 1) % self->type->animation_ticks_per_frame;
102 if(self->tick_counter == 0) {
103 self->current_frame = (self->current_frame + 1) % self->type->animation_length;
104 }
105 }
106
107 jumpnrun_enemy_type const jumpnrun_enemy_type_data[JUMPNRUN_ENEMY_TYPE_COUNT] = {
108 { 2, ARRAY_SIZE(anim_cat), anim_cat,
109 { FIXED_POINT_I(0, -800), FIXED_POINT_I(0, 0) },
110 enemy_collision_tiles_bounce_horiz,
111 enemy_collision_player_kill,
112 enemy_tick_cat
113 }
114 };
This page took 0.053974 seconds and 5 git commands to generate.