assert(delta_time > 0);
player_update(level->player, delta_time);
- player_collide_with_platforms(level->player, level->platforms);
boxes_update(level->boxes, delta_time);
- boxes_collide_with_player(level->boxes, level->player);
boxes_collide_with_platforms(level->boxes, level->platforms);
+ boxes_collide_with_player(level->boxes, level->player);
+
+ player_collide_with_platforms(level->player, level->platforms);
+ player_collide_with_boxes(level->player, level->boxes);
player_hide_goals(level->player, level->goals);
player_die_from_lava(level->player, level->lava);
#include <assert.h>
#include "game/level/boxes.h"
+#include "game/level/player.h"
#include "game/level/player/rigid_rect.h"
#include "system/lt.h"
#include "system/error.h"
assert(boxes);
assert(player);
- const rect_t hitbox = player_hitbox(player);
+ for (size_t i = 0; i < boxes->count; ++i) {
+ player_impact_rigid_rect(player, boxes->bodies[i]);
+ }
+}
+
+void boxes_rect_object_collide(const boxes_t *boxes,
+ rect_t object,
+ int sides[RECT_SIDE_N])
+{
+ assert(boxes);
+
+ memset(sides, 0, sizeof(int) * RECT_SIDE_N);
for (size_t i = 0; i < boxes->count; ++i) {
- player_collide_with_rect(player, rigid_rect_hitbox(boxes->bodies[i]));
- rigid_rect_collide_with_rect(boxes->bodies[i], hitbox);
+ const rect_t hitbox = rigid_rect_hitbox(boxes->bodies[i]);
+ rect_object_impact(&object, &hitbox, sides);
}
}
#define BOXES_H_
#include "game/level/platforms.h"
-#include "game/level/player.h"
#include "game/camera.h"
typedef struct boxes_t boxes_t;
+typedef struct player_t player_t;
boxes_t *create_boxes_from_stream(FILE *stream);
void destroy_boxes(boxes_t *boxes);
int boxes_render(boxes_t *boxes, camera_t *camera);
int boxes_update(boxes_t *boxes, float delta_time);
+void boxes_rect_object_collide(const boxes_t *boxes,
+ rect_t object,
+ int sides[RECT_SIDE_N]);
void boxes_collide_with_platforms(boxes_t *boxes,
const platforms_t *platforms);
void boxes_collide_with_player(boxes_t *boxes,
}
}
+void player_collide_with_boxes(player_t * player,
+ const boxes_t * boxes)
+{
+ if (player->state == PLAYER_STATE_ALIVE) {
+ rigid_rect_collide_with_boxes(player->alive_body, boxes);
+
+ if (rigid_rect_touches_ground(player->alive_body)) {
+ player->jump_count = 0;
+ }
+ }
+}
+
void player_collide_with_rect(player_t * player,
rect_t rect)
{
}
}
+void player_impact_rigid_rect(player_t * player,
+ rigid_rect_t *rigid_rect)
+{
+ if (player->state == PLAYER_STATE_ALIVE) {
+ rigid_rect_impact_rigid_rect(player->alive_body, rigid_rect);
+ }
+}
+
void player_move_left(player_t *player)
{
assert(player);
#include "game/sound_samples.h"
#include "lava.h"
#include "platforms.h"
+#include "boxes.h"
typedef struct player_t player_t;
-
typedef struct goals_t goals_t;
+typedef struct rigid_rect_t rigid_rect_t;
player_t *create_player(float x, float y, color_t color);
player_t *create_player_from_stream(FILE *stream);
const platforms_t *platforms);
void player_collide_with_rect(player_t * player,
rect_t rect);
+void player_collide_with_boxes(player_t * player,
+ const boxes_t * boxes);
+void player_impact_rigid_rect(player_t * player,
+ rigid_rect_t *rigid_rect);
rect_t player_hitbox(const player_t *player);
#include "rigid_rect.h"
#include "system/error.h"
#include "system/lt.h"
+#include "game/level/boxes.h"
#define RIGID_RECT_GRAVITY 1500.0f
}
}
+void rigid_rect_collide_with_boxes(rigid_rect_t * rigid_rect,
+ const boxes_t *boxes)
+{
+ int sides[RECT_SIDE_N] = { 0, 0, 0, 0 };
+
+ boxes_rect_object_collide(boxes, rigid_rect_hitbox(rigid_rect), sides);
+
+ if (sides[RECT_SIDE_BOTTOM]) {
+ rigid_rect->touches_ground = 1;
+ }
+
+ vec_t opposing_force = opposing_force_by_sides(sides);
+
+ for (int i = 0; i < 1000 && vec_length(opposing_force) > 1e-6; ++i) {
+ rigid_rect->position = vec_sum(
+ rigid_rect->position,
+ vec_scala_mult(
+ opposing_force,
+ 1e-2f));
+
+ if (fabs(opposing_force.x) > 1e-6 && (opposing_force.x < 0.0f) != ((rigid_rect->velocity.x + rigid_rect->movement.x) < 0.0f)) {
+ rigid_rect->velocity.x = 0.0f;
+ rigid_rect->movement.x = 0.0f;
+ }
+
+ if (fabs(opposing_force.y) > 1e-6 && (opposing_force.y < 0.0f) != ((rigid_rect->velocity.y + rigid_rect->movement.y) < 0.0f)) {
+ rigid_rect->velocity.y = 0.0f;
+ rigid_rect->movement.y = 0.0f;
+ }
+
+ boxes_rect_object_collide(
+ boxes,
+ rigid_rect_hitbox(rigid_rect),
+ sides);
+ opposing_force = opposing_force_by_sides(sides);
+ }
+}
+
+void rigid_rect_impact_rigid_rect(rigid_rect_t * rigid_rect,
+ rigid_rect_t *another_rect)
+{
+ if (rects_overlap(rigid_rect_hitbox(rigid_rect), rigid_rect_hitbox(another_rect))) {
+ rigid_rect_move(another_rect,
+ vec_sum(
+ rigid_rect->velocity,
+ rigid_rect->movement));
+ }
+}
+
rect_t rigid_rect_hitbox(const rigid_rect_t *rigid_rect)
{
return rect_from_vecs(
#include "math/rect.h"
typedef struct rigid_rect_t rigid_rect_t;
+typedef struct boxes_t boxes_t;
rigid_rect_t *create_rigid_rect(rect_t rect, color_t color);
rigid_rect_t *create_rigid_rect_from_stream(FILE *stream);
const platforms_t *platforms);
void rigid_rect_collide_with_rect(rigid_rect_t * rigid_rect,
rect_t rect);
+void rigid_rect_collide_with_boxes(rigid_rect_t * rigid_rect,
+ const boxes_t *boxes);
+void rigid_rect_impact_rigid_rect(rigid_rect_t * rigid_rect,
+ rigid_rect_t *another_rect);
rect_t rigid_rect_hitbox(const rigid_rect_t *rigid_rect);