summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFrederico Linhares <fred@linhares.blue>2022-05-23 10:38:55 -0300
committerFrederico Linhares <fred@linhares.blue>2022-05-23 10:38:55 -0300
commit9f3bf608e9b300d7f5c85acf591c7e3c2a0d4f43 (patch)
tree6bd2fc4acf553bc23d95e0e5f7f568b2f8384c76
parent056f43fd9c1217e3522e0715f035f339adab0d9a (diff)
feat Subdivide collision detection
* src/rect.c (cg_cRect_align_vertically, cg_cRect_align_horizontally): Collision detection consists of two different algorithms that detect if two boxes are aligned vertically and horizontally. Now those two algorithms can be used separately.
-rw-r--r--src/rect.c48
1 files changed, 44 insertions, 4 deletions
diff --git a/src/rect.c b/src/rect.c
index 206ab45..52c9dd4 100644
--- a/src/rect.c
+++ b/src/rect.c
@@ -27,6 +27,18 @@ cg_free_rect(mrb_state *mrb, void* obj)
const struct mrb_data_type cg_rect_type = {
"CG_Rect", cg_free_rect };
+static inline SDL_bool
+align_vertically(int a_x, int a_width, int b_x, int b_width)
+{
+ return a_x <= b_x + b_width && a_x + a_width >= b_x;
+}
+
+static inline SDL_bool
+align_horizontally(int a_y, int a_height, int b_y, int b_height)
+{
+ return a_y <= b_y + b_height && a_y + a_height >= b_y;
+}
+
static mrb_value
cg_cRect_initialize(mrb_state *mrb, mrb_value self)
{
@@ -164,6 +176,30 @@ cg_cRect_draw_fill(mrb_state *mrb, mrb_value self)
}
static mrb_value
+cg_cRect_align_vertically(mrb_state *mrb, mrb_value self)
+{
+ struct cg_rect *ptr, *that;
+
+ mrb_get_args(mrb, "d", &that, &cg_rect_type);
+ ptr = (struct cg_rect *)DATA_PTR(self);
+
+ return mrb_bool_value(
+ align_vertically(ptr->rect.x, ptr->rect.w, that->rect.x, that->rect.w));
+}
+
+static mrb_value
+cg_cRect_align_horizontally(mrb_state *mrb, mrb_value self)
+{
+ struct cg_rect *ptr, *that;
+
+ mrb_get_args(mrb, "d", &that, &cg_rect_type);
+ ptr = (struct cg_rect *)DATA_PTR(self);
+
+ return mrb_bool_value(
+ align_horizontally(ptr->rect.y, ptr->rect.h, that->rect.y, that->rect.h));
+}
+
+static mrb_value
cg_cRect_collide(mrb_state *mrb, mrb_value self)
{
struct cg_rect *ptr, *that;
@@ -172,10 +208,8 @@ cg_cRect_collide(mrb_state *mrb, mrb_value self)
ptr = (struct cg_rect *)DATA_PTR(self);
return mrb_bool_value(
- ptr->rect.x <= that->rect.x + that->rect.w &&
- ptr->rect.x + ptr->rect.w >= that->rect.x &&
- ptr->rect.y <= that->rect.y + that->rect.h &&
- ptr->rect.y + ptr->rect.h >= that->rect.y);
+ align_vertically(ptr->rect.x, ptr->rect.w, that->rect.x, that->rect.w) &&
+ align_horizontally(ptr->rect.y, ptr->rect.h, that->rect.y, that->rect.h));
}
void
@@ -205,5 +239,11 @@ cg_rect_init(mrb_state *mrb)
mrb_define_method(
mrb, cg_cRect, "draw_fill", cg_cRect_draw_fill, MRB_ARGS_NONE());
mrb_define_method(
+ mrb, cg_cRect, "align_vertically?", cg_cRect_align_vertically,
+ MRB_ARGS_REQ(1));
+ mrb_define_method(
+ mrb, cg_cRect, "align_horizontally?", cg_cRect_align_vertically,
+ MRB_ARGS_REQ(1));
+ mrb_define_method(
mrb, cg_cRect, "collide?", cg_cRect_collide, MRB_ARGS_REQ(1));
}